The Wolfenstein: Enemy Territory sources as originally released under the GPL license on August 20, 2010.

This commit is contained in:
Travis Bradshaw
2012-01-31 15:06:54 -06:00
commit 40342a9e36
1357 changed files with 699137 additions and 0 deletions

643
COPYING.txt Normal file
View File

@@ -0,0 +1,643 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
ADDITIONAL TERMS APPLICABLE TO THE WOLFENSTEIN: ENEMY TERRITORY GPL SOURCE CODE.
The following additional terms (“Additional Terms”) supplement and modify the GNU General Public License, Version 3 (“GPL”) applicable to the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”). In addition to the terms and conditions of the GPL, the Wolf ET Source Code is subject to the further restrictions below.
1. Replacement of Section 15. Section 15 of the GPL shall be deleted in its entirety and replaced with the following:
“15. Disclaimer of Warranty.
THE PROGRAM IS PROVIDED WITHOUT ANY WARRANTIES, WHETHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, TITLE AND MERCHANTABILITY. THE PROGRAM IS BEING DELIVERED OR MADE AVAILABLE “AS IS”, “WITH ALL FAULTS” AND WITHOUT WARRANTY OR REPRESENTATION. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.”
2. Replacement of Section 16. Section 16 of the GPL shall be deleted in its entirety and replaced with the following:
“16. LIMITATION OF LIABILITY.
UNDER NO CIRCUMSTANCES SHALL ANY COPYRIGHT HOLDER OR ITS AFFILIATES, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, FOR ANY DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, DIRECT, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL OR PUNITIVE DAMAGES ARISING FROM, OUT OF OR IN CONNECTION WITH THE USE OR INABILITY TO USE THE PROGRAM OR OTHER DEALINGS WITH THE PROGRAM(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), WHETHER OR NOT ANY COPYRIGHT HOLDER OR SUCH OTHER PARTY RECEIVES NOTICE OF ANY SUCH DAMAGES AND WHETHER OR NOT SUCH DAMAGES COULD HAVE BEEN FORESEEN.”
3. LEGAL NOTICES; NO TRADEMARK LICENSE; ORIGIN. You must reproduce faithfully all trademark, copyright and other proprietary and legal notices on any copies of the Program or any other required author attributions. This license does not grant you rights to use any copyright holder or any other partys name, logo, or trademarks. Neither the name of the copyright holder or its affiliates, or any other party who modifies and/or conveys the Program may be used to endorse or promote products derived from this software without specific prior written permission. The origin of the Program must not be misrepresented; you must not claim that you wrote the original Program. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original Program.
4. INDEMNIFICATION. IF YOU CONVEY A COVERED WORK AND AGREE WITH ANY RECIPIENT OF THAT COVERED WORK THAT YOU WILL ASSUME ANY LIABILITY FOR THAT COVERED WORK, YOU HEREBY AGREE TO INDEMNIFY, DEFEND AND HOLD HARMLESS THE OTHER LICENSORS AND AUTHORS OF THAT COVERED WORK FOR ANY DAMAEGS, DEMANDS, CLAIMS, LOSSES, CAUSES OF ACTION, LAWSUITS, JUDGMENTS EXPENSES (INCLUDING WITHOUT LIMITATION REASONABLE ATTORNEYS' FEES AND EXPENSES) OR ANY OTHER LIABLITY ARISING FROM, RELATED TO OR IN CONNECTION WITH YOUR ASSUMPTIONS OF LIABILITY.

160
README.txt Normal file
View File

@@ -0,0 +1,160 @@
Wolfenstein: Enemy Territory GPL source release
===============================================
This file contains the following sections:
GENERAL NOTES
LICENSE
GENERAL NOTES
=============
Game data and patching:
-----------------------
Wolfenstein: Enemy Territory is a free release, and can be downloaded from
http://www.splashdamage.com/content/wolfenstein-enemy-territory-barracks
This source release does not contain any game data, the game data is still
covered by the original EULA and must be obeyed as usual.
Install the latest version of the game for your platform to get the game data.
Compiling on win32:
-------------------
A Visual C++ 2008 project is provided in src\wolf.sln.
The solution file is compatible with the Express release of Visual C++.
In order to test your binaries, backup and remove Main\mp_bin.pk3, then replace
WolfMP.exe, Main\qagame_mp_x86.dll, Main\cgame_mp_x86.dll, Main\ui_mp_x86.dll
by your compiled versions. When starting the server make sure to specify
'Pure Server: No' in the advanced settings page.
Compiling on GNU/Linux x86:
---------------------------
Get scons from http://scons.org/ if your favorite distribution doesn't
package it.
run scons from the src/ directory. see scons --help for build options
If any problems occur, consult the internet.
Other platforms, updated source code, security issues:
------------------------------------------------------
If you have obtained this source code several weeks after the time of release
(August 2010), it is likely that you can find modified and improved
versions of the engine in various open source projects across the internet.
Depending what is your interest with the source code, those may be a better
starting point.
LICENSE
=======
See COPYING.txt for the GNU GENERAL PUBLIC LICENSE
ADDITIONAL TERMS: The Wolfenstein: Enemy Territory GPL Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU GPL which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
EXCLUDED CODE: The code described below and contained in the Wolfenstein: Enemy Territory GPL Source Code release is not part of the Program covered by the GPL and is expressly excluded from its terms. You are solely responsible for obtaining from the copyright holder a license for such code and complying with the applicable license terms.
IO on .zip files using portions of zlib
---------------------------------------------------------------------------
lines file(s)
4301 src/qcommon/unzip.c
Copyright (C) 1998 Gilles Vollant
zlib is Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
MD4 Message-Digest Algorithm
-----------------------------------------------------------------------------
lines file(s)
289 src/qcommon/md4.c
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved.
License to copy and use this software is granted provided that it is identified
as the <93>RSA Data Security, Inc. MD4 Message-Digest Algorithm<94> in all mater
ial mentioning or referencing this software or this function.
License is also granted to make and use derivative works provided that such work
s are identified as <93>derived from the RSA Data Security, Inc. MD4 Message-Dig
est Algorithm<94> in all material mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either the merchanta
bility of this software or the suitability of this software for any particular p
urpose. It is provided <93>as is<94> without express or implied warranty of any
kind.
JPEG library
-----------------------------------------------------------------------------
src/jpeg-6
Copyright (C) 1991-1995, Thomas G. Lane
Permission is hereby granted to use, copy, modify, and distribute this
software (or portions thereof) for any purpose, without fee, subject to these
conditions:
(1) If any part of the source code for this software is distributed, then this
README file must be included, with this copyright and no-warranty notice
unaltered; and any additions, deletions, or changes to the original files
must be clearly indicated in accompanying documentation.
(2) If only executable code is distributed, then the accompanying
documentation must state that "this software is based in part on the work of
the Independent JPEG Group".
(3) Permission for use of this software is granted only if the user accepts
full responsibility for any undesirable consequences; the authors accept
NO LIABILITY for damages of any kind.
These conditions apply to any software derived from or based on the IJG code,
not just to the unmodified library. If you use our work, you ought to
acknowledge us.
NOTE: unfortunately the README that came with our copy of the library has
been lost, so the one from release 6b is included instead. There are a few
'glue type' modifications to the library to make it easier to use from
the engine, but otherwise the dependency can be easily cleaned up to a
better release of the library.
CURL library
-----------------------------------------------------------------------------
src/curl-7.12.2
COPYRIGHT AND PERMISSION NOTICE
Copyright (c) 1996 - 2004, Daniel Stenberg, <daniel@haxx.se>.
All rights reserved.
Permission to use, copy, modify, and distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright
notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN
NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of a copyright holder shall not
be used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization of the copyright holder.
FT2 library
-----------------------------------------------------------------------------
src/ft2
The FT2 library is being used under the GPL v2 as indicated by its LICENSE.txt

473
etmain/ui/menudef.h Normal file
View File

@@ -0,0 +1,473 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#define ITEM_TYPE_TEXT 0 // simple text
#define ITEM_TYPE_BUTTON 1 // button, basically text with a border
#define ITEM_TYPE_RADIOBUTTON 2 // toggle button, may be grouped
#define ITEM_TYPE_CHECKBOX 3 // check box
#define ITEM_TYPE_EDITFIELD 4 // editable text, associated with a cvar
#define ITEM_TYPE_COMBO 5 // drop down list
#define ITEM_TYPE_LISTBOX 6 // scrollable list
#define ITEM_TYPE_MODEL 7 // model
#define ITEM_TYPE_OWNERDRAW 8 // owner draw, name specs what it is
#define ITEM_TYPE_NUMERICFIELD 9 // editable text, associated with a cvar
#define ITEM_TYPE_SLIDER 10 // mouse speed, volume, etc.
#define ITEM_TYPE_YESNO 11 // yes no cvar setting
#define ITEM_TYPE_MULTI 12 // multiple list setting, enumerated
#define ITEM_TYPE_BIND 13 // multiple list setting, enumerated
#define ITEM_TYPE_MENUMODEL 14 // special menu model
#define ITEM_TYPE_TIMEOUT_COUNTER 15 // ydnar
#define ITEM_TYPE_TRICHECKBOX 16 // tri-state check box
#define ITEM_ALIGN_LEFT 0 // left alignment
#define ITEM_ALIGN_CENTER 1 // center alignment
#define ITEM_ALIGN_RIGHT 2 // right alignment
#define ITEM_ALIGN_CENTER2 3 // center alignment
#define ITEM_TEXTSTYLE_NORMAL 0 // normal text
#define ITEM_TEXTSTYLE_BLINK 1 // fast blinking
#define ITEM_TEXTSTYLE_PULSE 2 // slow pulsing
#define ITEM_TEXTSTYLE_SHADOWED 3 // drop shadow ( need a color for this )
#define ITEM_TEXTSTYLE_OUTLINED 4 // drop shadow ( need a color for this )
#define ITEM_TEXTSTYLE_OUTLINESHADOWED 5 // drop shadow ( need a color for this )
#define ITEM_TEXTSTYLE_SHADOWEDMORE 6 // drop shadow ( need a color for this )
#define WINDOW_BORDER_NONE 0 // no border
#define WINDOW_BORDER_FULL 1 // full border based on border color ( single pixel )
#define WINDOW_BORDER_HORZ 2 // horizontal borders only
#define WINDOW_BORDER_VERT 3 // vertical borders only
#define WINDOW_BORDER_KCGRADIENT 4 // horizontal border using the gradient bars
#define WINDOW_STYLE_EMPTY 0 // no background
#define WINDOW_STYLE_FILLED 1 // filled with background color
#define WINDOW_STYLE_GRADIENT 2 // gradient bar based on background color
#define WINDOW_STYLE_SHADER 3 // gradient bar based on background color
#define WINDOW_STYLE_TEAMCOLOR 4 // team color
#define WINDOW_STYLE_CINEMATIC 5 // cinematic
#define MENU_TRUE 1 // uh.. true
#define MENU_FALSE 0 // and false
#define HUD_VERTICAL 0x00
#define HUD_HORIZONTAL 0x01
#define RANGETYPE_ABSOLUTE 0
#define RANGETYPE_RELATIVE 1
// list box element types
#define LISTBOX_TEXT 0x00
#define LISTBOX_IMAGE 0x01
// list feeders
#define FEEDER_HEADS 0x00 // model heads
#define FEEDER_MAPS 0x01 // text maps based on game type
#define FEEDER_SERVERS 0x02 // servers
#define FEEDER_CLANS 0x03 // clan names
#define FEEDER_ALLMAPS 0x04 // all maps available, in graphic format
#define FEEDER_REDTEAM_LIST 0x05 // red team members
#define FEEDER_BLUETEAM_LIST 0x06 // blue team members
#define FEEDER_PLAYER_LIST 0x07 // players
#define FEEDER_TEAM_LIST 0x08 // team members for team voting
#define FEEDER_MODS 0x09 // team members for team voting
#define FEEDER_DEMOS 0x0a // team members for team voting
#define FEEDER_SCOREBOARD 0x0b // team members for team voting
#define FEEDER_Q3HEADS 0x0c // model heads
#define FEEDER_SERVERSTATUS 0x0d // server status
#define FEEDER_FINDPLAYER 0x0e // find player
#define FEEDER_CINEMATICS 0x0f // cinematics
#define FEEDER_SAVEGAMES 0x10 // savegames
#define FEEDER_CAMPAIGNS 0x1a // Arnout: all unlocked campaigns available
#define FEEDER_ALLCAMPAIGNS 0x1b // Arnout: all campaigns available
#define FEEDER_PROFILES 0x1c // Arnout: profiles
#define FEEDER_GLINFO 0x1d // Arnout: glinfo
// display flags
#define CG_SHOW_BLUE_TEAM_HAS_REDFLAG 0x00000001
#define CG_SHOW_RED_TEAM_HAS_BLUEFLAG 0x00000002
#define CG_SHOW_ANYTEAMGAME 0x00000004
#define CG_SHOW_HARVESTER 0x00000008
#define CG_SHOW_ONEFLAG 0x00000010
#define CG_SHOW_CTF 0x00000020
#define CG_SHOW_OBELISK 0x00000040
#define CG_SHOW_HEALTHCRITICAL 0x00000080
#define CG_SHOW_SINGLEPLAYER 0x00000100
#define CG_SHOW_TOURNAMENT 0x00000200
#define CG_SHOW_DURINGINCOMINGVOICE 0x00000400
#define CG_SHOW_IF_PLAYER_HAS_FLAG 0x00000800
#define CG_SHOW_LANPLAYONLY 0x00001000
#define CG_SHOW_MINED 0x00002000
#define CG_SHOW_HEALTHOK 0x00004000
#define CG_SHOW_TEAMINFO 0x00008000
#define CG_SHOW_NOTEAMINFO 0x00010000
#define CG_SHOW_OTHERTEAMHASFLAG 0x00020000
#define CG_SHOW_YOURTEAMHASENEMYFLAG 0x00040000
#define CG_SHOW_ANYNONTEAMGAME 0x00080000
//(SA)
#define CG_SHOW_HIGHLIGHTED 0x00100000
#define CG_SHOW_NOT_V_BINOC 0x00400000 //----(SA) added // hide on binoc huds
#define CG_SHOW_NOT_V_SNOOPER 0x00800000 //----(SA) added // hide on snooper huds
#define CG_SHOW_NOT_V_FGSCOPE 0x01000000 //----(SA) added // hide on fg42 scope huds
#define CG_SHOW_NOT_V_CLEAR 0x02000000 //----(SA) added // hide on normal, full-view huds
#define CG_SHOW_NOT_V_GARANDSCOPE 0x04000000 // Arnout: hide on garand scope huds
#define CG_SHOW_NOT_V_K43SCOPE 0x08000000 // Arnout: hide on k43 scope huds
#define CG_SHOW_2DONLY 0x10000000
#define UI_SHOW_LEADER 0x00000001
#define UI_SHOW_NOTLEADER 0x00000002
#define UI_SHOW_FAVORITESERVERS 0x00000004
#define UI_SHOW_ANYNONTEAMGAME 0x00000008
#define UI_SHOW_ANYTEAMGAME 0x00000010
#define UI_SHOW_NEWHIGHSCORE 0x00000020
#define UI_SHOW_DEMOAVAILABLE 0x00000040
#define UI_SHOW_NEWBESTTIME 0x00000080
#define UI_SHOW_FFA 0x00000100
#define UI_SHOW_NOTFFA 0x00000200
#define UI_SHOW_NETANYNONTEAMGAME 0x00000400
#define UI_SHOW_NETANYTEAMGAME 0x00000800
#define UI_SHOW_NOTFAVORITESERVERS 0x00001000
#define UI_SHOW_CAMPAIGNMAP1EXISTS 0x00002000
#define UI_SHOW_CAMPAIGNMAP2EXISTS 0x00004000
#define UI_SHOW_CAMPAIGNMAP3EXISTS 0x00008000
#define UI_SHOW_CAMPAIGNMAP4EXISTS 0x00010000
#define UI_SHOW_CAMPAIGNMAP5EXISTS 0x00020000
#define UI_SHOW_CAMPAIGNMAP6EXISTS 0x00040000
#define UI_SHOW_SELECTEDCAMPAIGNMAPPLAYABLE 0x00080000
#define UI_SHOW_SELECTEDCAMPAIGNMAPNOTPLAYABLE 0x00100000
#define UI_SHOW_PLAYERMUTED 0x01000000
#define UI_SHOW_PLAYERNOTMUTED 0x02000000
#define UI_SHOW_PLAYERNOREFEREE 0x04000000
#define UI_SHOW_PLAYERREFEREE 0x08000000
// owner draw types
// ideally these should be done outside of this file but
// this makes it much easier for the macro expansion to
// convert them for the designers ( from the .menu files )
#define CG_OWNERDRAW_BASE 1
#define CG_PLAYER_ARMOR_ICON 1
#define CG_PLAYER_ARMOR_VALUE 2
#define CG_PLAYER_HEAD 3
#define CG_PLAYER_HEALTH 4
#define CG_PLAYER_AMMO_ICON 5
#define CG_PLAYER_AMMO_VALUE 6
#define CG_SELECTEDPLAYER_HEAD 7
#define CG_SELECTEDPLAYER_NAME 8
#define CG_SELECTEDPLAYER_STATUS 10
#define CG_SELECTEDPLAYER_WEAPON 11
#define CG_SELECTEDPLAYER_POWERUP 12
#define CG_FLAGCARRIER_HEAD 13
#define CG_FLAGCARRIER_NAME 14
#define CG_FLAGCARRIER_LOCATION 15
#define CG_FLAGCARRIER_STATUS 16
#define CG_FLAGCARRIER_WEAPON 17
#define CG_FLAGCARRIER_POWERUP 18
#define CG_PLAYER_ITEM 19
#define CG_PLAYER_SCORE 20
/*#define CG_BLUE_FLAGHEAD 21
#define CG_BLUE_FLAGSTATUS 22
#define CG_BLUE_FLAGNAME 23
#define CG_RED_FLAGHEAD 24
#define CG_RED_FLAGSTATUS 25
#define CG_RED_FLAGNAME 26*/
#define CG_BLUE_SCORE 27
#define CG_RED_SCORE 28
/*#define CG_RED_NAME 29
#define CG_BLUE_NAME 30
#define CG_HARVESTER_SKULLS 31 // only shows in harvester
#define CG_ONEFLAG_STATUS 32 // only shows in one flag*/
#define CG_TEAM_COLOR 34
//#define CG_CTF_POWERUP 35
#define CG_AREA_POWERUP 36
#define CG_AREA_LAGOMETER 37 // painted with old system
#define CG_PLAYER_HASFLAG 38
#define CG_GAME_TYPE 39 // not done
#define CG_SELECTEDPLAYER_HEALTH 41
#define CG_PLAYER_STATUS 42
#define CG_FRAGGED_MSG 43 // painted with old system
#define CG_PROXMINED_MSG 44 // painted with old system
#define CG_AREA_FPSINFO 45 // painted with old system
#define CG_AREA_SYSTEMCHAT 46 // painted with old system
#define CG_AREA_TEAMCHAT 47 // painted with old system
#define CG_AREA_CHAT 48 // painted with old system
#define CG_GAME_STATUS 49
#define CG_KILLER 50
#define CG_PLAYER_ARMOR_ICON2D 51
#define CG_PLAYER_AMMO_ICON2D 52
#define CG_ACCURACY 53
#define CG_ASSISTS 54
#define CG_DEFEND 55
#define CG_EXCELLENT 56
#define CG_IMPRESSIVE 57
#define CG_PERFECT 58
#define CG_GAUNTLET 59
#define CG_SPECTATORS 60
#define CG_TEAMINFO 61
#define CG_VOICE_HEAD 62
#define CG_VOICE_NAME 63
#define CG_PLAYER_HASFLAG2D 64
#define CG_HARVESTER_SKULLS2D 65 // only shows in harvester
#define CG_CAPFRAGLIMIT 66
#define CG_1STPLACE 67
#define CG_2NDPLACE 68
#define CG_CAPTURES 69
// (SA) adding
#define CG_PLAYER_AMMOCLIP_VALUE 70
#define CG_PLAYER_WEAPON_ICON2D 71
#define CG_CURSORHINT 72
#define CG_STAMINA 73
#define CG_PLAYER_WEAPON_HEAT 74
#define CG_PLAYER_POWERUP 75
#define CG_PLAYER_INVENTORY 77
#define CG_AREA_WEAPON 78 // draw weapons here
#define CG_AREA_HOLDABLE 79
#define CG_CURSORHINT_STATUS 80 // like 'health' bar when pointing at a func_explosive
#define CG_PLAYER_WEAPON_STABILITY 81 // shows aimSpreadScale value
#define CG_PLAYER_WEAPON_RECHARGE 82 // DHM - Nerve :: For various multiplayer weapons that have recharge times
#define UI_OWNERDRAW_BASE 200
#define UI_HANDICAP 200
#define UI_EFFECTS 201
#define UI_PLAYERMODEL 202
#define UI_CLANNAME 203
#define UI_CLANLOGO 204
#define UI_GAMETYPE 205
#define UI_MAPPREVIEW 206
#define UI_NETMAPPREVIEW 207
#define UI_BLUETEAMNAME 208
#define UI_REDTEAMNAME 209
#define UI_BLUETEAM1 210
#define UI_BLUETEAM2 211
#define UI_BLUETEAM3 212
#define UI_BLUETEAM4 213
#define UI_BLUETEAM5 214
#define UI_REDTEAM1 215
#define UI_REDTEAM2 216
#define UI_REDTEAM3 217
#define UI_REDTEAM4 218
#define UI_REDTEAM5 219
#define UI_NETSOURCE 220
//#define UI_NETMAPPREVIEW 221
#define UI_NETFILTER 222
#define UI_TIER 223
#define UI_OPPONENTMODEL 224
#define UI_TIERMAP1 225
#define UI_TIERMAP2 226
#define UI_TIERMAP3 227
#define UI_PLAYERLOGO 228
#define UI_OPPONENTLOGO 229
#define UI_PLAYERLOGO_METAL 230
#define UI_OPPONENTLOGO_METAL 231
#define UI_PLAYERLOGO_NAME 232
#define UI_OPPONENTLOGO_NAME 233
#define UI_TIER_MAPNAME 234
#define UI_TIER_GAMETYPE 235
#define UI_ALLMAPS_SELECTION 236
#define UI_OPPONENT_NAME 237
#define UI_VOTE_KICK 238
#define UI_BOTNAME 239
//#define UI_BOTSKILL 240
#define UI_REDBLUE 241
#define UI_CROSSHAIR 242
#define UI_SELECTEDPLAYER 243
#define UI_MAPCINEMATIC 244
#define UI_NETGAMETYPE 245
#define UI_NETMAPCINEMATIC 246
#define UI_SERVERREFRESHDATE 247
#define UI_SERVERMOTD 248
#define UI_KEYBINDSTATUS 250
#define UI_CLANCINEMATIC 251
#define UI_MAP_TIMETOBEAT 252
#define UI_JOINGAMETYPE 253
#define UI_PREVIEWCINEMATIC 254
#define UI_STARTMAPCINEMATIC 255
#define UI_MAPS_SELECTION 256
#define UI_LOADPANEL 257
//----(SA) added
#define UI_MENUMODEL 257
#define UI_SAVEGAME_SHOT 258
//----(SA) end
// NERVE - SMF
#define UI_LIMBOCHAT 259
// -NERVE - SMF
// Arnout: Enemy Territory
#define UI_CAMPAIGNCINEMATIC 260
#define UI_CAMPAIGNNAME 261
#define UI_CAMPAIGNDESCRIPTION 262
#define UI_CAMPAIGNMAP1_SHOT 263
#define UI_CAMPAIGNMAP2_SHOT 264
#define UI_CAMPAIGNMAP3_SHOT 265
#define UI_CAMPAIGNMAP4_SHOT 266
#define UI_CAMPAIGNMAP5_SHOT 267
#define UI_CAMPAIGNMAP6_SHOT 268
#define UI_CAMPAIGNMAP1_TEXT 269
#define UI_CAMPAIGNMAP2_TEXT 270
#define UI_CAMPAIGNMAP3_TEXT 271
#define UI_CAMPAIGNMAP4_TEXT 272
#define UI_CAMPAIGNMAP5_TEXT 273
#define UI_CAMPAIGNMAP6_TEXT 274
#define UI_GAMETYPEDESCRIPTION 280
// Gordon: Mission briefing
#define UI_MB_MAP 300
#define UI_MB_TITLE 301
#define UI_MB_OBJECTIVES 302
#define VOICECHAT_GETFLAG "getflag" // command someone to get the flag
#define VOICECHAT_OFFENSE "offense" // command someone to go on offense
#define VOICECHAT_DEFEND "defend" // command someone to go on defense
#define VOICECHAT_DEFENDFLAG "defendflag" // command someone to defend the flag
#define VOICECHAT_PATROL "patrol" // command someone to go on patrol (roam)
#define VOICECHAT_CAMP "camp" // command someone to camp (we don't have sounds for this one)
#define VOICECHAT_FOLLOWME "followme" // command someone to follow you
#define VOICECHAT_RETURNFLAG "returnflag" // command someone to return our flag
#define VOICECHAT_FOLLOWFLAGCARRIER "followflagcarrier" // command someone to follow the flag carrier
#define VOICECHAT_YES "yes" // yes, affirmative, etc.
#define VOICECHAT_NO "no" // no, negative, etc.
#define VOICECHAT_ONGETFLAG "ongetflag" // I'm getting the flag
#define VOICECHAT_ONOFFENSE "onoffense" // I'm on offense
#define VOICECHAT_ONDEFENSE "ondefense" // I'm on defense
#define VOICECHAT_ONPATROL "onpatrol" // I'm on patrol (roaming)
#define VOICECHAT_ONCAMPING "oncamp" // I'm camping somewhere
#define VOICECHAT_ONFOLLOW "onfollow" // I'm following
#define VOICECHAT_ONFOLLOWCARRIER "onfollowcarrier" // I'm following the flag carrier
#define VOICECHAT_ONRETURNFLAG "onreturnflag" // I'm returning our flag
#define VOICECHAT_INPOSITION "inposition" // I'm in position
#define VOICECHAT_IHAVEFLAG "ihaveflag" // I have the flag
#define VOICECHAT_BASEATTACK "baseattack" // the base is under attack
#define VOICECHAT_ENEMYHASFLAG "enemyhasflag" // the enemy has our flag (CTF)
#define VOICECHAT_STARTLEADER "startleader" // I'm the leader
#define VOICECHAT_STOPLEADER "stopleader" // I resign leadership
#define VOICECHAT_WHOISLEADER "whoisleader" // who is the team leader
#define VOICECHAT_WANTONDEFENSE "wantondefense" // I want to be on defense
#define VOICECHAT_WANTONOFFENSE "wantonoffense" // I want to be on offense
#define VOICECHAT_KILLINSULT "kill_insult" // I just killed you
#define VOICECHAT_TAUNT "taunt" // I want to taunt you
#define VOICECHAT_DEATHINSULT "death_insult" // you just killed me
#define VOICECHAT_KILLGAUNTLET "kill_gauntlet" // I just killed you with the gauntlet
#define VOICECHAT_PRAISE "praise" // you did something good
// NERVE - SMF - wolf multiplayer class/item selection mechanism
#define WM_START_SELECT 0
#define WM_SELECT_TEAM 1
#define WM_SELECT_CLASS 2
#define WM_SELECT_WEAPON 3
#define WM_SELECT_PISTOL 4
#define WM_SELECT_GRENADE 5
#define WM_SELECT_ITEM1 6
#define WM_AXIS 1
#define WM_ALLIES 2
#define WM_SPECTATOR 3
#define WM_SOLDIER 1
#define WM_MEDIC 2
#define WM_LIEUTENANT 3
#define WM_ENGINEER 4
#define WM_COVERTOPS 5
/*#define WM_PISTOL_1911 1
#define WM_PISTOL_LUGER 2
#define WM_WEAPON_MP40 3
#define WM_WEAPON_THOMPSON 4
#define WM_WEAPON_STEN 5
#define WM_WEAPON_MAUSER 6
#define WM_WEAPON_PANZERFAUST 8
#define WM_WEAPON_VENOM 9
#define WM_WEAPON_FLAMETHROWER 10
#define WM_PINEAPPLE_GRENADE 11
#define WM_STICK_GRENADE 12
#define WM_WEAPON_KAR98 13
#define WM_WEAPON_CARBINE 14
#define WM_WEAPON_GARAND 15
#define WM_WEAPON_FG42 16*/
// -NERVE - SMF
// Arnout: UI fonts, supports up to 6 fonts
#define UI_FONT_ARIBLK_16 0
#define UI_FONT_ARIBLK_27 1
#define UI_FONT_COURBD_21 2
#define UI_FONT_COURBD_30 3
// OSP - callvote server setting toggles
// CS_SERVERTOGGLES
#define CV_SVS_MUTESPECS 1
#define CV_SVS_FRIENDLYFIRE 2
// 2 bits for warmup damage setting
#define CV_SVS_WARMUPDMG 12
#define CV_SVS_PAUSE 16
#define CV_SVS_LOCKTEAMS 32
#define CV_SVS_LOCKSPECS 64
#define CV_SVS_ANTILAG 128
#define CV_SVS_BALANCEDTEAMS 256
#define CV_SVS_NEXTMAP 512
// "cg_ui_voteFlags"
#define CV_SVF_COMP 1
#define CV_SVF_GAMETYPE 2
#define CV_SVF_KICK 4
#define CV_SVF_MAP 8
#define CV_SVF_MATCHRESET 16
#define CV_SVF_MUTESPECS 32
#define CV_SVF_NEXTMAP 64
#define CV_SVF_PUB 128
#define CV_SVF_REFEREE 256
#define CV_SVF_SHUFFLETEAMS 512
#define CV_SVF_SWAPTEAMS 1024
#define CV_SVF_FRIENDLYFIRE 2048
#define CV_SVF_TIMELIMIT 4096
#define CV_SVF_WARMUPDAMAGE 8192
#define CV_SVF_ANTILAG 16384
#define CV_SVF_BALANCEDTEAMS 32768
#define CV_SVF_MUTING 65536
// referee level
#define RL_NONE 0
#define RL_REFEREE 1
#define RL_RCON 2
// -OSP

1034
etmain/ui/menumacros.h Normal file

File diff suppressed because it is too large Load Diff

144
src/SConscript.bspc Normal file
View File

@@ -0,0 +1,144 @@
# -*- mode: python -*-
# Enemy Territory build script
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import sys, os
import scons_utils
Import( 'GLOBALS' )
Import( GLOBALS )
bspc_string = """
_files.c
aas_areamerging.c
aas_cfg.c
aas_create.c
aas_edgemelting.c
aas_facemerging.c
aas_file.c
aas_gsubdiv.c
aas_map.c
aas_prunenodes.c
aas_store.c
be_aas_bspc.c
../botlib/be_aas_bspq3.c
../botlib/be_aas_cluster.c
../botlib/be_aas_move.c
../botlib/be_aas_optimize.c
../botlib/be_aas_reach.c
../botlib/be_aas_sample.c
brushbsp.c
bspc.c
../qcommon/cm_load.c
../qcommon/cm_patch.c
../qcommon/cm_test.c
../qcommon/cm_trace.c
csg.c
faces.c
glfile.c
l_bsp_ent.c
l_bsp_q3.c
l_cmd.c
../botlib/l_libvar.c
l_log.c
l_math.c
l_mem.c
l_poly.c
../botlib/l_precomp.c
l_qfiles.c
../botlib/l_script.c
../botlib/l_struct.c
l_threads.c
l_utils.c
leakfile.c
map.c
map_q3.c
../qcommon/md4.c
nodraw.c
portals.c
prtfile.c
textures.c
tree.c
../qcommon/unzip.c
writebsp.c
aas_areamerging.h
aas_cfg.h
aas_create.h
aas_edgemelting.h
aas_facemerging.h
aas_file.h
aas_gsubdiv.h
aas_map.h
aas_prunenodes.h
aas_store.h
../botlib/aasfile.h
../botlib/be_aas.h
../game/be_aas.h
../botlib/be_aas_bsp.h
be_aas_bspc.h
../botlib/be_aas_cluster.h
../botlib/be_aas_debug.h
../botlib/be_aas_def.h
../botlib/be_aas_entity.h
../botlib/be_aas_file.h
../botlib/be_aas_funcs.h
../botlib/be_aas_main.h
../botlib/be_aas_move.h
../botlib/be_aas_optimize.h
../botlib/be_aas_reach.h
../botlib/be_aas_route.h
../botlib/be_aas_routealt.h
../botlib/be_aas_routetable.h
../botlib/be_aas_sample.h
../botlib/be_interface.h
../botlib/botlib.h
../qcommon/cm_local.h
../qcommon/cm_patch.h
../qcommon/cm_polylib.h
../qcommon/cm_public.h
l_bsp_ent.h
l_bsp_hl.h
l_bsp_q1.h
l_bsp_q2.h
l_bsp_q3.h
l_bsp_sin.h
l_cmd.h
../botlib/l_libvar.h
../botlib/l_log.h
l_log.h
l_math.h
l_mem.h
../botlib/l_memory.h
l_poly.h
../botlib/l_precomp.h
l_qfiles.h
../botlib/l_script.h
../botlib/l_struct.h
l_threads.h
../botlib/l_utils.h
l_utils.h
q2files.h
q3files.h
../game/q_shared.h
qbsp.h
../qcommon/qcommon.h
qfiles.h
../qcommon/qfiles.h
sinfiles.h
../game/surfaceflags.h
../qcommon/unzip.h
"""
bspc_list = scons_utils.BuildList( 'bspc', bspc_string )
local_env = g_env.Clone()
local_env.Append( CPPDEFINES = [ 'BSPC' ] )
source_list = bspc_list
local_env['LINK'] = local_env['CC']
ret = local_env.Program( target = 'bspc', source = source_list )
Return( 'ret' )

85
src/SConscript.cgame Normal file
View File

@@ -0,0 +1,85 @@
# -*- mode: python -*-
# Enemy Territory build script
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import sys, os
import scons_utils
Import( 'GLOBALS' )
Import( GLOBALS )
cgame_string = """
cg_atmospheric.c
cg_character.c
cg_commandmap.c
cg_consolecmds.c
cg_debriefing.c
cg_draw.c
cg_drawtools.c
cg_effects.c
cg_ents.c
cg_event.c
cg_fireteamoverlay.c
cg_fireteams.c
cg_flamethrower.c
cg_info.c
cg_limbopanel.c
cg_loadpanel.c
cg_localents.c
cg_main.c
cg_marks.c
cg_missionbriefing.c
cg_multiview.c
cg_newDraw.c
cg_particles.c
cg_players.c
cg_playerstate.c
cg_polybus.c
cg_popupmessages.c
cg_predict.c
cg_scoreboard.c
cg_servercmds.c
cg_snapshot.c
cg_sound.c
cg_spawn.c
cg_statsranksmedals.c
cg_syscalls.c
cg_trails.c
cg_view.c
cg_weapons.c
cg_window.c
../game/bg_animation.c
../game/bg_animgroup.c
../game/bg_character.c
../game/bg_classes.c
../game/bg_misc.c
../game/bg_pmove.c
../game/bg_slidemove.c
../game/bg_sscript.c
../game/bg_stats.c
../game/bg_tracemap.c
../game/q_math.c
../game/q_shared.c
../ui/ui_shared.c
"""
cgame_list = scons_utils.BuildList( 'cgame', cgame_string )
local_env = g_env.Clone()
local_env.Append( CPPDEFINES = [ 'CGAMEDLL' ] )
source_list = cgame_list
local_env['LINK'] = local_env['CC']
# GAMERANGER isn't exported in all usage paths
try:
if ( GAMERANGER == '1' ):
local_env.Append( CPPDEFINES = [ 'GAMERANGER' ] )
except:
pass
ret = local_env.SharedLibrary( target = 'cgame', source = source_list )
Return( 'ret' )

332
src/SConscript.core Normal file
View File

@@ -0,0 +1,332 @@
# -*- mode: python -*-
# Enemy Territory build script
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import sys, os
import scons_utils
Import( 'GLOBALS' )
Import( GLOBALS )
jpeg_string = """
jcapimin.c
jchuff.c
jcinit.c
jccoefct.c
jccolor.c
jfdctflt.c
jcdctmgr.c
jcphuff.c
jcmainct.c
jcmarker.c
jcmaster.c
jcomapi.c
jcparam.c
jcprepct.c
jcsample.c
jdapimin.c
jdapistd.c
jdatasrc.c
jdcoefct.c
jdcolor.c
jddctmgr.c
jdhuff.c
jdinput.c
jdmainct.c
jdmarker.c
jdmaster.c
jdpostct.c
jdsample.c
jdtrans.c
jerror.c
jidctflt.c
jmemmgr.c
jmemnobs.c
jutils.c"""
jpeg_list = scons_utils.BuildList( 'jpeg-6', jpeg_string )
renderer_string = """
tr_animation_mdm.c
tr_animation_mds.c
tr_backend.c
tr_bsp.c
tr_cmds.c
tr_cmesh.c
tr_curve.c
tr_decals.c
tr_flares.c
tr_font.c
tr_image.c
tr_init.c
tr_light.c
tr_main.c
tr_marks.c
tr_mesh.c
tr_model.c
tr_noise.c
tr_scene.c
tr_shade.c
tr_shade_calc.c
tr_shader.c
tr_shadows.c
tr_sky.c
tr_surface.c
tr_world.c"""
renderer_list = scons_utils.BuildList( 'renderer', renderer_string )
server_string = """
sv_bot.c
sv_ccmds.c
sv_client.c
sv_game.c
sv_init.c
sv_main.c
sv_net_chan.c
sv_snapshot.c
sv_world.c"""
server_list = scons_utils.BuildList( 'server', server_string )
qcommon_string = """
cm_load.c
cm_patch.c
cm_polylib.c
cm_test.c
cm_trace.c
cmd.c
common.c
cvar.c
files.c
huffman.c
md4.c
msg.c
net_chan.c
unzip.c
vm.c
vm_interpreted.c"""
if ( cpu == 'x86' ):
qcommon_string += " vm_x86.c"
qcommon_list = scons_utils.BuildList( 'qcommon', qcommon_string )
splines_string = """
math_angles.cpp
math_matrix.cpp
math_quaternion.cpp
math_vector.cpp
q_parse.cpp
q_shared.c
splines.cpp
util_str.cpp"""
splines_list = scons_utils.BuildList( 'splines', splines_string )
client_string = """
cl_cgame.c
cl_cin.c
cl_console.c
cl_input.c
cl_keys.c
cl_main.c
cl_net_chan.c
cl_parse.c
cl_scrn.c
cl_ui.c
snd_adpcm.c
snd_dma.c
snd_mem.c
snd_mix.c
snd_wavelet.c"""
client_list = scons_utils.BuildList( 'client', client_string )
linux_sources = [
'unix/linux_signals.c',
'unix/unix_main.c',
'unix/unix_net.c',
'unix/unix_shared.c',
'game/q_shared.c',
'game/q_math.c',
# 'unix/matha.S'
]
linux_full_sources = [
'unix/linux_glimp.c',
'unix/linux_qgl.c',
'unix/linux_snd.c',
'unix/linux_joystick.c',
# 'unix/snd_mixa.S'
]
mac_sources = [
'game/q_shared.c',
'game/q_math.c',
'mac/mac_main.cpp',
'mac/mac_input.cpp',
'mac/mac_glimp.cpp',
'mac/mac_files.cpp',
'mac/mac_net.cpp',
'mac/mac_console.c',
'mac/mac_snddma.c',
'mac/CarbonMouse.cpp',
'mac/mac_event.cpp',
# 'mac/HID Manager/HID_Configure.c',
# 'mac/HID Manager/HID_CFM.c',
'mac/MacPrefs.cpp',
'mac/PickMonitor/pickmonitor.cpp',
'mac/PickMonitor/userpane.cpp',
'mac/mac_qgl.c',
'mac/mac_specific.cpp',
'mac/AGLUtils.cpp',
'mac/CDrawSprocket.cpp'
]
win32_sources = [
'win32/win_main.c',
'win32/win_net.c',
'win32/win_shared.c',
'win32/win_wndproc.c',
'win32/win_syscon.c',
'game/q_shared.c',
'game/q_math.c',
]
win32_full_sources = [
'win32/win_input.c',
'win32/win_glimp.c',
'win32/win_qgl.c',
'win32/win_gamma.c',
'win32/win_snd.c',
]
botlib_list = [
'be_aas_bspq3.c',
'be_aas_cluster.c',
'be_aas_debug.c',
'be_aas_entity.c',
'be_aas_file.c',
'be_aas_main.c',
'be_aas_move.c',
'be_aas_optimize.c',
'be_aas_reach.c',
'be_aas_route.c',
'be_aas_routealt.c',
'be_aas_routetable.c',
'be_aas_sample.c',
'be_ai_char.c',
'be_ai_chat.c',
'be_ai_gen.c',
'be_ai_goal.c',
'be_ai_move.c',
'be_ai_weap.c',
'be_ai_weight.c',
'be_ea.c',
'be_interface.c',
'l_crc.c',
'l_libvar.c',
'l_log.c',
'l_memory.c',
'l_precomp.c',
'l_script.c',
'l_struct.c'
]
botlib_env = g_env.Clone()
botlib_env.Append( CPPDEFINES = [ 'BOTLIB' ] )
botlib_objs = []
for i in botlib_list:
botlib_objs.append( botlib_env.StaticObject( os.path.join( 'botlib', i ) ) )
staticx11_libs = [ 'libXxf86dga.a', 'libXxf86vm.a' ]
if ( os.path.exists( os.path.join( '/usr/lib', staticx11_libs[0] ) ) ):
staticx11_libs = [ os.path.join( '/usr/lib', i ) for i in staticx11_libs ]
else:
staticx11_libs = [ os.path.join( '/usr/X11R6/lib', i ) for i in staticx11_libs ]
if ( g_os == 'Linux' ):
nasm_env = Environment( tools = [ 'nasm' ] )
nasm_env['ASFLAGS'] = '-f elf'
snapvector = nasm_env.StaticObject( 'unix/snapvector.asm' )
# gas assembly, with preprocessing
gas_env = Environment( tools = [ 'gcc', 'gas' ] )
gas_env.Append( CPPDEFINES = [ 'ELF' ] )
gas_env.Append( ASFLAGS = [ '-m32', '-x', 'assembler-with-cpp' ] )
matha = gas_env.StaticObject( 'unix/matha.spp' )
snd_mixa = gas_env.StaticObject( 'unix/snd_mixa.spp' )
splines_env = g_env.Clone()
splines_lib = splines_env.StaticLibrary( splines_list )
local_env = g_env.Clone()
if ( g_os == 'Linux' ):
local_env.Append( LIBS = [ 'dl' ] )
if ( local_dedicated == 0 ):
local_env.Append( LIBS = [ 'X11', 'Xext', 'm' ] )
local_env.Append( LIBPATH = [ '/usr/X11R6/lib' ] )
local_env.Append( CPPPATH = [ 'curl-7.12.2/include' ] )
else:
local_env.Append( CPPDEFINES = [ 'DEDICATED' ] )
local_env.Append( LIBS = [ 'm' ] )
if gcc3 == 0:
g_env.Append(LINKFLAGS=[ os.popen( g_env['CXX'] + ' -print-file-name=libstdc++.a' ).read().rstrip() ])
else:
local_env['ENV']['CC'] = g_env['CC']
local_env['LINK'] = 'unix/staticlinkcpp.sh'
elif ( g_os == 'win32' ):
local_env.Append( LIBS = [ 'm', 'winmm', 'wsock32', 'gdi32', 'ole32', 'iphlpapi' ] )
if ( local_dedicated == 0 ):
local_env.Append( LIBS = [ 'dinput', 'dsound' ] )
local_env.Append( CPPPATH = [ 'curl-7.12.2/include' ] )
else:
local_env.Append( CPPDEFINES = [ 'DEDICATED' ] )
local_env['LINK'] = g_env['CXX']
elif ( g_os == 'Darwin' ):
local_env.Append( LINKFLAGS = [ '-framework', 'AGL', '-framework', 'OpenGL', '-framework', 'Carbon', '-framework', 'IOKit', '-framework', 'DrawSprocket', '-lcurl' ] )
if ( MASTER != '' ):
local_env.Append( CPPDEFINES = [ 'MASTER_SERVER_NAME=\\"%s\\"' % MASTER ] )
source_list = server_list + qcommon_list
if ( g_os == 'Linux' ):
source_list += linux_sources + snapvector + matha
elif ( g_os == 'win32' ):
source_list += win32_sources
elif ( g_os == 'Darwin' ):
if ( BUILD == 'release' ):
local_env.Append( CPPFLAGS = [ '-include', 'mac/MacPrefix.h' ] )
else:
local_env.Append( CPPFLAGS = [ '-include', 'mac/MacPrefixDebug.h' ] )
mac_objects = []
for i in mac_sources:
mac_objects.append( local_env.StaticObject( i ) )
source_list += mac_objects
source_list += botlib_objs
if ( local_dedicated == 0 ):
source_list += jpeg_list
source_list += renderer_list
source_list += client_list
source_list += [ 'qcommon/dl_main_curl.c' ]
source_list += curl_lib
if ( g_os == 'Linux' ):
source_list += snd_mixa
source_list += linux_full_sources
source_list += staticx11_libs
if ( g_os == 'win32' ):
source_list += win32_full_sources
else:
source_list += [ 'null/null_client.c', 'null/null_input.c', 'null/null_snddma.c', 'qcommon/dl_main_stubs.c' ]
source_list += splines_lib
ret = local_env.Program( target = 'et', source = source_list )
Return( 'ret' )

49
src/SConscript.curl Normal file
View File

@@ -0,0 +1,49 @@
# -*- mode: python -*-
# ET build script
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import scons_utils
Import( 'GLOBALS' )
Import( GLOBALS )
class idBuildCurl( scons_utils.idSetupBase ):
def Compile( self, target = None, source = None, env = None ):
if ( g_os == 'win32' ):
self.TrySimpleCommand( 'cd ' + self.curl_dir + '/lib/ ; make -f Makefile.m32 clean' )
cmd = 'cd ' + self.curl_dir + '/lib/ ; CC=\'' + env['CC'] + '\' make -f Makefile.m32 libcurl.a'
self.SimpleCommand( cmd )
if ( self.debug ):
self.SimpleCommand( 'cd ' + self.curl_dir + ' ; mv ./lib/libcurl.a ./lib/.libs/libcurl-debug.a' )
else:
self.SimpleCommand( 'cd ' + self.curl_dir + ' ; mv ./lib/libcurl.a ./lib/.libs/libcurl-release.a' )
else:
self.TrySimpleCommand( 'cd ' + self.curl_dir + ' ; make distclean' )
cmd = 'cd ' + self.curl_dir + ' ; CC=\'' + env['CC'] + '\' ./configure --enable-shared=no --enable-static=yes --enable-http --enable-ftp --disable-gopher --enable-file --disable-ldap --disable-dict --disable-telnet --disable-manual --enable-libgcc --disable-ipv6 --disable-ares --without-ssl --without-zlib --without-libidn '
if ( self.debug ):
cmd += '--enable-debug'
else:
cmd += '--disable-debug'
self.SimpleCommand( cmd )
self.SimpleCommand( 'cd ' + self.curl_dir + ' ; make' )
if ( self.debug ):
self.SimpleCommand( 'cd ' + self.curl_dir + ' ; mv ./lib/.libs/libcurl.a ./lib/.libs/libcurl-debug.a' )
else:
self.SimpleCommand( 'cd ' + self.curl_dir + ' ; mv ./lib/.libs/libcurl.a ./lib/.libs/libcurl-release.a' )
return 0
build = idBuildCurl()
build.curl_dir = 'curl-7.12.2'
if ( local_curl == 1 ):
build.debug = 1
target_name = '#' + build.curl_dir + '/lib/.libs/libcurl-debug.a'
else:
build.debug = 0
target_name = '#' + build.curl_dir + '/lib/.libs/libcurl-release.a'
g_env.Command( target_name, None, Action( build.Compile ) )
curl_libs = [ target_name ]
Return( 'curl_libs' )

97
src/SConscript.game Normal file
View File

@@ -0,0 +1,97 @@
# -*- mode: python -*-
# Enemy Territory build script
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import sys, os
import scons_utils
Import( 'GLOBALS' )
Import( GLOBALS )
botai_string = """
ai_cmd.c
ai_dmgoal_mp.c
ai_dmnet_mp.c
ai_dmq3.c
ai_main.c
ai_script.c
ai_script_actions.c
ai_team.c
"""
botai_list = scons_utils.BuildList( 'botai', botai_string )
qagame_string = """
bg_animation.c
bg_animgroup.c
bg_campaign.c
bg_character.c
bg_classes.c
bg_misc.c
bg_pmove.c
bg_slidemove.c
bg_sscript.c
bg_stats.c
bg_tracemap.c
g_active.c
g_alarm.c
g_antilag.c
g_bot.c
g_buddy_list.c
g_character.c
g_client.c
g_cmds.c
g_cmds_ext.c
g_combat.c
g_config.c
g_fireteams.c
g_items.c
g_main.c
g_match.c
g_mem.c
g_misc.c
g_missile.c
g_mover.c
g_multiview.c
g_props.c
g_referee.c
g_save.c
g_script.c
g_script_actions.c
g_session.c
g_spawn.c
g_stats.c
g_sv_entities.c
g_svcmds.c
g_syscalls.c
g_systemmsg.c
g_target.c
g_team.c
g_teammapdata.c
g_trigger.c
g_utils.c
g_vote.c
g_weapon.c
q_math.c
q_shared.c
"""
qagame_list = scons_utils.BuildList( 'game', qagame_string )
#botai_objs = []
#for i in botai_list:
# botlib_ai.append( botai_env.StaticObject( os.path.join( 'botlib', i ) ) )
local_env = g_env.Clone()
local_env.Append( CPPDEFINES = [ 'GAMEDLL' ] )
local_env['LINK'] = local_env['CC']
source_list = botai_list
source_list += qagame_list
#ret = local_env.Program( target = 'et', source = source_list )
ret = local_env.SharedLibrary( target = 'qagame', source = source_list )
Return( 'ret' )

39
src/SConscript.ui Normal file
View File

@@ -0,0 +1,39 @@
# -*- mode: python -*-
# Enemy Territory build script
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import sys, os
import scons_utils
Import( 'GLOBALS' )
Import( GLOBALS )
ui_string = """
ui_atoms.c
ui_gameinfo.c
ui_loadpanel.c
ui_main.c
ui_players.c
ui_shared.c
ui_syscalls.c
ui_util.c
../game/bg_campaign.c
../game/bg_classes.c
../game/bg_misc.c
../game/q_math.c
../game/q_shared.c
"""
ui_list = scons_utils.BuildList( 'ui', ui_string )
local_env = g_env.Clone()
local_env.Append( CPPDEFINES = [ 'UIDLL' ] )
source_list = ui_list
local_env['LINK'] = local_env['CC']
ret = local_env.SharedLibrary( target = 'ui', source = source_list )
Return( 'ret' )

408
src/SConstruct Normal file
View File

@@ -0,0 +1,408 @@
# -*- mode: python -*-
# ET build script
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import sys, os, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, string, tempfile
import SCons
import scons_utils
conf_filename='site.conf'
# choose configuration variables which should be saved between runs
# ( we handle all those as strings )
serialized=[ 'CC', 'CXX', 'JOBS', 'BUILD', 'BUILD_ROOT', 'DEDICATED', 'TARGET_CORE', 'TARGET_BSPC', 'TARGET_CGAME', 'TARGET_GAME', 'TARGET_UI', 'MASTER' ]
# help -------------------------------------------
Help("""
Usage: scons [OPTIONS] [TARGET] [CONFIG]
[OPTIONS] and [TARGET] are covered in command line options, use scons -H
[CONFIG]: KEY="VALUE" [...]
a number of configuration options saved between runs in the """ + conf_filename + """ file
erase """ + conf_filename + """ to start with default settings again
CC (default gcc)
CXX (default g++)
Specify C and C++ compilers (defaults gcc and g++)
ex: CC="gcc-3.3"
You can use ccache and distcc, for instance:
CC="ccache distcc gcc" CXX="ccache distcc g++"
JOBS (default 1)
Parallel build
BUILD (default debug)
Use debug-all/debug/release to select build settings
ex: BUILD="release"
debug-all: no optimisations, debugging symbols
debug: -O -g
release: all optimisations, including CPU target etc.
DEDICATED (default 2)
Control regular / dedicated type of build:
0 - client
1 - dedicated server
2 - both
TARGET_CORE (default 1)
Build engine
TARGET_BSPC (default 0)
Build bspc utility
TARGET_GAME (default 1)
Build game module
TARGET_CGAME (default 1)
Build cgame module
TARGET_UI (default 1)
Build ui module
BUILD_ROOT (default 'build')
change the build root directory
NOCONF (default 0, not saved)
ignore site configuration and use defaults + command line only
MASTER (default '')
set to override the default master server address
COPYBINS (default 0, not saved)
copy the binaries in a ready-to-release format
BUILDMPBIN (default 0, not saved)
build mp_bin.pk3 using bin/ directories and game binaries for all platforms
"""
)
# end help ---------------------------------------
# sanity -----------------------------------------
EnsureSConsVersion( 0, 96 )
# end sanity -------------------------------------
# system detection -------------------------------
# CPU type
cpu = commands.getoutput('uname -m')
dll_cpu = '???' # grmbl, alternative naming for .so
exp = re.compile('.*i?86.*')
if exp.match(cpu):
cpu = 'x86'
dll_cpu = 'i386'
else:
cpu = commands.getoutput('uname -p')
if ( cpu == 'powerpc' ):
cpu = 'ppc'
dll_cpu = cpu
else:
cpu = 'cpu'
dll_cpu = cpu
OS = commands.getoutput( 'uname -s' )
if ( OS == 'Darwin' ):
print 'EXPERIMENTAL - INCOMPLETE'
print 'Use the XCode projects to compile ET universal binaries for OSX'
cpu = 'osx'
dll_cpu = 'osx'
print 'cpu: ' + cpu
# end system detection ---------------------------
# default settings -------------------------------
CC = 'gcc -m32'
CXX = 'g++ -m32'
JOBS = '1'
BUILD = 'debug'
DEDICATED = '2'
TARGET_CORE = '1'
TARGET_GAME = '1'
TARGET_CGAME = '1'
TARGET_UI = '1'
TARGET_BSPC = '0'
BUILD_ROOT = 'build'
NOCONF = '0'
MASTER = ''
COPYBINS = '0'
BUILDMPBIN = '0'
# end default settings ---------------------------
# arch detection ---------------------------------
def gcc_major():
major = os.popen( CC + ' -dumpversion' ).read().strip()
major = re.sub('^([^.]+)\\..*$', '\\1', major)
print 'gcc major: %s' % major
return major
gcc3 = (gcc_major() != '2')
def gcc_is_mingw():
mingw = os.popen( CC + ' -dumpmachine' ).read()
return re.search('mingw', mingw) != None
if gcc_is_mingw():
g_os = 'win32'
elif OS == 'Darwin':
g_os = 'Darwin'
else:
g_os = 'Linux'
print 'OS: %s' % g_os
# end arch detection -----------------------------
# site settings ----------------------------------
if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
site_dict = {}
if (os.path.exists(conf_filename)):
site_file = open(conf_filename, 'r')
p = pickle.Unpickler(site_file)
site_dict = p.load()
print 'Loading build configuration from ' + conf_filename + ':'
for k, v in site_dict.items():
exec_cmd = k + '=\'' + v + '\''
print ' ' + exec_cmd
exec(exec_cmd)
else:
print 'Site settings ignored'
# end site settings ------------------------------
# command line settings --------------------------
for k in ARGUMENTS.keys():
exec_cmd = k + '=\'' + ARGUMENTS[k] + '\''
print 'Command line: ' + exec_cmd
exec( exec_cmd )
# end command line settings ----------------------
# save site configuration ----------------------
if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
for k in serialized:
exec_cmd = 'site_dict[\'' + k + '\'] = ' + k
exec(exec_cmd)
site_file = open(conf_filename, 'w')
p = pickle.Pickler(site_file)
p.dump(site_dict)
site_file.close()
# end save site configuration ------------------
# general configuration, target selection --------
g_build = BUILD_ROOT + '/' + BUILD
SConsignFile( 'scons.signatures' )
SetOption('num_jobs', JOBS)
if ( OS == 'Linux' ):
LINK = CC
else:
LINK = CXX
# common flags
# BASE + CORE + OPT for engine
# BASE + GAME + OPT for game
BASECPPFLAGS = [ ]
CORECPPPATH = [ ]
CORELIBPATH = [ ]
CORECPPFLAGS = [ ]
GAMECPPFLAGS = [ ]
BASELINKFLAGS = [ ]
CORELINKFLAGS = [ ]
# for release build, further optimisations that may not work on all files
OPTCPPFLAGS = [ ]
if ( OS == 'Darwin' ):
BASECPPFLAGS += [ '-D__MACOS__', '-Wno-long-double', '-Wno-unknown-pragmas', '-Wno-trigraphs', '-fpascal-strings', '-fasm-blocks', '-Wreturn-type', '-Wunused-variable', '-ffast-math', '-fno-unsafe-math-optimizations', '-fvisibility=hidden', '-mmacosx-version-min=10.4', '-isysroot', '/Developer/SDKs/MacOSX10.4u.sdk' ]
BASECPPFLAGS += [ '-arch', 'i386' ]
BASELINKFLAGS += [ '-arch', 'i386' ]
BASECPPFLAGS.append( '-pipe' )
# warn all
BASECPPFLAGS.append( '-Wall' )
# don't wrap gcc messages
BASECPPFLAGS.append( '-fmessage-length=0' )
if ( BUILD == 'debug-all' ):
BASECPPFLAGS.append( '-g' )
BASECPPFLAGS.append( '-D_DEBUG' )
elif ( BUILD == 'debug' ):
BASECPPFLAGS.append( '-g' )
BASECPPFLAGS.append( '-O1' )
BASECPPFLAGS.append( '-D_DEBUG' )
elif ( BUILD == 'release' ):
BASECPPFLAGS.append( '-DNDEBUG' )
if ( OS == 'Linux' ):
# -fomit-frame-pointer: gcc manual indicates -O sets this implicitely,
# only if that doesn't affect debugging
# on Linux, this affects backtrace capability, so I'm assuming this is needed
# -finline-functions: implicit at -O3
# -fschedule-insns2: implicit at -O3
# -funroll-loops ?
# -mfpmath=sse -msse ?
OPTCPPFLAGS = [ '-O3', '-march=i686', '-Winline', '-ffast-math', '-fomit-frame-pointer', '-finline-functions', '-fschedule-insns2' ]
elif ( OS == 'Darwin' ):
OPTCPPFLAGS = []
else:
print 'Unknown build configuration ' + BUILD
sys.exit(0)
# create the build environements
g_base_env = Environment( ENV = os.environ, CC = CC, CXX = CXX, LINK = LINK, CPPFLAGS = BASECPPFLAGS, LINKFLAGS = BASELINKFLAGS, CPPPATH = CORECPPPATH, LIBPATH = CORELIBPATH )
scons_utils.SetupUtils( g_base_env )
g_env = g_base_env.Clone()
g_env['CPPFLAGS'] += OPTCPPFLAGS
g_env['CPPFLAGS'] += CORECPPFLAGS
g_env['LINKFLAGS'] += CORELINKFLAGS
if ( OS == 'Darwin' ):
# configure for dynamic bundle
g_env['SHLINKFLAGS'] = '$LINKFLAGS -bundle -flat_namespace -undefined suppress'
g_env['SHLIBSUFFIX'] = '.so'
# maintain this dangerous optimization off at all times
g_env.Append( CPPFLAGS = '-fno-strict-aliasing' )
if ( int(JOBS) > 1 ):
print 'Using buffered process output'
scons_utils.SetupBufferedOutput( g_env )
# mark the globals
local_dedicated = 0
# curl
local_curl = 0 # config selection
curl_lib = []
GLOBALS = 'g_env OS g_os BUILD local_dedicated curl_lib local_curl MASTER gcc3 cpu'
# end general configuration ----------------------
# win32 cross compilation ----------------------
if g_os == 'win32' and os.name != 'nt':
# mingw doesn't define the cpu type, but our only target is x86
g_env.Append(CPPDEFINES = '_M_IX86=400')
g_env.Append(LINKFLAGS = '-static-libgcc')
# scons doesn't support cross-compiling, so set these up manually
g_env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
g_env['WIN32DEFSUFFIX'] = '.def'
g_env['PROGSUFFIX'] = '.exe'
g_env['SHLIBSUFFIX'] = '.dll'
g_env['SHCCFLAGS'] = '$CCFLAGS'
# end win32 cross compilation ------------------
# targets ----------------------------------------
toplevel_targets = []
# build curl if needed
if ( TARGET_CORE == '1' and DEDICATED != '1' and OS != 'Darwin' ):
# 1: debug, 2: release
if ( BUILD == 'release' ):
local_curl = 2
else:
local_curl = 1
Export( 'GLOBALS ' + GLOBALS )
curl_lib = SConscript( 'SConscript.curl' )
if ( TARGET_CORE == '1' ):
if ( DEDICATED == '0' or DEDICATED == '2' ):
local_dedicated = 0
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/core', '.', duplicate = 0 )
et = SConscript( g_build + '/core/SConscript.core' )
if ( g_os == 'win32' ):
toplevel_targets.append( InstallAs( '#et.exe', et ) )
else:
toplevel_targets.append( InstallAs( '#et.' + cpu, et ) )
if ( DEDICATED == '1' or DEDICATED == '2' ):
local_dedicated = 1
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/dedicated', '.', duplicate = 0 )
etded = SConscript( g_build + '/dedicated/SConscript.core' )
if ( g_os == 'win32' ):
toplevel_targets.append( InstallAs( '#etded.exe', etded ) )
else:
toplevel_targets.append( InstallAs( '#etded.' + cpu, etded ) )
if ( TARGET_BSPC == '1' ):
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/bspc', '.', duplicate = 0 )
bspc = SConscript( g_build + '/bspc/SConscript.bspc' )
toplevel_targets.append( InstallAs( '#bspc.' + cpu, bspc ) )
if ( TARGET_GAME == '1' ):
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/game', '.', duplicate = 0 )
game = SConscript( g_build + '/game/SConscript.game' )
toplevel_targets.append( InstallAs( '#qagame.mp.%s.so' % dll_cpu, game ) )
if ( TARGET_CGAME == '1' ):
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/cgame', '.', duplicate = 0 )
cgame = SConscript( g_build + '/cgame/SConscript.cgame' )
toplevel_targets.append( InstallAs( '#cgame.mp.%s.so' % dll_cpu, cgame ) )
if ( TARGET_UI == '1' ):
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/ui', '.', duplicate = 0 )
ui = SConscript( g_build + '/ui/SConscript.ui' )
toplevel_targets.append( InstallAs( '#ui.mp.%s.so' % dll_cpu, ui ) )
class CopyBins(scons_utils.idSetupBase):
def copy_bins( self, target, source, env ):
for i in source:
j = os.path.normpath( os.path.join( os.path.dirname( i.abspath ), '../bin', os.path.basename( i.abspath ) ) )
self.SimpleCommand( 'cp ' + i.abspath + ' ' + j )
if ( OS == 'Linux' ):
self.SimpleCommand( 'strip ' + j )
else:
# see strip and otool man pages on mac
self.SimpleCommand( 'strip -ur ' + j )
copybins_target = []
if ( COPYBINS != '0' ):
copy = CopyBins()
copybins_target.append( Command( 'copybins', toplevel_targets, Action( copy.copy_bins ) ) )
class MpBin(scons_utils.idSetupBase):
def mp_bin( self, target, source, env ):
temp_dir = tempfile.mkdtemp( prefix = 'mp_bin' )
self.SimpleCommand( 'cp ../bin/ui* ' + temp_dir )
self.SimpleCommand( 'cp ../bin/cgame* ' + temp_dir )
# zip the mac bundles
mac_bundle_dir = tempfile.mkdtemp( prefix = 'mp_mac' )
self.SimpleCommand( 'cp -R "../bin/Wolfenstein ET.app/Contents/Resources/ui_mac.bundle" ' + mac_bundle_dir )
self.SimpleCommand( 'cp -R "../bin/Wolfenstein ET.app/Contents/Resources/cgame_mac.bundle" ' + mac_bundle_dir )
self.SimpleCommand( 'find %s -name \.svn | xargs rm -rf' % mac_bundle_dir )
self.SimpleCommand( 'cd %s ; zip -r -D %s/ui_mac.zip ui_mac.bundle ; mv %s/ui_mac.zip %s/ui_mac' % ( mac_bundle_dir, temp_dir, temp_dir, temp_dir ) )
self.SimpleCommand( 'cd %s ; zip -r -D %s/cgame_mac.zip cgame_mac.bundle ; mv %s/cgame_mac.zip %s/cgame_mac' % ( mac_bundle_dir, temp_dir, temp_dir, temp_dir ) )
mp_bin_path = os.path.abspath( os.path.join ( os.getcwd(), '../etmain/mp_bin.pk3' ) )
self.SimpleCommand( 'cd %s ; zip -r -D %s *' % ( temp_dir, mp_bin_path ) )
if ( BUILDMPBIN != '0' ):
mp_bin = MpBin()
mpbin_target = Command( 'mp_bin', toplevel_targets + copybins_target, Action( mp_bin.mp_bin ) )
# end targets ------------------------------------

380
src/SConstruct.sdk Normal file
View File

@@ -0,0 +1,380 @@
# -*- mode: python -*-
# ET build script
# TTimo <ttimo@idsoftware.com>
# http://scons.sourceforge.net
import sys, os, time, commands, re, pickle, StringIO, popen2, commands, pdb, zipfile, string, tempfile
import SCons
import scons_utils
conf_filename='site.conf'
# choose configuration variables which should be saved between runs
# ( we handle all those as strings )
serialized=[ 'CC', 'CXX', 'JOBS', 'BUILD', 'BUILD_ROOT', 'TARGET_CGAME', 'TARGET_GAME', 'TARGET_UI', 'GAMERANGER' ]
# help -------------------------------------------
Help("""
Usage: scons [OPTIONS] [TARGET] [CONFIG]
[OPTIONS] and [TARGET] are covered in command line options, use scons -H
[CONFIG]: KEY="VALUE" [...]
a number of configuration options saved between runs in the """ + conf_filename + """ file
erase """ + conf_filename + """ to start with default settings again
CC (default gcc)
CXX (default g++)
Specify C and C++ compilers (defaults gcc and g++)
ex: CC="gcc-3.3"
You can use ccache and distcc, for instance:
CC="ccache distcc gcc" CXX="ccache distcc g++"
JOBS (default 1)
Parallel build
BUILD (default debug)
Use debug-all/debug/release to select build settings
ex: BUILD="release"
debug-all: no optimisations, debugging symbols
debug: -O -g
release: all optimisations, including CPU target etc.
DEDICATED (default 2)
Control regular / dedicated type of build:
0 - client
1 - dedicated server
2 - both
TARGET_GAME (default 1)
Build game module
TARGET_CGAME (default 1)
Build cgame module
TARGET_UI (default 1)
Build ui module
BUILD_ROOT (default 'build')
change the build root directory
NOCONF (default 0, not saved)
ignore site configuration and use defaults + command line only
COPYBINS (default 0, not saved)
copy the binaries in a ready-to-release format
BUILDMPBIN (default 0, not saved)
build mp_bin.pk3 using bin/ directories and game binaries for all platforms
BUILDBUNDLE (default 0, not saved)
create mac bundle files
"""
)
# end help ---------------------------------------
# sanity -----------------------------------------
EnsureSConsVersion( 0, 96 )
# end sanity -------------------------------------
# system detection -------------------------------
# CPU type
cpu = commands.getoutput('uname -m')
dll_cpu = '???' # grmbl, alternative naming for .so
exp = re.compile('.*i?86.*')
if exp.match(cpu):
cpu = 'x86'
dll_cpu = 'i386'
else:
cpu = commands.getoutput('uname -p')
if ( cpu == 'powerpc' ):
cpu = 'ppc'
dll_cpu = cpu
else:
cpu = 'cpu'
dll_cpu = cpu
OS = commands.getoutput( 'uname -s' )
print 'cpu: ' + cpu
# end system detection ---------------------------
# default settings -------------------------------
CC = 'gcc'
CXX = 'g++'
JOBS = '1'
BUILD = 'debug'
DEDICATED = '2'
TARGET_GAME = '1'
TARGET_CGAME = '1'
TARGET_UI = '1'
GAMERANGER = '0'
BUILD_ROOT = 'build'
NOCONF = '0'
COPYBINS = '0'
BUILDMPBIN = '0'
BUILDBUNDLE = '0'
# end default settings ---------------------------
# arch detection ---------------------------------
def gcc_major():
major = os.popen( CC + ' -dumpversion' ).read().strip()
print 'dumpversion: %s' % major
major = re.sub('^([^.]+)\\..*$', '\\1', major)
print 'gcc major: %s' % major
return major
gcc3 = (gcc_major() != '2')
def gcc_is_mingw():
mingw = os.popen( CC + ' -dumpmachine' ).read()
return re.search('mingw', mingw) != None
if gcc_is_mingw():
g_os = 'win32'
elif cpu == 'ppc':
g_os = 'Darwin'
else:
g_os = 'Linux'
print 'os: %s' % g_os
# end arch detection -----------------------------
# site settings ----------------------------------
if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
site_dict = {}
if (os.path.exists(conf_filename)):
site_file = open(conf_filename, 'r')
p = pickle.Unpickler(site_file)
site_dict = p.load()
print 'Loading build configuration from ' + conf_filename + ':'
for k, v in site_dict.items():
exec_cmd = k + '=\'' + v + '\''
print ' ' + exec_cmd
exec(exec_cmd)
else:
print 'Site settings ignored'
# end site settings ------------------------------
# command line settings --------------------------
for k in ARGUMENTS.keys():
exec_cmd = k + '=\'' + ARGUMENTS[k] + '\''
print 'Command line: ' + exec_cmd
exec( exec_cmd )
# end command line settings ----------------------
# save site configuration ----------------------
if ( not ARGUMENTS.has_key( 'NOCONF' ) or ARGUMENTS['NOCONF'] != '1' ):
for k in serialized:
exec_cmd = 'site_dict[\'' + k + '\'] = ' + k
exec(exec_cmd)
site_file = open(conf_filename, 'w')
p = pickle.Pickler(site_file)
p.dump(site_dict)
site_file.close()
# end save site configuration ------------------
# arch detection ---------------------------------
def gcc_major():
major = os.popen( CC + ' -dumpversion' ).read().strip()
major = re.sub('^([^.]+)\\..*$', '\\1', major)
print 'gcc major: %s' % major
return major
gcc3 = (gcc_major() != '2')
def gcc_is_mingw():
mingw = os.popen( CC + ' -dumpmachine' ).read()
return re.search('mingw', mingw) != None
win32_build = gcc_is_mingw()
# end arch detection -----------------------------
# general configuration, target selection --------
g_build = BUILD_ROOT + '/' + BUILD
SConsignFile( 'scons.signatures' )
SetOption('num_jobs', JOBS)
if ( OS == 'Linux' ):
LINK = CC
else:
LINK = CXX
# common flags
# BASE + GAME + OPT for game
BASECPPFLAGS = [ ]
CORECPPPATH = [ ]
CORELIBPATH = [ ]
CORECPPFLAGS = [ ]
GAMECPPFLAGS = [ ]
BASELINKFLAGS = [ ]
CORELINKFLAGS = [ ]
# for release build, further optimisations that may not work on all files
OPTCPPFLAGS = [ ]
if ( OS == 'Darwin' ):
# taken from xcode's default project settings
BASECPPFLAGS += [ '-D__MACOS__', '-Wno-long-double', '-arch', 'ppc', '-fasm-blocks', '-fpascal-strings', '-faltivec', '-mcpu=G4', '-mtune=G4', '-Wno-unknown-pragmas' ]
BASECPPFLAGS.append( '-pipe' )
# warn all
BASECPPFLAGS.append( '-Wall' )
# don't wrap gcc messages
BASECPPFLAGS.append( '-fmessage-length=0' )
if ( BUILD == 'debug-all' ):
BASECPPFLAGS.append( '-g' )
BASECPPFLAGS.append( '-D_DEBUG' )
elif ( BUILD == 'debug' ):
BASECPPFLAGS.append( '-g' )
BASECPPFLAGS.append( '-O1' )
BASECPPFLAGS.append( '-D_DEBUG' )
elif ( BUILD == 'release' ):
BASECPPFLAGS.append( '-DNDEBUG' )
if ( OS == 'Linux' ):
# -fomit-frame-pointer: gcc manual indicates -O sets this implicitely,
# only if that doesn't affect debugging
# on Linux, this affects backtrace capability, so I'm assuming this is needed
# -finline-functions: implicit at -O3
# -fschedule-insns2: implicit at -O3
# -funroll-loops ?
# -mfpmath=sse -msse ?
OPTCPPFLAGS = [ '-O3', '-march=i686', '-Winline', '-ffast-math', '-fomit-frame-pointer', '-finline-functions', '-fschedule-insns2' ]
elif ( OS == 'Darwin' ):
OPTCPPFLAGS = [ '-O3', '-falign-functions=16', '-falign-loops=16', '-finline' ]
else:
print 'Unknown build configuration ' + BUILD
sys.exit(0)
# create the build environments
g_base_env = Environment( ENV = os.environ, CC = CC, CXX = CXX, LINK = LINK, CPPFLAGS = BASECPPFLAGS, LINKFLAGS = BASELINKFLAGS, CPPPATH = CORECPPPATH, LIBPATH = CORELIBPATH )
scons_utils.SetupUtils( g_base_env )
g_env = g_base_env.Clone()
g_env['CPPFLAGS'] += OPTCPPFLAGS
g_env['CPPFLAGS'] += CORECPPFLAGS
g_env['LINKFLAGS'] += CORELINKFLAGS
if ( OS == 'Darwin' ):
# configure for dynamic bundle
g_env['SHLINKFLAGS'] = '$LINKFLAGS -bundle -flat_namespace -undefined suppress'
g_env['SHLIBSUFFIX'] = '.so'
# maintain this dangerous optimization off at all times
g_env.Append( CPPFLAGS = '-fno-strict-aliasing' )
if ( int(JOBS) > 1 ):
print 'Using buffered process output'
scons_utils.SetupBufferedOutput( g_env )
# mark the globals
GLOBALS = 'g_env OS g_os BUILD gcc3 cpu GAMERANGER'
# end general configuration ----------------------
# win32 cross compilation ----------------------
if g_os == 'win32' and os.name != 'nt':
# mingw doesn't define the cpu type, but our only target is x86
g_env.Append(CPPDEFINES = '_M_IX86=400')
g_env.Append(LINKFLAGS = '-static-libgcc')
# scons doesn't support cross-compiling, so set these up manually
g_env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
g_env['WIN32DEFSUFFIX'] = '.def'
g_env['PROGSUFFIX'] = '.exe'
g_env['SHLIBSUFFIX'] = '.dll'
g_env['SHCCFLAGS'] = '$CCFLAGS'
# end win32 cross compilation ------------------
# targets ----------------------------------------
toplevel_targets = []
if ( TARGET_GAME == '1' ):
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/game', '.', duplicate = 0 )
game = SConscript( g_build + '/game/SConscript.game' )
toplevel_targets.append( InstallAs( '#qagame.mp.%s.so' % dll_cpu, game ) )
if ( TARGET_CGAME == '1' ):
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/cgame', '.', duplicate = 0 )
cgame = SConscript( g_build + '/cgame/SConscript.cgame' )
toplevel_targets.append( InstallAs( '#cgame.mp.%s.so' % dll_cpu, cgame ) )
if ( TARGET_UI == '1' ):
Export( 'GLOBALS ' + GLOBALS )
BuildDir( g_build + '/ui', '.', duplicate = 0 )
ui = SConscript( g_build + '/ui/SConscript.ui' )
toplevel_targets.append( InstallAs( '#ui.mp.%s.so' % dll_cpu, ui ) )
class CopyBins(scons_utils.idSetupBase):
def copy_bins( self, target, source, env ):
for i in source:
j = os.path.normpath( os.path.join( os.path.dirname( i.abspath ), '../bin', os.path.basename( i.abspath ) ) )
self.SimpleCommand( 'cp ' + i.abspath + ' ' + j )
if ( OS == 'Linux' ):
self.SimpleCommand( 'strip ' + j )
else:
# see strip and otool man pages on mac
self.SimpleCommand( 'strip -ur ' + j )
copybins_target = []
if ( COPYBINS != '0' ):
copy = CopyBins()
copybins_target.append( Command( 'copybins', toplevel_targets, Action( copy.copy_bins ) ) )
class MpBin(scons_utils.idSetupBase):
def mp_bin( self, target, source, env ):
temp_dir = tempfile.mkdtemp( prefix = 'mp_bin' )
self.SimpleCommand( 'cp ../bin/ui* ' + temp_dir )
self.SimpleCommand( 'cp ../bin/cgame* ' + temp_dir )
# zip the mac bundles
mac_bundle_dir = tempfile.mkdtemp( prefix = 'mp_mac' )
self.SimpleCommand( 'cp -R "../bin/Wolfenstein ET.app/Contents/Resources/ui_mac.bundle" ' + mac_bundle_dir )
self.SimpleCommand( 'cp -R "../bin/Wolfenstein ET.app/Contents/Resources/cgame_mac.bundle" ' + mac_bundle_dir )
self.SimpleCommand( 'find %s -name \.svn | xargs rm -rf' % mac_bundle_dir )
self.SimpleCommand( 'cd %s ; zip -r -D %s/ui_mac.zip ui_mac.bundle ; mv %s/ui_mac.zip %s/ui_mac' % ( mac_bundle_dir, temp_dir, temp_dir, temp_dir ) )
self.SimpleCommand( 'cd %s ; zip -r -D %s/cgame_mac.zip cgame_mac.bundle ; mv %s/cgame_mac.zip %s/cgame_mac' % ( mac_bundle_dir, temp_dir, temp_dir, temp_dir ) )
mp_bin_path = os.path.abspath( os.path.join ( os.getcwd(), '../etmain/mp_bin.pk3' ) )
self.SimpleCommand( 'cd %s ; zip -r -D %s *' % ( temp_dir, mp_bin_path ) )
if ( BUILDMPBIN != '0' ):
mp_bin = MpBin()
mpbin_target = Command( 'mp_bin', toplevel_targets + copybins_target, Action( mp_bin.mp_bin ) )
class BuildBundle(scons_utils.idSetupBase):
def make_bundle( self, target, source, env ):
for i in source:
self.SimpleCommand( './makebundle.sh %s' % i )
if ( BUILDBUNDLE != '0' ):
build_bundle = BuildBundle()
bundle_target = Command( 'build_bundle', toplevel_targets, Action( build_bundle.make_bundle ) )
# end targets ------------------------------------

1540
src/botai/ai_cmd.c Normal file

File diff suppressed because it is too large Load Diff

40
src/botai/ai_cmd.h Normal file
View File

@@ -0,0 +1,40 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: ai_cmd.h
*
* desc: Wolf bot AI
*
*
*****************************************************************************/
int BotMatchMessage( bot_state_t *bs, char *message );
void BotPrintTeamGoal( bot_state_t *bs );

262
src/botai/ai_distances.h Normal file
View File

@@ -0,0 +1,262 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: ai_distances.h
*
* desc: Distance constants used by the AI in Single Player
*
*
*****************************************************************************/
// Distance bots follow the leader
#define kBOT_FOLLOW_DIST 100
// When is a bot close enough to it's goal?
// For when the goal is another bot
#define kBOT_CLOSE_ENOUGH 72
// For when we have a location goal
#define kBOT_LOC_CLOSE_ENOUGH 40
// When looking for nearby goals (to pick up health/ammo/flags), how far away can we look
#define kBOT_NEARBY_GOAL_DIST 384
// When looking for nearby goals (to pick up health/ammo/flags), how long can we take to get there
#define kBOT_NEARBY_GOAL_TIME 1000
// For goals where we need to touch our target - revive, get disguise, open door
#define kBOT_TOUCHING_DIST 50
// How far to retreat after reviving someone
#define kBOT_REVIVE_RETREAT_DIST 96
// How close we should be to call in an airstrike, or throw a smoke grenade
#define kBOT_AIRSTRIKE_DISTANCE 160
// The range we're using for the grenade launcher WP_M7
#define kBOT_M7_RANGE 1024
// Ok, so these aren't distances. Oh well
// The health fractions at which bots start requesting a medic
#define kBOT_INJURED_LEVEL 0.4f
#define kBOT_REALLYINJURED_LEVEL 0.2f
// It a client is going faster than this, we think they're moving
#define kBOT_ENTITY_MOVING_UNSTEALTHY_SPEED 2
// If our best enemy is this close to us, and we're on an mg42, drop
// the gun...
#define kBOT_DROP_MG42_DISTANCE 240 // 20 feet roughly
// If our best enemy is this close, and out of our gun arc, drop
// the mg42
#define kBOT_DROP_MG42_DISTANCE_OUT_OF_ARC 480 // 40 feet roughly
// Really way too far for an mg42 to shoot
#define kBOT_MAX_MG42_TARGET_RANGE 2400
// Radius to call for help - idle friendly bots in this radius are expected to come help their teammates
#define kBOT_HELP_RADIUS 1000
// how close should player be to play the idle animation
#define kBOT_IDLE_ANIM_DISTANCE 384
// A distance which is much bigger than any we'd really ever need
#define kBOT_GIGANTIC_DISTANCE 999999
// The range out of which a bot will advance towards the player
#define kBOT_CHASE_RANGE 1200
// Don't go to a seek cover spot further than this
#define kBOT_MAX_SEEK_COVER_RANGE 1000
// Maximum distance enemies can be from you to be considered in the
// AAS_Retreat code
#define kBOT_MAX_RETREAT_ENEMY_DIST 2000
// How much away from our current pos we'd like to be on retreat
#define kBOT_RETREAT_FROM_CURRENT_POS_DIST 200
// How much away from any danger we'd like to be on retreat
#define kBOT_RETREAT_FROM_DANGER_DIST 800
// How close is close enough when retreating to the player
#define kBOT_RETREAT_TO_PLAYER_DIST 192
// How close is close enough to apply the "I'm near a leader" bonusses
#define kBOT_NEAR_LEADER_DISTANCE 800
// How far is far enough that we get max "No leader" penalty
#define kBOT_FAR_FROM_LEADER_DISTANCE 2000
// How long when following to change modes
#define kBOT_FOLLOW_DEFAULT_TIME 1500
#define kBOT_FOLLOW_DEFAULT_RAND_TIME 2500
// time to change follow stance
#define kBOT_FOLLOW_STANCE_TIME 1000
#define kBOT_FOLLOW_STANCE_RAND_TIME 4000
// Time after standing still to seek cover
#define kBOT_STAND_SEEKCOVER_TIME 5000
#define kBOT_STAND_SEEKCOVER_RAND_TIME 3000
// Distance can travel on stand to seek cover - should be pretty small
#define kBOT_STAND_SEEKCOVER_DIST 256
///////////////////////////////////////
//
// SPEED CONSTANTS
//
///////////////////////////////////////
#define kBOT_FOLLOW_SPEED_BONUS ( 1.25f )
///////////////////////////////////////
//
// TIME CONSTANTS
//
// Most of these are in milliseconds
//
///////////////////////////////////////
// A short period of time to indicate we were just shot by someone
#define kBOT_JUST_SHOT_TIME 1000
// Max travel time a bot will spend travelling to heal/give ammo on a give team health/ammo command
// NOTE: also checks autonomy range, so this is just an additional check
#define kBOT_MAX_RESUPPLY_TRAVEL_TIME 3000
//////////////////////////////
// Combat time constants
//
// Time to give up on an enemy when you haven't been able to shoot at him
#define kBOT_ENEMY_GIVEUP_TIME 20000
// How long minimum to stay at a combat spot?
#define kBOT_MIN_COMBAT_SPOT_TIME 3500
// Random addition for staying at a combat spot
#define kBOT_RANDOM_COMBAT_SPOT_TIME 5500
// Time to stay at a cover spot if we're switching between it and an exposed spot
#define kBOT_MIN_COVERSPOT_TIME_WITH_EXPOSED 12000
// and random addition
#define kBOT_RANDOM_COVERSPOT_TIME_WITH_EXPOSED 4000
// How long minimum to stay crouched down?
#define kBOT_HIDE_MIN_TIME 3500
// How much to vary the crouch time randomly
#define kBOT_HIDE_TIME_RANDOM 2500
// How long to stand up after hiding in a seek cover spot
#define kBOT_COVER_STAND_MIN_TIME 500
// and random addition
#define kBOT_COVER_STAND_TIME_RANDOM 1000
// For how long after we've been shot will we do evasive maneuvers (only with no seek cover spot!)
#define kBOT_EVASIVE_MANEUVER_TIME 5000
// How often do we check to see if we can fire
#define kBOT_MIN_FIRE_CYCLE_TIME 1500
#define kBOT_MAX_FIRE_CYCLE_TIME 2700
// For how long do we consider an axis cover spot claimed
#define kBOT_IGNORE_COMBAT_SPOT_TIME 500
// Don't keep replanning our retreat location too often.
#define kBOT_MIN_RETREAT_REPLAN_TIME 3000
// If we've retreated and not been shot for a while, go to Stand.
#define kBOT_MAX_RETREAT_TIME 45000
// Minimum time to wait between calling for help
#define kBOT_MIN_CALL_FOR_HELP_TIME 15000
// If an enemy is within this distance, bot won't go prone
#define kBOT_MIN_PRONE_DIST 256
////////////////////////////////////////////////
// Retreat to Player constants
//
// How frequently do we check to see if we should retreat?
#define kBOT_RETREAT_UPDATE_TIME 100
#define kBOT_RETREAT_UPDATE_RANDOM 500
// Damage level below which we never break - this gets modified by the wimp factor
#define kBOT_RETREAT_DAMAGE_THRESHOLD 0.75f
// Damage level at which we are considered to be about to die
#define kBOT_RETREAT_ABOUT_TO_DIE_DAMAGE 0.8f
// Multiplier to wimp factor to decide when we retreat to player
#define kBOT_RETREAT_MULTIPLIER 1.0
// when we retreat all out
#define kBOT_RETREAT_ALLOUT_MULTIPLIER 2.0
// Percent of damage ratio to add to likeliness to break
#define kBOT_RETREAT_DAMAGE_FACTOR 0.5f
// Multiplier to distance ratio to add to likeliness
#define kBOT_RETREAT_DISTANCE_FACTOR 0.3f
// Maximum distFactor we care about for retreating
#define kBOT_MAX_RETREAT_DIST_FACTOR 3.0f
// Amount to increase break likeliness if...
// can't see the player
#define kBOT_RETREAT_PLAYER_OUTOFSIGHT 0.2f
// player is dead
#define kBOT_RETREAT_PLAYER_DEAD 0.4f
// How long after retreating before we can engage again?
#define kBOT_RETREAT_TIMETOENGAGE 20000
////////////////////////////////////////////////
// Combat penalty constants
//
// How much to penalize damage ratio based on distance from leader
// NOTE: 1 == take full damage at max dist, 0 == use scripted ratio
#define NO_LEADER_DAMAGE_PENALTY ( 0.6f )
// How much to penalize the aiming accuracy based on distance from
// leader. 1 == can't hit at all, 0 == No penalty
#define NO_LEADER_MAX_AIM_PENALTY ( 0.5f )
// how much inaccuracy to remove. e.g. 0.5 = 50% less inaccuracy
#define AIM_ACCURACY_BONUS_PRONE 0.5
#define AIM_ACCURACY_BONUS_CROUCH 0.3
#define AIM_SKILL_BONUS_PRONE 0.5
#define AIM_ACCURACY_ENEMY_PENALTY_PRONE 0.5
#define AIM_ACCURACY_ENEMY_PENALTY_CROUCH 0.2

3079
src/botai/ai_dmgoal_mp.c Normal file

File diff suppressed because it is too large Load Diff

46
src/botai/ai_dmgoal_mp.h Normal file
View File

@@ -0,0 +1,46 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: ai_dmgoal_mp.h
*
* desc: Wolf bot AI
*
*
*****************************************************************************/
//
// MULTIPLAYER GOAL AI
//
qboolean BotMP_CheckEmergencyGoals( bot_state_t *bs );
qboolean BotMP_FindGoal( bot_state_t *bs );
// Gordon: new version
qboolean BotMP_FindGoal_New( bot_state_t *bs );

6696
src/botai/ai_dmnet_mp.c Normal file

File diff suppressed because it is too large Load Diff

102
src/botai/ai_dmnet_mp.h Normal file
View File

@@ -0,0 +1,102 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: ai_dmnet_mp.h
*
* desc: Wolf bot AI
*
*
*****************************************************************************/
void AIEnter_MP_PlantMine( bot_state_t *bs );
void AIEnter_MP_Intermission( bot_state_t *bs );
void AIEnter_MP_Observer( bot_state_t *bs );
void AIEnter_MP_Respawn( bot_state_t *bs );
void AIEnter_MP_Stand( bot_state_t *bs );
void AIEnter_MP_Seek_ActivateEntity( bot_state_t *bs );
void AIEnter_MP_Seek_NBG( bot_state_t *bs );
void AIEnter_MP_Seek_LTG( bot_state_t *bs );
void AIEnter_MP_Seek_Camp( bot_state_t *bs );
void AIEnter_MP_Battle_Fight( bot_state_t *bs );
void AIEnter_MP_Battle_Chase( bot_state_t *bs );
void AIEnter_MP_Battle_Retreat( bot_state_t *bs );
void AIEnter_MP_DynamiteTarget( bot_state_t *bs );
void AIEnter_MP_SatchelChargeTarget( bot_state_t *bs );
void AIEnter_MP_ConstructibleTarget( bot_state_t *bs );
void AIEnter_MP_TouchTarget( bot_state_t *bs );
void AIEnter_MP_DefendTarget( bot_state_t *bs );
void AIEnter_MP_MedicRevive( bot_state_t *bs );
void AIEnter_MP_MedicGiveHealth( bot_state_t *bs );
void AIEnter_MP_DisarmDynamite( bot_state_t *bs );
void AIEnter_MP_AvoidDanger( bot_state_t *bs );
void AIEnter_MP_GiveAmmo( bot_state_t *bs );
void AIEnter_MP_PanzerTarget( bot_state_t *bs );
void AIEnter_MP_SniperSpot( bot_state_t *bs );
void AIEnter_MP_ScanForLandmines( bot_state_t *bs );
void AIEnter_MP_FixMG42( bot_state_t *bs );
void AIEnter_MP_MG42Scan( bot_state_t *bs );
void AIEnter_MP_MG42Mount( bot_state_t *bs );
void AIEnter_MP_Script_MoveToMarker( bot_state_t *bs );
void AIEnter_MP_MoveToAutonomyRange( bot_state_t *bs );
void AIEnter_MP_PanzerTarget( bot_state_t *bs );
void AIEnter_MP_AttackTarget( bot_state_t *bs );
void AIEnter_MP_NavigateFromVoid( bot_state_t *bs );
void AIEnter_MP_Battle_MobileMG42( bot_state_t *bs );
int AINode_MP_PlantMine( bot_state_t *bs );
int AINode_MP_Intermission( bot_state_t *bs );
int AINode_MP_Observer( bot_state_t *bs );
int AINode_MP_Respawn( bot_state_t *bs );
int AINode_MP_Stand( bot_state_t *bs );
int AINode_MP_Seek_ActivateEntity( bot_state_t *bs );
int AINode_MP_Seek_NBG( bot_state_t *bs );
int AINode_MP_Battle_Fight( bot_state_t *bs );
int AINode_MP_Battle_Chase( bot_state_t *bs );
int AINode_MP_Battle_Retreat( bot_state_t *bs );
int AINode_MP_DynamiteTarget( bot_state_t *bs );
int AINode_MP_SatchelChargeTarget( bot_state_t *bs );
int AINode_MP_ConstructibleTarget( bot_state_t *bs );
int AINode_MP_TouchTarget( bot_state_t *bs );
int AINode_MP_DefendTarget( bot_state_t *bs );
int AINode_MP_MedicRevive( bot_state_t *bs );
int AINode_MP_MedicGiveHealth( bot_state_t *bs );
int AINode_MP_DisarmDynamite( bot_state_t *bs );
int AINode_MP_AvoidDanger( bot_state_t *bs );
int AINode_MP_GiveAmmo( bot_state_t *bs );
int AINode_MP_PanzerTarget( bot_state_t *bs );
int AINode_MP_SniperSpot( bot_state_t *bs );
int AINode_MP_FixMG42( bot_state_t *bs );
int AINode_MP_MG42Scan( bot_state_t *bs );
int AINode_MP_MG42Mount( bot_state_t *bs );
int AINode_MP_ScanForLandmines( bot_state_t *bs );
int AINode_MP_Script_MoveToMarker( bot_state_t *bs );
int AINode_MP_MoveToAutonomyRange( bot_state_t *bs );
int AINode_MP_AttackTarget( bot_state_t *bs );
int AINode_MP_NavigateFromVoid( bot_state_t *bs );
int AINode_MP_Battle_MobileMG42( bot_state_t *bs );

7572
src/botai/ai_dmq3.c Normal file

File diff suppressed because it is too large Load Diff

313
src/botai/ai_dmq3.h Normal file
View File

@@ -0,0 +1,313 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: ai_dmq3.h
*
* desc: Wolf bot AI
*
*
*****************************************************************************/
// How many targets we'll let the bots choose between?
#define BOT_MAX_POTENTIAL_TARGETS 10
// This value stands for an un-inited/bad target
#define BOT_INVALID_TARGET ( -1 )
// Penalties and bonusses used in choosing targets
#define BOT_TARGET_ALREADY_TARGETTED_PENALTY ( 5 )
#define BOT_TARGET_PERSISTENT_ENEMY_BONUS ( -2 )
#define BOT_TARGET_SHOT_ME_BONUS ( -9 )
#define BOT_TARGET_VISUAL_BONUS ( -2 )
///////////////////////////////////////////////////////////////////////////////
//
// STRUCT BotTarget
//
typedef struct BotTarget_s
{
// Who is this target?
int m_target;
// Distance from bot
float m_distance;
// Did he shoot us?
qboolean m_thisGuyShotUsDammit;
// Did we see him?
qboolean m_canSeeTarget;
// Did we hear him?
qboolean m_canHearTarget;
// Did we hear footsteps?
qboolean m_heardFootSteps;
// Did we hear shooting?
qboolean m_heardShooting;
} BotTarget_t;
//
// STRUCT AI_Team
//
///////////////////////////////////////////////////////////////////////////////
// Did this bot just shoot me?
qboolean BotJustShotMe( bot_state_t *bs, int suspect );
void BotCountLandMines( void );
int BotBestTargetWeapon( bot_state_t *bs, int targetNum );
gentity_t *BotGetVisibleDamagableScriptMover( bot_state_t *bs );
qboolean BotEnemyCarryingFlag( int entnum );
float BotHealthScale( int entnum );
int BotGetNumVisibleSniperSpots( bot_state_t *bs );
int BotCanSnipe( bot_state_t *bs, qboolean checkAmmo );
qboolean BotIsConstructible( team_t botTeam, int toiNum );
qboolean BotGetReachableEntityArea( bot_state_t *bs, int entityNum, bot_goal_t *goal );
qboolean BotEntityTargetClassnameMatch( int entityNum, const char *classname );
qboolean BotDirectMoveToGoal( bot_state_t *bs, bot_goal_t *goal, bot_moveresult_t *moveresult );
int BotLastHurt( bot_state_t *bs );
qboolean BotBattleNewNode( bot_state_t *bs );
int BotLastAttacked( bot_state_t *bs );
int BotTravelTimeToEntity( bot_state_t *bs, int entnum );
int BotReduceListByTravelTime( int *list, int numList, vec3_t destpos, int destarea, int traveltime );
qboolean BotCanAttack( bot_state_t *bs );
float *BotGetOrigin( int entnum );
float *BotGetEye( int entnum );
int BotGetArea( int entnum );
qboolean BotSeekCover( bot_state_t *bs );
void BotShareLastAttacked( bot_state_t *bs );
char *BotStringForMovementAutonomy( int value );
char *BotStringForWeaponAutonomy( int value );
qboolean BotCanPursue( bot_state_t *bs, int enemy );
int BotGetMovementAutonomyLevel( bot_state_t *bs );
void BotEnemyFire( bot_state_t *bs );
void BotDefaultNode( bot_state_t *bs );
qboolean BotGetMovementAutonomyPos( bot_state_t *bs, vec3_t pos );
qboolean BotCheckEmergencyTargets( bot_state_t *bs );
qboolean BotFindSpecialGoals( bot_state_t *bs );
void BotCheckVoiceChats( bot_state_t *bs );
int BotWeaponAutonomyForString( char *string );
int BotMovementAutonomyForString( char *string );
int BotScriptAutonomyForString( char *string );
float BotGetRawMovementAutonomyRange( bot_state_t *bs );
float BotGetMovementAutonomyRange( bot_state_t *bs, bot_goal_t *goal );
// Start - TAT 9/18/2002
// What distance should a bot be from its leader during a follow order? Based on autonomy
float BotGetFollowAutonomyDist( bot_state_t *bs );
// Is a bot within the desired distance of its leader?
qboolean BotWithinLeaderFollowDist( bot_state_t *bs );
// End - TAT 9/18/2002
// Start TAT 9/23/2002
// Update recon state information for a bot
void BotUpdateReconInfo( bot_state_t *bs );
qboolean BotPointWithinMovementAutonomy( bot_state_t *bs, bot_goal_t *goal, vec3_t point );
qboolean BotPointWithinRawMovementAutonomy( bot_state_t *bs, vec3_t point );
qboolean BotGoalWithinMovementAutonomy( bot_state_t *bs, bot_goal_t *goal, int urgency );
qboolean BotCheckMovementAutonomy( bot_state_t *bs, bot_goal_t *goal );
qboolean BotGoalForEntity( bot_state_t *bs, int entityNum, bot_goal_t *goal, int urgency );
qboolean BotDangerousGoal( bot_state_t *bs, bot_goal_t *goal );
qboolean BotCarryingFlag( int client );
qboolean BotFindNearbyGoal( bot_state_t *bs );
float BotWeaponWantScale( bot_state_t *bs, weapon_t weapon );
qboolean BotWeaponCharged( bot_state_t *bs, int weapon );
void BotRecordTeamChange( int client );
void BotRecordKill( int client, int enemy );
void BotRecordPain( int client, int enemy, int mod );
void BotRecordDeath( int client, int enemy );
void BotGetAimAccuracySkill( bot_state_t *bs, float *outAimAccuracy, float *outSkill );
int BotBestSniperSpot( bot_state_t *bs );
int BotBestLandmineSpotingSpot( bot_state_t *bs );
int BotGetRandomVisibleSniperSpot( bot_state_t *bs );
void BotClearGoal( bot_goal_t *goal );
qboolean BotGotEnoughAmmoForWeapon( bot_state_t *bs, int weapon );
int BotReachableBBoxAreaNum( bot_state_t *bs, vec3_t absmin, vec3_t absmax );
void BotDropFlag( bot_state_t *bs );
int BotBestMG42Spot( bot_state_t *bs, qboolean force );
//setup the deathmatch AI
void BotSetupDeathmatchAI( void );
//shutdown the deathmatch AI
void BotShutdownDeathmatchAI( void );
//let the bot live within it's deathmatch AI net
void BotDeathmatchAI( bot_state_t *bs, float thinktime );
//free waypoints
void BotFreeWaypoints( bot_waypoint_t *wp );
//choose a weapon
void BotChooseWeapon( bot_state_t *bs );
// TAT 11/14/2002 -Bot cycles to next weapon in inventory, and will use it until told to cycle again
void BotCycleWeapon( bot_state_t *bs );
// Gordon: set pow status
void BotSetPOW( int entityNum, qboolean isPOW );
//setup movement stuff
void BotSetupForMovement( bot_state_t *bs );
//update the inventory
void BotUpdateInventory( bot_state_t *bs );
//update the inventory during battle
void BotUpdateBattleInventory( bot_state_t *bs, int enemy );
//use holdable items during battle
void BotBattleUseItems( bot_state_t *bs );
//return true if the bot is dead
qboolean BotIsDead( bot_state_t *bs );
//returns true if the bot is in observer mode
qboolean BotIsPOW( bot_state_t *bs );
//Gordon: returns true if the bot is a prisoner of war
qboolean BotIsObserver( bot_state_t *bs );
//returns true if the bot is in the intermission
qboolean BotIntermission( bot_state_t *bs );
//returns true if the bot is in lava
qboolean BotInLava( bot_state_t *bs );
//returns true if the bot is in slime
qboolean BotInSlime( bot_state_t *bs );
//returns true if the entity is dead
qboolean EntityIsDead( aas_entityinfo_t *entinfo );
//returns true if the entity is in limbo
qboolean EntityInLimbo( aas_entityinfo_t *entinfo );
//returns true if the entity is invisible
qboolean EntityIsInvisible( aas_entityinfo_t *entinfo );
//returns true if the entity is shooting
qboolean EntityIsShooting( aas_entityinfo_t *entinfo );
//returns the name of the client
char *ClientName( int client, char *name, int size );
//returns an simplyfied client name
char *EasyClientName( int client, char *name, int size );
//returns the skin used by the client
char *ClientSkin( int client, char *skin, int size );
//returns the aggression of the bot in the range [0, 100]
float BotAggression( bot_state_t *bs );
//returns true if the bot wants to retreat
int BotWantsToRetreat( bot_state_t *bs );
//returns true if the bot wants to chase
int BotWantsToChase( bot_state_t *bs );
//returns true if the bot wants to help
int BotWantsToHelp( bot_state_t *bs );
//returns true if the bot can and wants to rocketjump
int BotCanAndWantsToRocketJump( bot_state_t *bs );
//returns true if the bot wants to and goes camping
int BotWantsToCamp( bot_state_t *bs );
//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
int BotSameTeam( bot_state_t *bs, int entnum );
//returns true if teamplay is on
int TeamPlayIsOn( void );
// Set up our danger spots
void BotFindEnemies
(
bot_state_t *bs,
int *dangerSpots,
int *dangerSpotCount
);
// Returns true if we can do the battle fight.
// Returns false if enemy is too far or not visible
qboolean EnemyIsCloseEnoughToFight( bot_state_t *bs );
// TAT 11/21/2002
// Find an enemy and try to attack it
void BotFindAndAttackEnemy( bot_state_t *bs );
// Update the viewangle
void BotUpdateViewAngles( bot_state_t *bs, bot_goal_t *goal, bot_moveresult_t moveresult );
//returns true and sets the .enemy field when an enemy is found
int BotFindEnemyMP( bot_state_t *bs, int curenemy, qboolean ignoreViewRestrictions );
//returns true if the entity is within our view restrictions
qboolean BotEntityWithinView( bot_state_t *bs, int viewEnt );
float BotWeaponRange( bot_state_t *bs, int weaponnum );
qboolean BotScopedWeapon( int weapon );
//returns a roam goal
void BotRoamGoal( bot_state_t *bs, vec3_t goal );
//returns entity visibility in the range [0, 1]
float BotEntityVisible( int viewer, vec3_t eye, vec3_t viewangles, float fov, int ent, vec3_t entorigin );
//the bot will aim at the current enemy
void BotAimAtEnemy( bot_state_t *bs );
//the bot will aim at the current enemy
void BotAimAtEnemySP( bot_state_t *bs );
//check if the bot should attack
qboolean BotCheckAttack( bot_state_t *bs );
//AI when the bot is blocked
void BotAIBlocked( bot_state_t *bs, bot_moveresult_t *moveresult, int activate );
//create a new waypoint
bot_waypoint_t *BotCreateWayPoint( char *name, vec3_t origin, int areanum );
//find a waypoint with the given name
bot_waypoint_t *BotFindWayPoint( bot_waypoint_t *waypoints, char *name );
//strstr but case insensitive
char *stristr( char *str, char *charset );
//
int BotPointAreaNum( int entnum, vec3_t origin );
//
void BotMapScripts( bot_state_t *bs );
//
qboolean BotMoveWhileFiring( int weapon );
qboolean ChangeBotAlertState( bot_state_t *bs, aistateEnum_t newAlertState, qboolean force );
//ctf flags
#define CTF_FLAG_NONE 0
#define CTF_FLAG_RED 1
#define CTF_FLAG_BLUE 2
//CTF skins
#define CTF_SKIN_REDTEAM "red"
#define CTF_SKIN_BLUETEAM "blue"
//CTF teams
#define CTF_TEAM_NONE 0
#define CTF_TEAM_AXIS 1
#define CTF_TEAM_ALLIES 2
extern int gametype; //game type
// Rafael gameskill
extern int gameskill;
// done
extern vmCvar_t bot_grapple;
extern vmCvar_t bot_rocketjump;
extern vmCvar_t bot_fastchat;
extern vmCvar_t bot_nochat;
extern vmCvar_t bot_testrchat;
extern bot_goal_t ctf_redflag;
extern bot_goal_t ctf_blueflag;

474
src/botai/ai_func_decs.h Normal file
View File

@@ -0,0 +1,474 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
extern int BotObjectiveFunc ( bot_state_t * bs ) ;
extern int BotBehaviourFunc ( bot_state_t * bs ) ;
extern int BotEngagementFunc ( bot_state_t * bs ) ;
extern void BotSetLeaderTagEnt ( bot_state_t * bs ) ;
extern int EntGetNumBotFollowers ( int entNum ) ;
extern int BotGetLeader ( bot_state_t * bs , qboolean onlyRequested ) ;
extern qboolean G_RequestedFollow ( bot_state_t * bs , int client ) ;
extern void BotSpawnSpecialEntities ( void ) ;
extern void BotVoiceChatAfterTeamIdleTime ( int client , const char * id , int mode , int delay , qboolean voiceonly , int idleTime , qboolean forceIfDead ) ;
extern void AI_Team_Init_All_Teams ( ) ;
extern void AI_Team_Init ( AI_Team_t * thisOne ) ;
extern void BotVoiceChatAfterIdleTime ( int client , const char * id , int mode , int delay , qboolean voiceonly , int idleTime , qboolean forceIfDead ) ;
extern void BotSendVoiceChat ( bot_state_t * bs , const char * id , int mode , int delay , qboolean voiceonly , qboolean forceIfDead ) ;
extern void BotDelayedVoiceChat ( gentity_t * ent ) ;
extern void BotCheckVoiceChatResponse ( bot_state_t * bs ) ;
extern void BotRecordVoiceChat ( int client , int destclient , const char * id , int mode , qboolean noResponse ) ;
extern qboolean BotClass_LtCheckGiveAmmo ( bot_state_t * bs , int maxTravelTime , bot_goal_t * goal ) ;
extern qboolean G_RequestedAmmo ( bot_state_t * bs , int client , qboolean clear ) ;
extern qboolean BotClass_MedicCheckGiveHealth ( bot_state_t * bs , int maxTravelTime , bot_goal_t * goal ) ;
extern qboolean G_RequestedHealth ( bot_state_t * bs , int client , qboolean clearRequest ) ;
extern qboolean BotClass_MedicCheckRevives ( bot_state_t * bs , int maxtravel , bot_goal_t * goal , qboolean lookForBots ) ;
extern qboolean BotClass_CovertOpsCheckDisguises ( bot_state_t * bs , int maxTravel , bot_goal_t * goal ) ;
extern void BotTeamOrders ( bot_state_t * bs ) ;
extern void BotCTFOrders_BothFlagsAtBase ( bot_state_t * bs ) ;
extern void BotCTFOrders_EnemyFlagNotAtBase ( bot_state_t * bs ) ;
extern void BotCTFOrders_FlagNotAtBase ( bot_state_t * bs ) ;
extern void BotCTFOrders_BothFlagsNotAtBase ( bot_state_t * bs ) ;
extern int BotSuggestWeapon ( bot_state_t * bs , team_t team ) ;
extern int BotSuggestClass ( bot_state_t * bs , team_t team ) ;
extern qboolean BotCheckNeedEngineer ( bot_state_t * bs , team_t team ) ;
extern int BotNumTeamClasses ( team_t team , int mpClass , int ignore ) ;
extern int BotNumTeamMembers ( int team ) ;
extern int BotGetConstructibles ( team_t team , int * list , int listSize , qboolean ignoreBuilt ) ;
extern int BotGetTargetDynamite ( int * list , int listSize , gentity_t * target ) ;
extern int GetTargetExplosives ( team_t team , qboolean ignoreDynamite ) ;
extern int BotGetTargetExplosives ( team_t team , int * list , int listSize , qboolean ignoreDynamite ) ;
extern int BotGetTargetsForSatchelCharge ( team_t team , int * list , int listSize , qboolean ignoreSatchelCharge ) ;
extern gentity_t * G_FindSatchelChargeTargetForTeam ( gentity_t * trav , team_t team ) ;
extern gentity_t * G_FindDynamiteTargetForTeam ( gentity_t * trav , team_t team ) ;
extern gentity_t * G_IsConstructible ( team_t team , gentity_t * toi ) ;
extern gentity_t * G_ConstructionForTeam ( gentity_t * toi , team_t team ) ;
extern qboolean G_ConstructionIsDestroyable ( gentity_t * ent ) ;
extern qboolean G_ConstructionIsPartlyBuilt ( gentity_t * ent ) ;
extern qboolean G_ConstructionIsFullyBuilt ( gentity_t * ent ) ;
extern qboolean G_ConstructionBegun ( gentity_t * ent ) ;
extern gentity_t * G_FindSatchels ( gentity_t * start ) ;
extern gentity_t * G_FindLandmine ( gentity_t * start ) ;
extern gentity_t * G_FindSmokeBomb ( gentity_t * start ) ;
extern gentity_t * G_FindDynamite ( gentity_t * start ) ;
extern gentity_t * G_FindMissile ( gentity_t * start , weapon_t weap ) ;
extern int BotFindSparseDefendArea ( bot_state_t * bs , bot_goal_t * goal , qboolean force ) ;
extern qboolean BotFindDroppedFlag ( gentity_t * * returnEnt ) ;
extern void BotSayTeamOrder ( bot_state_t * bs , int toclient ) ;
extern int BotSortTeamMatesByBaseTravelTime ( bot_state_t * bs , int * teammates , int maxteammates ) ;
extern int BotClientTravelTimeToGoal ( int client , bot_goal_t * goal ) ;
extern int BotFlagAtBase ( int team , gentity_t * * returnEnt ) ;
extern int BotGetTeamFlagCarrier ( bot_state_t * bs ) ;
extern gentity_t * BotGetEnemyFlagCarrier ( bot_state_t * bs ) ;
extern float * BotSortPlayersByTraveltime ( int areanum , int * list , int numList ) ;
extern float * BotSortPlayersByDistance ( vec3_t target , int * list , int numList ) ;
extern int BotNumTeamMatesWithTargetAndCloser ( bot_state_t * bs , int targetEntity , int targetArea , int * list , int maxList , int playerType ) ;
extern int BotNumTeamMatesWithTargetByClass ( bot_state_t * bs , int targetEntity , int * list , int maxList , int playerType ) ;
extern int BotNumTeamMatesWithTarget ( bot_state_t * bs , int targetEntity , int * list , int maxList ) ;
extern int BotNumTeamMates ( bot_state_t * bs , int * list , int maxList ) ;
extern int BotValidTeamLeader ( bot_state_t * bs ) ;
extern qboolean Bot_ScriptAction_SetCivilian ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetAmmoAmount ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetScriptAutonomy ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_FireAtTarget ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_Announce ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetActiveWeapon ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetSpeedCoefficient ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetCloseHearingRange ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetFarSeeingRange ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetVisionRange ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetFireCycleTime ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetFireRate ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_BotDebugging ( gentity_t * ent , char * params ) ;
extern qboolean Bot_ScriptAction_PrintGlobalAccum ( gentity_t * ent , char * params ) ;
extern qboolean Bot_ScriptAction_PrintAccum ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetProne ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetCrouch ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetHearingRange ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetFieldOfView ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_ResetScript ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_NoTarget ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_MovementAutonomy ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetMovementAutonomy ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_Cvar ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_FollowLeader ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_GlobalAccum ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetClass ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetWeapon ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_PlaySoundAtPlayer ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_MountMG42 ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetAttribute ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_AbortIfWarmup ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_Logging ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_Trigger ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_MoveToMarker ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_Wait ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_Accum ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SpawnBot ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_SetAccumToPlayerCount ( bot_state_t * bs , char * params ) ;
extern qboolean Bot_ScriptAction_Print ( bot_state_t * bs , char * params ) ;
extern void Bot_ScriptError ( bot_state_t * bs , char * fmt , ... ) ;
extern qboolean Bot_ScriptAction_SetSpeed ( bot_state_t * bs , char * params ) ;
extern void Bot_ScriptThink ( void ) ;
extern void Bot_ScriptLog_Entry ( bot_state_t * bs , qboolean showDetails , char * preText , char * fmt , ... ) ;
extern int Bot_Script_GetCurrentLine ( bot_state_t * bs ) ;
extern qboolean Bot_ScriptRun ( bot_state_t * bs , qboolean force ) ;
extern void Bot_TeamScriptEvent ( int team , char * eventStr , char * params ) ;
extern void Bot_ForceScriptEvent ( int entityNum , char * eventStr , char * params ) ;
extern void Bot_ScriptEvent ( int entityNum , char * eventStr , char * params ) ;
extern void Bot_ScriptChange ( bot_state_t * bs , int newScriptNum ) ;
extern char * Bot_LineText ( char * text ) ;
extern qboolean Bot_ScriptInitBot ( int entnum ) ;
extern void Bot_ScriptParse ( bot_script_data_t * bsd , char * * text ) ;
extern void Bot_ScriptParseAllCharacters ( ) ;
extern void Bot_ScriptLoad ( void ) ;
extern bot_script_stack_action_t * Bot_ActionForString ( char * string ) ;
extern int Bot_EventForString ( char * string ) ;
extern qboolean Bot_EventMatch_IntInRange ( bot_script_event_t * event , char * eventParm ) ;
extern qboolean Bot_EventMatch_StringEqual ( bot_script_event_t * event , char * eventParm ) ;
extern int Bot_FindSriptGlobalData ( bot_script_data_t * data ) ;
extern void BotDebugViewClient ( int client ) ;
extern void BotInitMovementAutonomyPos ( gentity_t * bot ) ;
extern void BotSetIdealViewAngles ( int clientNum , vec3_t angle ) ;
extern void GetBotAmmo ( int clientNum , int * weapon , int * ammo , int * ammoclip ) ;
extern void GetBotAutonomies ( int clientNum , int * weapAutonomy , int * moveAutonomy ) ;
extern void BotDebug ( int clientNum ) ;
extern void BotRecordAttack ( int src , int dest ) ;
extern void BotRecordTeamDeath ( int client ) ;
extern void G_SetAASBlockingEntity ( gentity_t * ent , int blocking ) ;
extern qboolean BotCoop ( ) ;
extern qboolean BotSinglePlayer ( ) ;
extern gentity_t * BotFindEntityForName ( char * name ) ;
extern gentity_t * BotFindNextStaticEntity ( gentity_t * start , botStaticEntityEnum_t entityEnum ) ;
extern void BotBuildStaticEntityCache ( void ) ;
extern gentity_t * BotGetEntity ( int entityNum ) ;
extern bot_state_t * FindBotByName ( char * botName ) ;
extern gentity_t * BotFindEntity ( gentity_t * from , int fieldofs , char * match ) ;
extern int BotAIShutdown ( int restart ) ;
extern int BotAISetup ( int restart ) ;
extern int BotInitLibrary ( void ) ;
extern int BotAIStartFrame ( int time ) ;
extern int BotAIThinkFrame ( int time ) ;
extern void BotPreProcessAI ( ) ;
extern int BotAILoadMap ( int restart ) ;
extern void BotResetState ( bot_state_t * bs ) ;
extern int BotAIShutdownClient ( int client ) ;
extern int BotAISetupClient ( int client , struct bot_settings_s * settings ) ;
extern void BotSetUpCharacter ( bot_state_t * bs ) ;
extern void BotSetCharacterAttributes ( bot_state_t * bs , BotDefaultAttributes_t * defaults ) ;
extern void ParseBotDefaultAttributes ( char * fileName ) ;
extern void BotGetInitialAttributes ( bot_state_t * bs ) ;
extern void BotScheduleBotThink ( void ) ;
extern int BotAI ( int client , float thinktime ) ;
extern int BotTravelFlagsForClient ( int client ) ;
extern void BotAIRegularUpdate ( void ) ;
extern void BotUpdateInput ( bot_state_t * bs , int time ) ;
extern void BotInputToUserCommand ( bot_state_t * bs , bot_input_t * bi , usercmd_t * ucmd , int delta_angles [ 3 ] , int time ) ;
extern void BotSpeedBonus ( int clientNum ) ;
extern void BotChangeViewAngles ( bot_state_t * bs , float thinktime ) ;
extern float BotChangeViewAngle ( float angle , float ideal_angle , float speed ) ;
extern float AngleDifference ( float ang1 , float ang2 ) ;
extern void BotAI_SetNumBots ( int numbots ) ;
extern int BotAI_GetNumBots ( void ) ;
extern void BotEntityInfo ( int entnum , aas_entityinfo_t * info ) ;
extern void BotInterbreeding ( void ) ;
extern void QDECL BotAI_BotInitialChat ( bot_state_t * bs , char * type , ... ) ;
extern int BotAI_GetSnapshotEntity ( int clientNum , int sequence , entityState_t * state ) ;
extern int BotAI_GetEntityState ( int entityNum , entityState_t * state ) ;
extern int BotAI_GetClientState ( int clientNum , playerState_t * state ) ;
extern void BotAI_Trace ( bsp_trace_t * bsptrace , vec3_t start , vec3_t mins , vec3_t maxs , vec3_t end , int passent , int contentmask ) ;
extern void QDECL BotAI_Print ( int type , char * fmt , ... ) ;
extern qboolean BotEntityWithinView ( bot_state_t * bs , int viewEnt ) ;
extern void BotPickupWeapon ( int client , int weaponnum , qboolean alreadyHave ) ;
extern void BotCountLandMines ( void ) ;
extern gentity_t * BotGetVisibleDamagableScriptMover ( bot_state_t * bs ) ;
extern int BotBestTargetWeapon ( bot_state_t * bs , int targetNum ) ;
extern void BotSetPOW ( int entityNum , qboolean isPOW ) ;
extern void BotUpdateViewAngles ( bot_state_t * bs , bot_goal_t * goal , bot_moveresult_t moveresult ) ;
extern void BotFindAndAttackEnemy ( bot_state_t * bs ) ;
extern qboolean EnemyIsCloseEnoughToFight ( bot_state_t * bs ) ;
extern float BotHealthScale ( int entnum ) ;
extern int BotCanSnipe ( bot_state_t * bs , qboolean checkAmmo ) ;
extern qboolean BotIsConstructible ( team_t team , int toiNum ) ;
extern qboolean BotGetReachableEntityArea ( bot_state_t * bs , int entityNum , bot_goal_t * goal ) ;
extern qboolean BotEntityTargetClassnameMatch ( int entityNum , const char * classname ) ;
extern qboolean BotDirectMoveToGoal ( bot_state_t * bs , bot_goal_t * goal , bot_moveresult_t * moveresult ) ;
extern qboolean BotBattleNewNode ( bot_state_t * bs ) ;
extern int BotTravelTimeToEntity ( bot_state_t * bs , int entnum ) ;
extern int BotReduceListByTravelTime ( int * list , int numList , vec3_t destpos , int destarea , int traveltime ) ;
extern int BotGetArea ( int entnum ) ;
extern float * BotGetOrigin ( int entnum ) ;
extern float * BotGetEye ( int entnum ) ;
extern qboolean BotSeekCover ( bot_state_t * bs ) ;
extern int BotLastHurt ( bot_state_t * bs ) ;
extern int BotLastAttacked ( bot_state_t * bs ) ;
extern qboolean BotEnemyCarryingFlag ( int entnum ) ;
extern void BotShareLastAttacked ( bot_state_t * bs ) ;
extern void BotEnemyFire ( bot_state_t * bs ) ;
extern void BotCheckVoiceChats ( bot_state_t * bs ) ;
extern void BotDefaultNode ( bot_state_t * bs ) ;
extern qboolean BotFindSpecialGoals ( bot_state_t * bs ) ;
extern qboolean BotCheckEmergencyTargets ( bot_state_t * bs ) ;
extern int BotScriptAutonomyForString ( char * string ) ;
extern char * BotStringForWeaponAutonomy ( int value ) ;
extern int BotWeaponAutonomyForString ( char * string ) ;
extern char * BotStringForMovementAutonomy ( int value ) ;
extern int BotMovementAutonomyForString ( char * string ) ;
extern void BotCalculateMg42Spots ( void ) ;
extern void BotDropFlag ( bot_state_t * bs ) ;
extern void BotClearGoal ( bot_goal_t * goal ) ;
extern int BotGetRandomVisibleSniperSpot ( bot_state_t * bs ) ;
extern int BotGetNumVisibleSniperSpots ( bot_state_t * bs ) ;
extern int BotBestMG42Spot ( bot_state_t * bs , qboolean force ) ;
extern int BotBestLandmineSpotingSpot ( bot_state_t * bs ) ;
extern int BotBestSniperSpot ( bot_state_t * bs ) ;
extern void BotGetAimAccuracySkill ( bot_state_t * bs , float * outAimAccuracy , float * outAimSkill ) ;
extern void BotRecordDeath ( int client , int enemy ) ;
extern void BotRecordPain ( int client , int enemy , int mod ) ;
extern void BotRecordKill ( int client , int enemy ) ;
extern void BotRecordTeamChange ( int client ) ;
extern void BotMoveToIntermission ( int client ) ;
extern void BotSetBlockEnt ( int client , int blocker ) ;
extern void BotShutdownDeathmatchAI ( void ) ;
extern void BotSetupDeathmatchAI ( void ) ;
extern void BotDeathmatchAI ( bot_state_t * bs , float thinktime ) ;
extern void BotPowThink ( bot_state_t * bs ) ;
extern void BotDeathmatchAIFirstCalled ( bot_state_t * bs ) ;
extern void BotDumpNodeSwitches ( bot_state_t * bs ) ;
extern void BotResetNodeSwitches ( void ) ;
extern void BotUpdateReconInfo ( bot_state_t * bs ) ;
extern void BotCheckAlert ( bot_state_t * bs ) ;
extern void BotCheckAir ( bot_state_t * bs ) ;
extern void BotCheckSnapshot ( bot_state_t * bs ) ;
extern void BotCheckEvents ( bot_state_t * bs , entityState_t * state ) ;
extern void BotAIBlocked ( bot_state_t * bs , bot_moveresult_t * moveresult , int activate ) ;
extern void BotModelMinsMaxs ( int modelindex , vec3_t mins , vec3_t maxs ) ;
extern void BotSetMovedir ( vec3_t angles , vec3_t movedir ) ;
extern int BotEntityToActivate ( int entitynum ) ;
extern void BotMapScripts ( bot_state_t * bs ) ;
extern qboolean BotCheckAttack ( bot_state_t * bs ) ;
extern qboolean BotScopedWeapon ( int weapon ) ;
extern qboolean BotThrottleWeapon ( int weapon ) ;
extern qboolean BotMoveWhileFiring ( int weapon ) ;
extern void BotAimAtEnemySP ( bot_state_t * bs ) ;
extern void BotAimAtEnemy ( bot_state_t * bs ) ;
extern float swayrand ( float x , float y ) ;
extern float BotGetReactionTime ( bot_state_t * bs ) ;
extern int BotFindEnemyMP ( bot_state_t * bs , int curenemy , qboolean ignoreViewRestrictions ) ;
extern void BotSortClientsByDistance ( vec3_t srcpos , int * sorted , qboolean hasPanzer ) ;
extern qboolean BotHasWeaponWithRange ( bot_state_t * bs , float dist ) ;
extern float BotWeaponRange ( bot_state_t * bs , int weaponnum ) ;
extern void BotFindEnemies ( bot_state_t * bs , int * dangerSpots , int * dangerSpotCount ) ;
extern qboolean BotIsValidTarget ( bot_state_t * bs , int target , int curenemy ) ;
extern float BotGetEntitySurfaceSoundCoefficient ( int clientNum ) ;
extern void BotUpdateAlertStateSquadSensingInfo ( bot_state_t * bs , qboolean canSeeTarget , qboolean heardFootSteps , qboolean heardShooting ) ;
extern qboolean ChangeBotAlertState ( bot_state_t * bs , aistateEnum_t newAlertState , qboolean force ) ;
extern float BotNoLeaderPenalty ( bot_state_t * bs ) ;
extern qboolean BotDangerousGoal ( bot_state_t * bs , bot_goal_t * goal ) ;
extern void BotIgnoreGoal ( bot_state_t * bs , bot_goal_t * goal , int duration ) ;
extern qboolean BotCheckMovementAutonomy ( bot_state_t * bs , bot_goal_t * goal ) ;
extern void sAdjustPointTowardsPlayer ( vec3_t playerLoc , vec3_t endPos , qboolean shouldLoop , vec3_t outPos ) ;
extern float sAngleBetweenVectors ( vec3_t a , vec3_t b ) ;
extern void botindicator_think ( gentity_t * ent ) ;
extern qboolean BotGoalForEntity ( bot_state_t * bs , int entityNum , bot_goal_t * goal , int urgency ) ;
extern qboolean BotGoalWithinMovementAutonomy ( bot_state_t * bs , bot_goal_t * goal , int urgency ) ;
extern qboolean BotPointWithinRawMovementAutonomy ( bot_state_t * bs , vec3_t point ) ;
extern qboolean BotPointWithinMovementAutonomy ( bot_state_t * bs , bot_goal_t * goal , vec3_t point ) ;
extern qboolean BotWithinLeaderFollowDist ( bot_state_t * bs ) ;
extern float BotGetFollowAutonomyDist ( bot_state_t * bs ) ;
extern float BotGetMovementAutonomyRange ( bot_state_t * bs , bot_goal_t * goal ) ;
extern float BotGetRawMovementAutonomyRange ( bot_state_t * bs ) ;
extern qboolean BotGetMovementAutonomyPos ( bot_state_t * bs , vec3_t pos ) ;
extern int BotGetMovementAutonomyLevel ( bot_state_t * bs ) ;
extern qboolean BotCheckAttackAtPos ( int entnum , int enemy , vec3_t pos , qboolean ducking , qboolean allowHitWorld ) ;
extern qboolean BotVisibleFromPos ( vec3_t srcorigin , int srcnum , vec3_t destorigin , int destent , qboolean dummy ) ;
extern float BotEntityVisible ( int viewer , vec3_t eye , vec3_t viewangles , float fov , int ent , vec3_t entorigin ) ;
extern qboolean BotEntInvisibleBySmokeBomb ( vec3_t start , vec3_t end ) ;
extern qboolean InFieldOfVision ( vec3_t viewangles , float fov , vec3_t angles ) ;
extern int BotSameTeam ( bot_state_t * bs , int entnum ) ;
extern bot_moveresult_t BotAttackMove ( bot_state_t * bs , int tfl ) ;
extern void BotRoamGoal ( bot_state_t * bs , vec3_t goal ) ;
extern void BotGoForPowerups ( bot_state_t * bs ) ;
extern void BotDontAvoid ( bot_state_t * bs , char * itemname ) ;
extern void BotGoCamp ( bot_state_t * bs , bot_goal_t * goal ) ;
extern int BotCanAndWantsToRocketJump ( bot_state_t * bs ) ;
extern int BotWantsToHelp ( bot_state_t * bs ) ;
extern int BotWantsToChase ( bot_state_t * bs ) ;
extern int BotWantsToRetreat ( bot_state_t * bs ) ;
extern float BotAggression ( bot_state_t * bs ) ;
extern int TeamPlayIsOn ( void ) ;
extern void BotInitWaypoints ( void ) ;
extern void BotFreeWaypoints ( bot_waypoint_t * wp ) ;
extern bot_waypoint_t * BotFindWayPoint ( bot_waypoint_t * waypoints , char * name ) ;
extern bot_waypoint_t * BotCreateWayPoint ( char * name , vec3_t origin , int areanum ) ;
extern qboolean EntityHasQuad ( aas_entityinfo_t * entinfo ) ;
extern qboolean EntityIsChatting ( aas_entityinfo_t * entinfo ) ;
extern qboolean EntityIsShooting ( aas_entityinfo_t * entinfo ) ;
extern qboolean EntityIsInvisible ( aas_entityinfo_t * entinfo ) ;
extern qboolean EntityInLimbo ( aas_entityinfo_t * entinfo ) ;
extern qboolean EntityIsDead ( aas_entityinfo_t * entinfo ) ;
extern qboolean BotInSlime ( bot_state_t * bs ) ;
extern qboolean BotInLava ( bot_state_t * bs ) ;
extern qboolean BotIntermission ( bot_state_t * bs ) ;
extern qboolean BotIsObserver ( bot_state_t * bs ) ;
extern qboolean BotIsPOW ( bot_state_t * bs ) ;
extern qboolean BotIsDead ( bot_state_t * bs ) ;
extern void BotSetTeleportTime ( bot_state_t * bs ) ;
extern void BotBattleUseItems ( bot_state_t * bs ) ;
extern void BotUpdateBattleInventory ( bot_state_t * bs , int enemy ) ;
extern void BotUpdateInventory ( bot_state_t * bs ) ;
extern void BotSetupForMovement ( bot_state_t * bs ) ;
extern void BotCycleWeapon ( bot_state_t * bs ) ;
extern void BotChooseWeapon ( bot_state_t * bs ) ;
extern int BotBestFightWeapon ( bot_state_t * bs ) ;
extern float BotWeaponWantScale ( bot_state_t * bs , weapon_t weapon ) ;
extern int BotTeamMatesNearEnemy ( bot_state_t * bs ) ;
extern float BotWeaponClosestDist ( int weaponnum ) ;
extern qboolean BotWeaponOnlyUseIfInInRange ( int weaponnum ) ;
extern qboolean BotWeaponCharged ( bot_state_t * bs , int weapon ) ;
extern qboolean G_WeaponCharged ( playerState_t * ps , team_t team , int weapon , int * skill ) ;
extern qboolean BotGotEnoughAmmoForWeapon ( bot_state_t * bs , int weapon ) ;
extern char * EasyClientName ( int client , char * buf , int size ) ;
extern char * stristr ( char * str , char * charset ) ;
extern int ClientFromName ( char * name ) ;
extern char * ClientSkin ( int client , char * skin , int size ) ;
extern char * ClientName ( int client , char * name , int size ) ;
extern qboolean BotFindNearbyGoal ( bot_state_t * bs ) ;
extern qboolean BotFindNearbyTriggerGoal ( bot_state_t * bs ) ;
extern int BotReachableBBoxAreaNum ( bot_state_t * bs , vec3_t absmin , vec3_t absmax ) ;
extern int BotPointAreaNum ( int entnum , vec3_t origin ) ;
extern int BotFirstLadderArea ( int entnum , int * areas , int numareas ) ;
extern int BotFirstReachabilityArea ( int entnum , vec3_t origin , int * areas , int numareas , qboolean distCheck ) ;
extern qboolean BotCarryingFlag ( int client ) ;
extern int AINode_MP_NavigateFromVoid ( bot_state_t * bs ) ;
extern void AIEnter_MP_NavigateFromVoid ( bot_state_t * bs ) ;
extern int AINode_MP_MoveToAutonomyRange ( bot_state_t * bs ) ;
extern void AIEnter_MP_MoveToAutonomyRange ( bot_state_t * bs ) ;
extern int AINode_MP_Script_MoveToMarker ( bot_state_t * bs ) ;
extern void AIEnter_MP_Script_MoveToMarker ( bot_state_t * bs ) ;
extern int AINode_MP_Battle_Retreat ( bot_state_t * bs ) ;
extern void AIEnter_MP_Battle_Retreat ( bot_state_t * bs ) ;
extern int AINode_MP_Battle_Chase ( bot_state_t * bs ) ;
extern void AIEnter_MP_Battle_Chase ( bot_state_t * bs ) ;
extern int AINode_MP_Battle_Fight ( bot_state_t * bs ) ;
extern void AIEnter_MP_Battle_Fight ( bot_state_t * bs ) ;
extern int AINode_MP_DisarmDynamite ( bot_state_t * bs ) ;
extern void AIEnter_MP_DisarmDynamite ( bot_state_t * bs ) ;
extern int AINode_MP_PlantMine ( bot_state_t * bs ) ;
extern void AIEnter_MP_PlantMine ( bot_state_t * bs ) ;
extern int AINode_MP_ConstructibleTarget ( bot_state_t * bs ) ;
extern void AIEnter_MP_ConstructibleTarget ( bot_state_t * bs ) ;
extern int AINode_MP_DynamiteTarget ( bot_state_t * bs ) ;
extern void AIEnter_MP_DynamiteTarget ( bot_state_t * bs ) ;
extern int AINode_MP_SatchelChargeTarget ( bot_state_t * bs ) ;
extern void AIEnter_MP_SatchelChargeTarget ( bot_state_t * bs ) ;
extern int AINode_MP_TouchTarget ( bot_state_t * bs ) ;
extern void AIEnter_MP_TouchTarget ( bot_state_t * bs ) ;
extern int AINode_MP_DefendTarget ( bot_state_t * bs ) ;
extern void AIEnter_MP_DefendTarget ( bot_state_t * bs ) ;
extern int AINode_MP_SniperSpot ( bot_state_t * bs ) ;
extern void AIEnter_MP_SniperSpot ( bot_state_t * bs ) ;
extern int AINode_MP_ScanForLandmines ( bot_state_t * bs ) ;
extern void AIEnter_MP_ScanForLandmines ( bot_state_t * bs ) ;
extern int AINode_MP_MG42Mount ( bot_state_t * bs ) ;
extern void AIEnter_MP_MG42Mount ( bot_state_t * bs ) ;
extern int AINode_MP_MG42Scan ( bot_state_t * bs ) ;
extern void AIEnter_MP_MG42Scan ( bot_state_t * bs ) ;
extern int AINode_MP_Battle_MobileMG42 ( bot_state_t * bs ) ;
extern void AIEnter_MP_Battle_MobileMG42 ( bot_state_t * bs ) ;
extern int AINode_MP_FixMG42 ( bot_state_t * bs ) ;
extern void AIEnter_MP_FixMG42 ( bot_state_t * bs ) ;
extern int AINode_MP_AttackTarget ( bot_state_t * bs ) ;
extern void AIEnter_MP_AttackTarget ( bot_state_t * bs ) ;
extern int AINode_MP_PanzerTarget ( bot_state_t * bs ) ;
extern void AIEnter_MP_PanzerTarget ( bot_state_t * bs ) ;
extern int AINode_MP_MedicRevive ( bot_state_t * bs ) ;
extern void AIEnter_MP_MedicRevive ( bot_state_t * bs ) ;
extern int AINode_MP_MedicGiveHealth ( bot_state_t * bs ) ;
extern void AIEnter_MP_MedicGiveHealth ( bot_state_t * bs ) ;
extern int AINode_MP_GiveAmmo ( bot_state_t * bs ) ;
extern void AIEnter_MP_GiveAmmo ( bot_state_t * bs ) ;
extern int AINode_MP_AvoidDanger ( bot_state_t * bs ) ;
extern void AIEnter_MP_AvoidDanger ( bot_state_t * bs ) ;
extern int AINode_MP_Seek_NBG ( bot_state_t * bs ) ;
extern void AIEnter_MP_Seek_NBG ( bot_state_t * bs ) ;
extern int AINode_MP_Seek_ActivateEntity ( bot_state_t * bs ) ;
extern void AIEnter_MP_Seek_ActivateEntity ( bot_state_t * bs ) ;
extern int AINode_MP_Respawn ( bot_state_t * bs ) ;
extern void AIEnter_MP_Respawn ( bot_state_t * bs ) ;
extern int AINode_MP_Stand ( bot_state_t * bs ) ;
extern void AIEnter_MP_Stand ( bot_state_t * bs ) ;
extern int AINode_MP_Observer ( bot_state_t * bs ) ;
extern void AIEnter_MP_Observer ( bot_state_t * bs ) ;
extern int AINode_MP_Intermission ( bot_state_t * bs ) ;
extern void AIEnter_MP_Intermission ( bot_state_t * bs ) ;
extern void BotMP_MoveToGoal ( bot_state_t * bs , bot_moveresult_t * result , int movestate , bot_goal_t * goal , int travelflags ) ;
extern qboolean BotMP_FindGoal ( bot_state_t * bs ) ;
extern qboolean BotMP_FindGoal_New ( bot_state_t * bs ) ;
extern qboolean BotMP_AlreadyDoing_FastOut ( bot_state_t * bs , botgoalFind_t * bg ) ;
extern void BotMP_FindGoal_PostProcessGoal ( bot_state_t * bs , botgoalFind_t * bg , bot_goal_t * goal ) ;
extern botMPpg_t BotMP_FindGoal_ProcessGoal ( bot_state_t * bs , botgoalFind_t * bg , bot_goal_t * target_goal ) ;
extern int BotMP_FindGoal_ClassForGoalType ( botgoalFindType_t type ) ;
extern int QDECL BotMP_FindGoals_Sort_CovertOps ( const void * a , const void * b ) ;
extern int QDECL BotMP_FindGoals_Sort_Engineer ( const void * a , const void * b ) ;
extern int QDECL BotMP_FindGoals_Sort_Standard ( const void * a , const void * b ) ;
extern int BotMP_FindGoal_BuildGoalList ( bot_state_t * bs , botgoalFind_t * pGoals , int maxGoals ) ;
extern qboolean BotMP_CheckEmergencyGoals ( bot_state_t * bs ) ;
extern qboolean BotMP_CheckClassActions ( bot_state_t * bs ) ;
extern int BotMatchMessage ( bot_state_t * bs , char * message ) ;
extern void BotMatch_Kill ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_LeadTheWay ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_WhereAreYou ( bot_state_t * bs , bot_match_t * match ) ;
extern float BotNearestVisibleItem ( bot_state_t * bs , char * itemname , bot_goal_t * goal ) ;
extern void BotMatch_WhatIsMyCommand ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_WhatAreYouDoing ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_WhoIsTeamLeader ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_StopTeamLeaderShip ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_StartTeamLeaderShip ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_Dismiss ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_FormationSpace ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_CheckPoint ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_WhichTeam ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_LeaveSubteam ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_JoinSubteam ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_ReturnFlag ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_RushBase ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_GetFlag ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_Patrol ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_Camp ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_GetItem ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_DefendKeyArea ( bot_state_t * bs , bot_match_t * match ) ;
extern void BotMatch_HelpAccompany ( bot_state_t * bs , bot_match_t * match ) ;
extern int BotGPSToPosition ( char * buf , vec3_t position ) ;
extern int BotAddressedToBot ( bot_state_t * bs , bot_match_t * match ) ;
extern int BotGetPatrolWaypoints ( bot_state_t * bs , bot_match_t * match ) ;
extern int NumPlayersOnSameTeam ( bot_state_t * bs ) ;
extern int FindEnemyByName ( bot_state_t * bs , char * name ) ;
extern int FindClientByName ( char * name ) ;
extern float BotGetTime ( bot_match_t * match ) ;
extern int BotGetMessageTeamGoal ( bot_state_t * bs , char * goalname , bot_goal_t * goal ) ;
extern int BotGetItemTeamGoal ( char * goalname , bot_goal_t * goal ) ;

475
src/botai/ai_funcs.h Normal file
View File

@@ -0,0 +1,475 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
{"BotObjectiveFunc", (byte *)BotObjectiveFunc},
{"BotBehaviourFunc", (byte *)BotBehaviourFunc},
{"BotEngagementFunc", (byte *)BotEngagementFunc},
{"BotSetLeaderTagEnt", (byte *)BotSetLeaderTagEnt},
{"EntGetNumBotFollowers", (byte *)EntGetNumBotFollowers},
{"BotGetLeader", (byte *)BotGetLeader},
{"G_RequestedFollow", (byte *)G_RequestedFollow},
{"BotSpawnSpecialEntities", (byte *)BotSpawnSpecialEntities},
{"BotVoiceChatAfterTeamIdleTime", (byte *)BotVoiceChatAfterTeamIdleTime},
{"AI_Team_Init_All_Teams", (byte *)AI_Team_Init_All_Teams},
{"AI_Team_Init", (byte *)AI_Team_Init},
{"BotVoiceChatAfterIdleTime", (byte *)BotVoiceChatAfterIdleTime},
{"BotSendVoiceChat", (byte *)BotSendVoiceChat},
{"BotDelayedVoiceChat", (byte *)BotDelayedVoiceChat},
{"BotCheckVoiceChatResponse", (byte *)BotCheckVoiceChatResponse},
{"BotRecordVoiceChat", (byte *)BotRecordVoiceChat},
{"BotClass_LtCheckGiveAmmo", (byte *)BotClass_LtCheckGiveAmmo},
{"G_RequestedAmmo", (byte *)G_RequestedAmmo},
{"BotClass_MedicCheckGiveHealth", (byte *)BotClass_MedicCheckGiveHealth},
{"G_RequestedHealth", (byte *)G_RequestedHealth},
{"BotClass_MedicCheckRevives", (byte *)BotClass_MedicCheckRevives},
{"BotClass_CovertOpsCheckDisguises", (byte *)BotClass_CovertOpsCheckDisguises},
{"BotTeamOrders", (byte *)BotTeamOrders},
{"BotCTFOrders_BothFlagsAtBase", (byte *)BotCTFOrders_BothFlagsAtBase},
{"BotCTFOrders_EnemyFlagNotAtBase", (byte *)BotCTFOrders_EnemyFlagNotAtBase},
{"BotCTFOrders_FlagNotAtBase", (byte *)BotCTFOrders_FlagNotAtBase},
{"BotCTFOrders_BothFlagsNotAtBase", (byte *)BotCTFOrders_BothFlagsNotAtBase},
{"BotSuggestWeapon", (byte *)BotSuggestWeapon},
{"BotSuggestClass", (byte *)BotSuggestClass},
{"BotCheckNeedEngineer", (byte *)BotCheckNeedEngineer},
{"BotNumTeamClasses", (byte *)BotNumTeamClasses},
{"BotNumTeamMembers", (byte *)BotNumTeamMembers},
{"BotGetConstructibles", (byte *)BotGetConstructibles},
{"BotGetTargetDynamite", (byte *)BotGetTargetDynamite},
{"GetTargetExplosives", (byte *)GetTargetExplosives},
{"BotGetTargetExplosives", (byte *)BotGetTargetExplosives},
{"BotGetTargetsForSatchelCharge", (byte *)BotGetTargetsForSatchelCharge},
{"G_FindSatchelChargeTargetForTeam", (byte *)G_FindSatchelChargeTargetForTeam},
{"G_FindDynamiteTargetForTeam", (byte *)G_FindDynamiteTargetForTeam},
{"G_IsConstructible", (byte *)G_IsConstructible},
{"G_ConstructionForTeam", (byte *)G_ConstructionForTeam},
{"G_ConstructionIsDestroyable", (byte *)G_ConstructionIsDestroyable},
{"G_ConstructionIsPartlyBuilt", (byte *)G_ConstructionIsPartlyBuilt},
{"G_ConstructionIsFullyBuilt", (byte *)G_ConstructionIsFullyBuilt},
{"G_ConstructionBegun", (byte *)G_ConstructionBegun},
{"G_FindSatchels", (byte *)G_FindSatchels},
{"G_FindLandmine", (byte *)G_FindLandmine},
{"G_FindSmokeBomb", (byte *)G_FindSmokeBomb},
{"G_FindDynamite", (byte *)G_FindDynamite},
{"G_FindMissile", (byte *)G_FindMissile},
{"BotFindSparseDefendArea", (byte *)BotFindSparseDefendArea},
{"BotFindDroppedFlag", (byte *)BotFindDroppedFlag},
{"BotSayTeamOrder", (byte *)BotSayTeamOrder},
{"BotSortTeamMatesByBaseTravelTime", (byte *)BotSortTeamMatesByBaseTravelTime},
{"BotClientTravelTimeToGoal", (byte *)BotClientTravelTimeToGoal},
{"BotFlagAtBase", (byte *)BotFlagAtBase},
{"BotGetTeamFlagCarrier", (byte *)BotGetTeamFlagCarrier},
{"BotGetEnemyFlagCarrier", (byte *)BotGetEnemyFlagCarrier},
{"BotSortPlayersByTraveltime", (byte *)BotSortPlayersByTraveltime},
{"BotSortPlayersByDistance", (byte *)BotSortPlayersByDistance},
{"BotNumTeamMatesWithTargetAndCloser", (byte *)BotNumTeamMatesWithTargetAndCloser},
{"BotNumTeamMatesWithTargetByClass", (byte *)BotNumTeamMatesWithTargetByClass},
{"BotNumTeamMatesWithTarget", (byte *)BotNumTeamMatesWithTarget},
{"BotNumTeamMates", (byte *)BotNumTeamMates},
{"BotValidTeamLeader", (byte *)BotValidTeamLeader},
{"Bot_ScriptAction_SetCivilian", (byte *)Bot_ScriptAction_SetCivilian},
{"Bot_ScriptAction_SetAmmoAmount", (byte *)Bot_ScriptAction_SetAmmoAmount},
{"Bot_ScriptAction_SetScriptAutonomy", (byte *)Bot_ScriptAction_SetScriptAutonomy},
{"Bot_ScriptAction_FireAtTarget", (byte *)Bot_ScriptAction_FireAtTarget},
{"Bot_ScriptAction_Announce", (byte *)Bot_ScriptAction_Announce},
{"Bot_ScriptAction_SetActiveWeapon", (byte *)Bot_ScriptAction_SetActiveWeapon},
{"Bot_ScriptAction_SetSpeedCoefficient", (byte *)Bot_ScriptAction_SetSpeedCoefficient},
{"Bot_ScriptAction_SetCloseHearingRange", (byte *)Bot_ScriptAction_SetCloseHearingRange},
{"Bot_ScriptAction_SetFarSeeingRange", (byte *)Bot_ScriptAction_SetFarSeeingRange},
{"Bot_ScriptAction_SetVisionRange", (byte *)Bot_ScriptAction_SetVisionRange},
{"Bot_ScriptAction_SetFireCycleTime", (byte *)Bot_ScriptAction_SetFireCycleTime},
{"Bot_ScriptAction_SetFireRate", (byte *)Bot_ScriptAction_SetFireRate},
{"Bot_ScriptAction_BotDebugging", (byte *)Bot_ScriptAction_BotDebugging},
{"Bot_ScriptAction_PrintGlobalAccum", (byte *)Bot_ScriptAction_PrintGlobalAccum},
{"Bot_ScriptAction_PrintAccum", (byte *)Bot_ScriptAction_PrintAccum},
{"Bot_ScriptAction_SetProne", (byte *)Bot_ScriptAction_SetProne},
{"Bot_ScriptAction_SetCrouch", (byte *)Bot_ScriptAction_SetCrouch},
{"Bot_ScriptAction_SetHearingRange", (byte *)Bot_ScriptAction_SetHearingRange},
{"Bot_ScriptAction_SetFieldOfView", (byte *)Bot_ScriptAction_SetFieldOfView},
{"Bot_ScriptAction_ResetScript", (byte *)Bot_ScriptAction_ResetScript},
{"Bot_ScriptAction_NoTarget", (byte *)Bot_ScriptAction_NoTarget},
{"Bot_ScriptAction_MovementAutonomy", (byte *)Bot_ScriptAction_MovementAutonomy},
{"Bot_ScriptAction_SetMovementAutonomy", (byte *)Bot_ScriptAction_SetMovementAutonomy},
{"Bot_ScriptAction_Cvar", (byte *)Bot_ScriptAction_Cvar},
{"Bot_ScriptAction_FollowLeader", (byte *)Bot_ScriptAction_FollowLeader},
{"Bot_ScriptAction_GlobalAccum", (byte *)Bot_ScriptAction_GlobalAccum},
{"Bot_ScriptAction_SetClass", (byte *)Bot_ScriptAction_SetClass},
{"Bot_ScriptAction_SetWeapon", (byte *)Bot_ScriptAction_SetWeapon},
{"Bot_ScriptAction_PlaySoundAtPlayer", (byte *)Bot_ScriptAction_PlaySoundAtPlayer},
{"Bot_ScriptAction_MountMG42", (byte *)Bot_ScriptAction_MountMG42},
{"Bot_ScriptAction_SetAttribute", (byte *)Bot_ScriptAction_SetAttribute},
{"Bot_ScriptAction_AbortIfWarmup", (byte *)Bot_ScriptAction_AbortIfWarmup},
{"Bot_ScriptAction_Logging", (byte *)Bot_ScriptAction_Logging},
{"Bot_ScriptAction_Trigger", (byte *)Bot_ScriptAction_Trigger},
{"Bot_ScriptAction_MoveToMarker", (byte *)Bot_ScriptAction_MoveToMarker},
{"Bot_ScriptAction_Wait", (byte *)Bot_ScriptAction_Wait},
{"Bot_ScriptAction_Accum", (byte *)Bot_ScriptAction_Accum},
{"Bot_ScriptAction_SpawnBot", (byte *)Bot_ScriptAction_SpawnBot},
{"Bot_ScriptAction_SetAccumToPlayerCount", (byte *)Bot_ScriptAction_SetAccumToPlayerCount},
{"Bot_ScriptAction_Print", (byte *)Bot_ScriptAction_Print},
{"Bot_ScriptError", (byte *)Bot_ScriptError},
{"Bot_ScriptAction_SetSpeed", (byte *)Bot_ScriptAction_SetSpeed},
{"Bot_ScriptThink", (byte *)Bot_ScriptThink},
{"Bot_ScriptLog_Entry", (byte *)Bot_ScriptLog_Entry},
{"Bot_Script_GetCurrentLine", (byte *)Bot_Script_GetCurrentLine},
{"Bot_ScriptRun", (byte *)Bot_ScriptRun},
{"Bot_TeamScriptEvent", (byte *)Bot_TeamScriptEvent},
{"Bot_ForceScriptEvent", (byte *)Bot_ForceScriptEvent},
{"Bot_ScriptEvent", (byte *)Bot_ScriptEvent},
{"Bot_ScriptChange", (byte *)Bot_ScriptChange},
{"Bot_LineText", (byte *)Bot_LineText},
{"Bot_ScriptInitBot", (byte *)Bot_ScriptInitBot},
{"Bot_ScriptParse", (byte *)Bot_ScriptParse},
{"Bot_ScriptParseAllCharacters", (byte *)Bot_ScriptParseAllCharacters},
{"Bot_ScriptLoad", (byte *)Bot_ScriptLoad},
{"Bot_ActionForString", (byte *)Bot_ActionForString},
{"Bot_EventForString", (byte *)Bot_EventForString},
{"Bot_EventMatch_IntInRange", (byte *)Bot_EventMatch_IntInRange},
{"Bot_EventMatch_StringEqual", (byte *)Bot_EventMatch_StringEqual},
{"Bot_FindSriptGlobalData", (byte *)Bot_FindSriptGlobalData},
{"BotDebugViewClient", (byte *)BotDebugViewClient},
{"BotInitMovementAutonomyPos", (byte *)BotInitMovementAutonomyPos},
{"BotSetIdealViewAngles", (byte *)BotSetIdealViewAngles},
{"GetBotAmmo", (byte *)GetBotAmmo},
{"GetBotAutonomies", (byte *)GetBotAutonomies},
{"BotDebug", (byte *)BotDebug},
{"BotRecordAttack", (byte *)BotRecordAttack},
{"BotRecordTeamDeath", (byte *)BotRecordTeamDeath},
{"G_SetAASBlockingEntity", (byte *)G_SetAASBlockingEntity},
{"BotCoop", (byte *)BotCoop},
{"BotSinglePlayer", (byte *)BotSinglePlayer},
{"BotFindEntityForName", (byte *)BotFindEntityForName},
{"BotFindNextStaticEntity", (byte *)BotFindNextStaticEntity},
{"BotBuildStaticEntityCache", (byte *)BotBuildStaticEntityCache},
{"BotGetEntity", (byte *)BotGetEntity},
{"FindBotByName", (byte *)FindBotByName},
{"BotFindEntity", (byte *)BotFindEntity},
{"BotAIShutdown", (byte *)BotAIShutdown},
{"BotAISetup", (byte *)BotAISetup},
{"BotInitLibrary", (byte *)BotInitLibrary},
{"BotAIStartFrame", (byte *)BotAIStartFrame},
{"BotAIThinkFrame", (byte *)BotAIThinkFrame},
{"BotPreProcessAI", (byte *)BotPreProcessAI},
{"BotAILoadMap", (byte *)BotAILoadMap},
{"BotResetState", (byte *)BotResetState},
{"BotAIShutdownClient", (byte *)BotAIShutdownClient},
{"BotAISetupClient", (byte *)BotAISetupClient},
{"BotSetUpCharacter", (byte *)BotSetUpCharacter},
{"BotSetCharacterAttributes", (byte *)BotSetCharacterAttributes},
{"ParseBotDefaultAttributes", (byte *)ParseBotDefaultAttributes},
{"BotGetInitialAttributes", (byte *)BotGetInitialAttributes},
{"BotScheduleBotThink", (byte *)BotScheduleBotThink},
{"BotAI", (byte *)BotAI},
{"BotTravelFlagsForClient", (byte *)BotTravelFlagsForClient},
{"BotAIRegularUpdate", (byte *)BotAIRegularUpdate},
{"BotUpdateInput", (byte *)BotUpdateInput},
{"BotInputToUserCommand", (byte *)BotInputToUserCommand},
{"BotSpeedBonus", (byte *)BotSpeedBonus},
{"BotChangeViewAngles", (byte *)BotChangeViewAngles},
{"BotChangeViewAngle", (byte *)BotChangeViewAngle},
{"AngleDifference", (byte *)AngleDifference},
{"BotAI_SetNumBots", (byte *)BotAI_SetNumBots},
{"BotAI_GetNumBots", (byte *)BotAI_GetNumBots},
{"BotEntityInfo", (byte *)BotEntityInfo},
{"BotInterbreeding", (byte *)BotInterbreeding},
{"BotAI_BotInitialChat", (byte *)BotAI_BotInitialChat},
{"BotAI_GetSnapshotEntity", (byte *)BotAI_GetSnapshotEntity},
{"BotAI_GetEntityState", (byte *)BotAI_GetEntityState},
{"BotAI_GetClientState", (byte *)BotAI_GetClientState},
{"BotAI_Trace", (byte *)BotAI_Trace},
{"BotAI_Print", (byte *)BotAI_Print},
{"BotEntityWithinView", (byte *)BotEntityWithinView},
{"BotPickupWeapon", (byte *)BotPickupWeapon},
{"BotCountLandMines", (byte *)BotCountLandMines},
{"BotGetVisibleDamagableScriptMover", (byte *)BotGetVisibleDamagableScriptMover},
{"BotBestTargetWeapon", (byte *)BotBestTargetWeapon},
{"BotSetPOW", (byte *)BotSetPOW},
{"BotUpdateViewAngles", (byte *)BotUpdateViewAngles},
{"BotFindAndAttackEnemy", (byte *)BotFindAndAttackEnemy},
{"EnemyIsCloseEnoughToFight", (byte *)EnemyIsCloseEnoughToFight},
{"BotHealthScale", (byte *)BotHealthScale},
{"BotCanSnipe", (byte *)BotCanSnipe},
{"BotIsConstructible", (byte *)BotIsConstructible},
{"BotGetReachableEntityArea", (byte *)BotGetReachableEntityArea},
{"BotEntityTargetClassnameMatch", (byte *)BotEntityTargetClassnameMatch},
{"BotDirectMoveToGoal", (byte *)BotDirectMoveToGoal},
{"BotBattleNewNode", (byte *)BotBattleNewNode},
{"BotTravelTimeToEntity", (byte *)BotTravelTimeToEntity},
{"BotReduceListByTravelTime", (byte *)BotReduceListByTravelTime},
{"BotGetArea", (byte *)BotGetArea},
{"BotGetOrigin", (byte *)BotGetOrigin},
{"BotGetEye", (byte *)BotGetEye},
{"BotSeekCover", (byte *)BotSeekCover},
{"BotLastHurt", (byte *)BotLastHurt},
{"BotLastAttacked", (byte *)BotLastAttacked},
{"BotEnemyCarryingFlag", (byte *)BotEnemyCarryingFlag},
{"BotShareLastAttacked", (byte *)BotShareLastAttacked},
{"BotEnemyFire", (byte *)BotEnemyFire},
{"BotCheckVoiceChats", (byte *)BotCheckVoiceChats},
{"BotDefaultNode", (byte *)BotDefaultNode},
{"BotFindSpecialGoals", (byte *)BotFindSpecialGoals},
{"BotCheckEmergencyTargets", (byte *)BotCheckEmergencyTargets},
{"BotScriptAutonomyForString", (byte *)BotScriptAutonomyForString},
{"BotStringForWeaponAutonomy", (byte *)BotStringForWeaponAutonomy},
{"BotWeaponAutonomyForString", (byte *)BotWeaponAutonomyForString},
{"BotStringForMovementAutonomy", (byte *)BotStringForMovementAutonomy},
{"BotMovementAutonomyForString", (byte *)BotMovementAutonomyForString},
{"BotCalculateMg42Spots", (byte *)BotCalculateMg42Spots},
{"BotDropFlag", (byte *)BotDropFlag},
{"BotClearGoal", (byte *)BotClearGoal},
{"BotGetRandomVisibleSniperSpot", (byte *)BotGetRandomVisibleSniperSpot},
{"BotGetNumVisibleSniperSpots", (byte *)BotGetNumVisibleSniperSpots},
{"BotBestMG42Spot", (byte *)BotBestMG42Spot},
{"BotBestLandmineSpotingSpot", (byte *)BotBestLandmineSpotingSpot},
{"BotBestSniperSpot", (byte *)BotBestSniperSpot},
{"BotGetAimAccuracySkill", (byte *)BotGetAimAccuracySkill},
{"BotRecordDeath", (byte *)BotRecordDeath},
{"BotRecordPain", (byte *)BotRecordPain},
{"BotRecordKill", (byte *)BotRecordKill},
{"BotRecordTeamChange", (byte *)BotRecordTeamChange},
{"BotMoveToIntermission", (byte *)BotMoveToIntermission},
{"BotSetBlockEnt", (byte *)BotSetBlockEnt},
{"BotShutdownDeathmatchAI", (byte *)BotShutdownDeathmatchAI},
{"BotSetupDeathmatchAI", (byte *)BotSetupDeathmatchAI},
{"BotDeathmatchAI", (byte *)BotDeathmatchAI},
{"BotPowThink", (byte *)BotPowThink},
{"BotDeathmatchAIFirstCalled", (byte *)BotDeathmatchAIFirstCalled},
{"BotDumpNodeSwitches", (byte *)BotDumpNodeSwitches},
{"BotResetNodeSwitches", (byte *)BotResetNodeSwitches},
{"BotUpdateReconInfo", (byte *)BotUpdateReconInfo},
{"BotCheckAlert", (byte *)BotCheckAlert},
{"BotCheckAir", (byte *)BotCheckAir},
{"BotCheckSnapshot", (byte *)BotCheckSnapshot},
{"BotCheckEvents", (byte *)BotCheckEvents},
{"BotAIBlocked", (byte *)BotAIBlocked},
{"BotModelMinsMaxs", (byte *)BotModelMinsMaxs},
{"BotSetMovedir", (byte *)BotSetMovedir},
{"BotEntityToActivate", (byte *)BotEntityToActivate},
{"BotMapScripts", (byte *)BotMapScripts},
{"BotCheckAttack", (byte *)BotCheckAttack},
{"BotScopedWeapon", (byte *)BotScopedWeapon},
{"BotThrottleWeapon", (byte *)BotThrottleWeapon},
{"BotMoveWhileFiring", (byte *)BotMoveWhileFiring},
{"BotAimAtEnemySP", (byte *)BotAimAtEnemySP},
{"BotAimAtEnemy", (byte *)BotAimAtEnemy},
{"swayrand", (byte *)swayrand},
{"BotGetReactionTime", (byte *)BotGetReactionTime},
{"BotFindEnemyMP", (byte *)BotFindEnemyMP},
{"BotSortClientsByDistance", (byte *)BotSortClientsByDistance},
{"BotHasWeaponWithRange", (byte *)BotHasWeaponWithRange},
{"BotWeaponRange", (byte *)BotWeaponRange},
{"BotFindEnemies", (byte *)BotFindEnemies},
{"BotIsValidTarget", (byte *)BotIsValidTarget},
{"BotGetEntitySurfaceSoundCoefficient", (byte *)BotGetEntitySurfaceSoundCoefficient},
{"BotUpdateAlertStateSquadSensingInfo", (byte *)BotUpdateAlertStateSquadSensingInfo},
{"ChangeBotAlertState", (byte *)ChangeBotAlertState},
{"BotNoLeaderPenalty", (byte *)BotNoLeaderPenalty},
{"BotDangerousGoal", (byte *)BotDangerousGoal},
{"BotIgnoreGoal", (byte *)BotIgnoreGoal},
{"BotCheckMovementAutonomy", (byte *)BotCheckMovementAutonomy},
{"sAdjustPointTowardsPlayer", (byte *)sAdjustPointTowardsPlayer},
{"sAngleBetweenVectors", (byte *)sAngleBetweenVectors},
{"botindicator_think", (byte *)botindicator_think},
{"BotGoalForEntity", (byte *)BotGoalForEntity},
{"BotGoalWithinMovementAutonomy", (byte *)BotGoalWithinMovementAutonomy},
{"BotPointWithinRawMovementAutonomy", (byte *)BotPointWithinRawMovementAutonomy},
{"BotPointWithinMovementAutonomy", (byte *)BotPointWithinMovementAutonomy},
{"BotWithinLeaderFollowDist", (byte *)BotWithinLeaderFollowDist},
{"BotGetFollowAutonomyDist", (byte *)BotGetFollowAutonomyDist},
{"BotGetMovementAutonomyRange", (byte *)BotGetMovementAutonomyRange},
{"BotGetRawMovementAutonomyRange", (byte *)BotGetRawMovementAutonomyRange},
{"BotGetMovementAutonomyPos", (byte *)BotGetMovementAutonomyPos},
{"BotGetMovementAutonomyLevel", (byte *)BotGetMovementAutonomyLevel},
{"BotCheckAttackAtPos", (byte *)BotCheckAttackAtPos},
{"BotVisibleFromPos", (byte *)BotVisibleFromPos},
{"BotEntityVisible", (byte *)BotEntityVisible},
{"BotEntInvisibleBySmokeBomb", (byte *)BotEntInvisibleBySmokeBomb},
{"InFieldOfVision", (byte *)InFieldOfVision},
{"BotSameTeam", (byte *)BotSameTeam},
{"BotAttackMove", (byte *)BotAttackMove},
{"BotRoamGoal", (byte *)BotRoamGoal},
{"BotGoForPowerups", (byte *)BotGoForPowerups},
{"BotDontAvoid", (byte *)BotDontAvoid},
{"BotGoCamp", (byte *)BotGoCamp},
{"BotCanAndWantsToRocketJump", (byte *)BotCanAndWantsToRocketJump},
{"BotWantsToHelp", (byte *)BotWantsToHelp},
{"BotWantsToChase", (byte *)BotWantsToChase},
{"BotWantsToRetreat", (byte *)BotWantsToRetreat},
{"BotAggression", (byte *)BotAggression},
{"TeamPlayIsOn", (byte *)TeamPlayIsOn},
{"BotInitWaypoints", (byte *)BotInitWaypoints},
{"BotFreeWaypoints", (byte *)BotFreeWaypoints},
{"BotFindWayPoint", (byte *)BotFindWayPoint},
{"BotCreateWayPoint", (byte *)BotCreateWayPoint},
{"EntityHasQuad", (byte *)EntityHasQuad},
{"EntityIsChatting", (byte *)EntityIsChatting},
{"EntityIsShooting", (byte *)EntityIsShooting},
{"EntityIsInvisible", (byte *)EntityIsInvisible},
{"EntityInLimbo", (byte *)EntityInLimbo},
{"EntityIsDead", (byte *)EntityIsDead},
{"BotInSlime", (byte *)BotInSlime},
{"BotInLava", (byte *)BotInLava},
{"BotIntermission", (byte *)BotIntermission},
{"BotIsObserver", (byte *)BotIsObserver},
{"BotIsPOW", (byte *)BotIsPOW},
{"BotIsDead", (byte *)BotIsDead},
{"BotSetTeleportTime", (byte *)BotSetTeleportTime},
{"BotBattleUseItems", (byte *)BotBattleUseItems},
{"BotUpdateBattleInventory", (byte *)BotUpdateBattleInventory},
{"BotUpdateInventory", (byte *)BotUpdateInventory},
{"BotSetupForMovement", (byte *)BotSetupForMovement},
{"BotCycleWeapon", (byte *)BotCycleWeapon},
{"BotChooseWeapon", (byte *)BotChooseWeapon},
{"BotBestFightWeapon", (byte *)BotBestFightWeapon},
{"BotWeaponWantScale", (byte *)BotWeaponWantScale},
{"BotTeamMatesNearEnemy", (byte *)BotTeamMatesNearEnemy},
{"BotWeaponClosestDist", (byte *)BotWeaponClosestDist},
{"BotWeaponOnlyUseIfInInRange", (byte *)BotWeaponOnlyUseIfInInRange},
{"BotWeaponCharged", (byte *)BotWeaponCharged},
{"G_WeaponCharged", (byte *)G_WeaponCharged},
{"BotGotEnoughAmmoForWeapon", (byte *)BotGotEnoughAmmoForWeapon},
{"EasyClientName", (byte *)EasyClientName},
{"stristr", (byte *)stristr},
{"ClientFromName", (byte *)ClientFromName},
{"ClientSkin", (byte *)ClientSkin},
{"ClientName", (byte *)ClientName},
{"BotFindNearbyGoal", (byte *)BotFindNearbyGoal},
{"BotFindNearbyTriggerGoal", (byte *)BotFindNearbyTriggerGoal},
{"BotReachableBBoxAreaNum", (byte *)BotReachableBBoxAreaNum},
{"BotPointAreaNum", (byte *)BotPointAreaNum},
{"BotFirstLadderArea", (byte *)BotFirstLadderArea},
{"BotFirstReachabilityArea", (byte *)BotFirstReachabilityArea},
{"BotCarryingFlag", (byte *)BotCarryingFlag},
{"AINode_MP_NavigateFromVoid", (byte *)AINode_MP_NavigateFromVoid},
{"AIEnter_MP_NavigateFromVoid", (byte *)AIEnter_MP_NavigateFromVoid},
{"AINode_MP_MoveToAutonomyRange", (byte *)AINode_MP_MoveToAutonomyRange},
{"AIEnter_MP_MoveToAutonomyRange", (byte *)AIEnter_MP_MoveToAutonomyRange},
{"AINode_MP_Script_MoveToMarker", (byte *)AINode_MP_Script_MoveToMarker},
{"AIEnter_MP_Script_MoveToMarker", (byte *)AIEnter_MP_Script_MoveToMarker},
{"AINode_MP_Battle_Retreat", (byte *)AINode_MP_Battle_Retreat},
{"AIEnter_MP_Battle_Retreat", (byte *)AIEnter_MP_Battle_Retreat},
{"AINode_MP_Battle_Chase", (byte *)AINode_MP_Battle_Chase},
{"AIEnter_MP_Battle_Chase", (byte *)AIEnter_MP_Battle_Chase},
{"AINode_MP_Battle_Fight", (byte *)AINode_MP_Battle_Fight},
{"AIEnter_MP_Battle_Fight", (byte *)AIEnter_MP_Battle_Fight},
{"AINode_MP_DisarmDynamite", (byte *)AINode_MP_DisarmDynamite},
{"AIEnter_MP_DisarmDynamite", (byte *)AIEnter_MP_DisarmDynamite},
{"AINode_MP_PlantMine", (byte *)AINode_MP_PlantMine},
{"AIEnter_MP_PlantMine", (byte *)AIEnter_MP_PlantMine},
{"AINode_MP_ConstructibleTarget", (byte *)AINode_MP_ConstructibleTarget},
{"AIEnter_MP_ConstructibleTarget", (byte *)AIEnter_MP_ConstructibleTarget},
{"AINode_MP_DynamiteTarget", (byte *)AINode_MP_DynamiteTarget},
{"AIEnter_MP_DynamiteTarget", (byte *)AIEnter_MP_DynamiteTarget},
{"AINode_MP_SatchelChargeTarget", (byte *)AINode_MP_SatchelChargeTarget},
{"AIEnter_MP_SatchelChargeTarget", (byte *)AIEnter_MP_SatchelChargeTarget},
{"AINode_MP_TouchTarget", (byte *)AINode_MP_TouchTarget},
{"AIEnter_MP_TouchTarget", (byte *)AIEnter_MP_TouchTarget},
{"AINode_MP_DefendTarget", (byte *)AINode_MP_DefendTarget},
{"AIEnter_MP_DefendTarget", (byte *)AIEnter_MP_DefendTarget},
{"AINode_MP_SniperSpot", (byte *)AINode_MP_SniperSpot},
{"AIEnter_MP_SniperSpot", (byte *)AIEnter_MP_SniperSpot},
{"AINode_MP_ScanForLandmines", (byte *)AINode_MP_ScanForLandmines},
{"AIEnter_MP_ScanForLandmines", (byte *)AIEnter_MP_ScanForLandmines},
{"AINode_MP_MG42Mount", (byte *)AINode_MP_MG42Mount},
{"AIEnter_MP_MG42Mount", (byte *)AIEnter_MP_MG42Mount},
{"AINode_MP_MG42Scan", (byte *)AINode_MP_MG42Scan},
{"AIEnter_MP_MG42Scan", (byte *)AIEnter_MP_MG42Scan},
{"AINode_MP_Battle_MobileMG42", (byte *)AINode_MP_Battle_MobileMG42},
{"AIEnter_MP_Battle_MobileMG42", (byte *)AIEnter_MP_Battle_MobileMG42},
{"AINode_MP_FixMG42", (byte *)AINode_MP_FixMG42},
{"AIEnter_MP_FixMG42", (byte *)AIEnter_MP_FixMG42},
{"AINode_MP_AttackTarget", (byte *)AINode_MP_AttackTarget},
{"AIEnter_MP_AttackTarget", (byte *)AIEnter_MP_AttackTarget},
{"AINode_MP_PanzerTarget", (byte *)AINode_MP_PanzerTarget},
{"AIEnter_MP_PanzerTarget", (byte *)AIEnter_MP_PanzerTarget},
{"AINode_MP_MedicRevive", (byte *)AINode_MP_MedicRevive},
{"AIEnter_MP_MedicRevive", (byte *)AIEnter_MP_MedicRevive},
{"AINode_MP_MedicGiveHealth", (byte *)AINode_MP_MedicGiveHealth},
{"AIEnter_MP_MedicGiveHealth", (byte *)AIEnter_MP_MedicGiveHealth},
{"AINode_MP_GiveAmmo", (byte *)AINode_MP_GiveAmmo},
{"AIEnter_MP_GiveAmmo", (byte *)AIEnter_MP_GiveAmmo},
{"AINode_MP_AvoidDanger", (byte *)AINode_MP_AvoidDanger},
{"AIEnter_MP_AvoidDanger", (byte *)AIEnter_MP_AvoidDanger},
{"AINode_MP_Seek_NBG", (byte *)AINode_MP_Seek_NBG},
{"AIEnter_MP_Seek_NBG", (byte *)AIEnter_MP_Seek_NBG},
{"AINode_MP_Seek_ActivateEntity", (byte *)AINode_MP_Seek_ActivateEntity},
{"AIEnter_MP_Seek_ActivateEntity", (byte *)AIEnter_MP_Seek_ActivateEntity},
{"AINode_MP_Respawn", (byte *)AINode_MP_Respawn},
{"AIEnter_MP_Respawn", (byte *)AIEnter_MP_Respawn},
{"AINode_MP_Stand", (byte *)AINode_MP_Stand},
{"AIEnter_MP_Stand", (byte *)AIEnter_MP_Stand},
{"AINode_MP_Observer", (byte *)AINode_MP_Observer},
{"AIEnter_MP_Observer", (byte *)AIEnter_MP_Observer},
{"AINode_MP_Intermission", (byte *)AINode_MP_Intermission},
{"AIEnter_MP_Intermission", (byte *)AIEnter_MP_Intermission},
{"BotMP_MoveToGoal", (byte *)BotMP_MoveToGoal},
{"BotMP_FindGoal", (byte *)BotMP_FindGoal},
{"BotMP_FindGoal_New", (byte *)BotMP_FindGoal_New},
{"BotMP_AlreadyDoing_FastOut", (byte *)BotMP_AlreadyDoing_FastOut},
{"BotMP_FindGoal_PostProcessGoal", (byte *)BotMP_FindGoal_PostProcessGoal},
{"BotMP_FindGoal_ProcessGoal", (byte *)BotMP_FindGoal_ProcessGoal},
{"BotMP_FindGoal_ClassForGoalType", (byte *)BotMP_FindGoal_ClassForGoalType},
{"BotMP_FindGoals_Sort_CovertOps", (byte *)BotMP_FindGoals_Sort_CovertOps},
{"BotMP_FindGoals_Sort_Engineer", (byte *)BotMP_FindGoals_Sort_Engineer},
{"BotMP_FindGoals_Sort_Standard", (byte *)BotMP_FindGoals_Sort_Standard},
{"BotMP_FindGoal_BuildGoalList", (byte *)BotMP_FindGoal_BuildGoalList},
{"BotMP_CheckEmergencyGoals", (byte *)BotMP_CheckEmergencyGoals},
{"BotMP_CheckClassActions", (byte *)BotMP_CheckClassActions},
{"BotMatchMessage", (byte *)BotMatchMessage},
{"BotMatch_Kill", (byte *)BotMatch_Kill},
{"BotMatch_LeadTheWay", (byte *)BotMatch_LeadTheWay},
{"BotMatch_WhereAreYou", (byte *)BotMatch_WhereAreYou},
{"BotNearestVisibleItem", (byte *)BotNearestVisibleItem},
{"BotMatch_WhatIsMyCommand", (byte *)BotMatch_WhatIsMyCommand},
{"BotMatch_WhatAreYouDoing", (byte *)BotMatch_WhatAreYouDoing},
{"BotMatch_WhoIsTeamLeader", (byte *)BotMatch_WhoIsTeamLeader},
{"BotMatch_StopTeamLeaderShip", (byte *)BotMatch_StopTeamLeaderShip},
{"BotMatch_StartTeamLeaderShip", (byte *)BotMatch_StartTeamLeaderShip},
{"BotMatch_Dismiss", (byte *)BotMatch_Dismiss},
{"BotMatch_FormationSpace", (byte *)BotMatch_FormationSpace},
{"BotMatch_CheckPoint", (byte *)BotMatch_CheckPoint},
{"BotMatch_WhichTeam", (byte *)BotMatch_WhichTeam},
{"BotMatch_LeaveSubteam", (byte *)BotMatch_LeaveSubteam},
{"BotMatch_JoinSubteam", (byte *)BotMatch_JoinSubteam},
{"BotMatch_ReturnFlag", (byte *)BotMatch_ReturnFlag},
{"BotMatch_RushBase", (byte *)BotMatch_RushBase},
{"BotMatch_GetFlag", (byte *)BotMatch_GetFlag},
{"BotMatch_Patrol", (byte *)BotMatch_Patrol},
{"BotMatch_Camp", (byte *)BotMatch_Camp},
{"BotMatch_GetItem", (byte *)BotMatch_GetItem},
{"BotMatch_DefendKeyArea", (byte *)BotMatch_DefendKeyArea},
{"BotMatch_HelpAccompany", (byte *)BotMatch_HelpAccompany},
{"BotGPSToPosition", (byte *)BotGPSToPosition},
{"BotAddressedToBot", (byte *)BotAddressedToBot},
{"BotGetPatrolWaypoints", (byte *)BotGetPatrolWaypoints},
{"NumPlayersOnSameTeam", (byte *)NumPlayersOnSameTeam},
{"FindEnemyByName", (byte *)FindEnemyByName},
{"FindClientByName", (byte *)FindClientByName},
{"BotGetTime", (byte *)BotGetTime},
{"BotGetMessageTeamGoal", (byte *)BotGetMessageTeamGoal},
{"BotGetItemTeamGoal", (byte *)BotGetItemTeamGoal},
{0, 0}

2670
src/botai/ai_main.c Normal file

File diff suppressed because it is too large Load Diff

941
src/botai/ai_main.h Normal file
View File

@@ -0,0 +1,941 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: ai_main.h
*
* desc: Wolf bot AI
*
*
*****************************************************************************/
//#define DEBUG
#define CTF
// Uncomment the next line to get rid of massve repeat scrolling
// AI errors
//#define DONT_PRINT_REPEATED_AI_ERRORS
#define BOT_DEBUG_FOLLOW_PLAYER 11
// Mad Doctor I, 9/1/2002. Get bots speeds tweaked
#define NORMALIZED_MOVEMENT_SPEED 255
#define MAX_ITEMS 256
#define MAX_BOTAIWAYPOINTS 128
//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_MISCFLAG 64 // different uses for each ainode
#define BFL_DISMOUNT_MG42 128 //wanting to dismount mg42
#define BFL_SPRINT 256 // sprint
#define BFL_FIXED_MOVEMENT_AUTONOMY 512 // player has set movement autonomy
#define BFL_FIXED_WEAPON_AUTONOMY 1024 // player has set weapon autonomy
#define BFL_BATTLE_MODE 2048 // bot is in combat mode
#define BFL_SNIPING 4096 // bot is sniping
#define BFL_SCRIPTED_LEADER 8192 // leader is enforce via scripting
//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
//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 240 //4 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 CTF_GETFLAG_TIME 240 //4 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
//patrol flags
#define PATROL_LOOP 1
#define PATROL_REVERSE 2
#define PATROL_BACK 4
//copied from the aas file header
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
//RF, misc defines
#define BOT_FLAG_CARRIER_DEFENDERS 3
#define MAX_BOTLEADER_DIST 2048
#define MAX_BOTLEADER_TRAVEL 1000
// group formations
#define BOT_FORM_SINGLEFILE 0
#define BOT_FORM_DOUBLEFILE 1
#define BOT_FORM_PATROL_LINE 2
#define BOT_FORM_SEEK_COVER 3
#define BOT_FORM_NUM 4
#define BOT_FOLLOW_BEHIND 0
#define BOT_FOLLOW_LEFT 1
#define BOT_FOLLOW_RIGHT 2
#define BOT_FOLLOW_NUM 3
struct bot_state_s;
//check points
typedef struct bot_waypoint_s
{
int inuse;
char name[32];
bot_goal_t goal;
struct bot_waypoint_s *next, *prev;
} bot_waypoint_t;
#define BWPOFS( x ) ( (int)&( ( (bot_waypoint_t *)0 )->x ) )
#define MAX_VCHATS 16
typedef struct
{
int time;
int id;
int client; // who sent it
int mode;
} bot_chat_t;
//-----------------------------------------------------------------------------------------
// scripting
//
// defines
#define BOT_MAX_SCRIPT_ITEMS 512 // per character
#define BOT_MAX_SCRIPT_EVENTS 128 // per character
#define BOT_SIZE_STRING_POOL 16384
//
// flags
#define BSFL_FIRST_CALL 1
#define BSFL_LOGGING 2
#define BSFL_MOUNT_MG42 4
#define BSFL_FORCED_MOVEMENT_AUTONOMY 8 // scripting has enforced movement autonomy
#define BSFL_FORCED_WEAPON_AUTONOMY 16 // scripting has enforced weapon autonomy
// START xkan, 8/22/2002
// flags that make bots crouch/prone through scripts
#define BSFL_CROUCH 32
#define BSFL_PRONE 64
//#define BSFL_TALK 128 // flag to make bot play talk animation
// END xkan, 8/22/2002
//
// frame flags (stay resident until next script frame)
#define BSFFL_MOVETOTARGET 1
#define BSFFL_FOLLOW_LEADER 2
#define BSFFL_DIRECTMOVE 4 // move directly towards marker
// Force us to stand still
#define BSFFL_STAND 8
//
// movement autonomy
#define BMA_NOVALUE -1
#define BMA_LOW 0
#define BMA_MEDIUM 1
#define BMA_HIGH 2
#define NUM_BMA 3
//
// weapon autonomy
#define BWA_NOVALUE -1
#define BWA_LOW 0
#define BWA_MEDIUM 1
#define BWA_HIGH 2
#define NUM_BWA 3
// How many people can each bot be scripted to watch?
#define MAX_PEOPLE_TO_WATCH 8
// TAT 12/5/2002
// script autonomy values
typedef enum
{
BSA_NOVALUE = -1,
BSA_IGNOREENEMIES = 0,
BSA_MAINTAINSCRIPT,
BSA_NOCHASE,
BSA_QUITSCRIPT
} scriptAutonomy_t;
// TAT 12/5/2002
// So the follow behavior is different, depending on what our leader is doing
// Possible follow modes:
typedef enum
{
FOLLOW_LINE, // follow in a line
FOLLOW_LINE_CROUCH, // follow in a line, but crouched
FOLLOW_SEEKCOVER, // spread out and seek cover
FOLLOW_SEEKCOVER_FAR, // spread out further and seek cover
} followModes_t;
// START Mad Doctor I changes, 8/15/2002
//
// Alert State
// xkan, 1/10/2003 - replaced ALERTSTATE with AISTATE_*
//#define ALERTSTATE_RELAXED 0
//#define ALERTSTATE_ENGAGED 1
// END Mad Doctor I changes, 8/15/2002
// Start TAT 9/23/2002
// Bot recon information
// Invalid - not doing recon
#define BOTRECON_INVALID 0
// No enemies spotted
#define BOTRECON_ALLCLEAR 1
// saw enemies
#define BOTRECON_ENEMYSPOTTED 2
// under attack
#define BOTRECON_UNDERFIRE 3
// End TAT 9/23/2002
//
typedef enum {
BSMT_DEFAULT,
BSMT_WALKING,
BSMT_CROUCHING,
} botScriptMovetype_t;
//
typedef struct
{
char *actionString;
qboolean ( *actionFunc )( struct bot_state_s *bs, char *params );
} bot_script_stack_action_t;
//
typedef struct
{
// set during script parsing
bot_script_stack_action_t *action; // points to an action to perform
char *params;
// debugging info
int lineNum;
char *text; // points to the item location in global script buffer
} bot_script_stack_item_t;
//
typedef struct
{
int startIndex; // place in character items this stack begins
int numItems; // how many items in this stack
} bot_script_stack_t;
//
typedef struct
{
int eventNum; // index in scriptEvents[]
char *params; // trigger targetname, etc
bot_script_stack_t stack;
// debugging info
int lineNum;
char *text; // points to the item location in global script buffer
} bot_script_event_t;
//
typedef struct
{
char *eventStr;
qboolean ( *eventMatch )( bot_script_event_t *event, char *eventParm );
} bot_script_event_define_t;
//
// Scripting Status (NOTE: this MUST NOT contain any pointer vars)
typedef struct
{
int stackHead, stackChangeTime;
int eventIndex; // current event containing stack of actions to perform
bot_script_stack_item_t *currentItem;
int id; // incremented each time the script changes
vec3_t playanim_viewangles;
int scriptNoAttackTime;
int scriptNoMoveTime;
int playAnimViewlockTime;
//
// function-relative variables (lost after function finishes)
// ...
} bot_script_status_t;
//
// static parsed data
typedef struct
{
int numEvents;
char stringPool[BOT_SIZE_STRING_POOL];
bot_script_stack_item_t items[BOT_MAX_SCRIPT_ITEMS];
bot_script_event_t events[BOT_MAX_SCRIPT_EVENTS]; // contains a list of actions to perform for each event type
} bot_script_data_t;
//
typedef struct
{
int lineNum;
char *name;
char *params;
bot_script_data_t *data;
} bot_script_global_data_t;
//
typedef struct
{
bot_script_data_t *data; // pointer to global list of scripted characters
//
bot_script_status_t status; // current status of scripting
int callIndex; // inc'd each time a script is called
// persistent across function calls
int flags;
int frameFlags; // cleared at start of each script frame
int entityNum;
botScriptMovetype_t moveType;
fileHandle_t logFile;
int mg42entnum;
int weaponType;
int pauseTime; // stop running script for some time
int weaponAutonomy;
int movementAutonomy;
vec3_t movementAutonomyPos;
int accumBuffer[MAX_SCRIPT_ACCUM_BUFFERS]; // the accumulation buffer
} bot_script_t;
//-----------------------------------------------------------------------------------------
// Bot orders (issued by another player)
#define MAX_BOT_DEFAULT_STRING 512
///////////////////////////////////////////////////////////////////////////////
//
// STRUCT BotDefaultAttributes
//
typedef struct BotDefaultAttributes_s
{
// Name of the bot
char m_botName[MAX_BOT_DEFAULT_STRING];
// What delay is there before we react to an enemy?
float m_reactionTime;
// How often do we hit our target?
float m_aimAccuracy;
// How likely are we to run back to the player
float m_wimpFactor;
// How fast do we move?
float m_speedCoefficient;
// What % of the time will we fire?
float m_fireRate;
// Min fire cycle length
int m_minFireRateCycleTime;
// Max fire cycle length
int m_maxFireRateCycleTime;
// What is our scripted FOV?
float m_scriptedFieldOfView;
// What is our scripted hearing range?
float m_scriptedHearingRange;
// When an enemy is this close; we can hear them even outside our field of view
float m_closeHearingRange;
// How far can this bot see?
float m_visionRange;
// This range is range to which we can see enemies; even if they are too far to attack
float m_farSeeingRange;
// How independent?
int m_movementAutonomy;
// How likely to shoot
int m_weaponAutonomy;
} BotDefaultAttributes_t;
//
// STRUCT BotDefaultAttributes
//
///////////////////////////////////////////////////////////////////////////////
// Allow a good number of default character attributes
#define MAX_BOT_DEFAULTS 64
#define MAX_BOT_DEFAULT_FILE_SIZE 50000
#define NUM_BOT_DEFAULT_SIZE 16
typedef enum
{
BOT_COMMAND_NULL,
BOT_COMMAND_FOLLOWME,
BOT_COMMAND_SEEK_COVER,
BOT_COMMAND_OBJECTIVE,
BOT_COMMAND_SNIPER,
BOT_COMMAND_COMETOME,
BOT_COMMAND_PLANT_MINE,
BOT_COMMAND_STANDSTILLDAMMIT,
// TAT - adding new commands
BOT_COMMAND_HOLDPOSITION,
BOT_COMMAND_MOVETOLOC, // move to the location the player is looking at
BOT_COMMAND_REVIVE, // medic ordered to revive an ailing teammate
BOT_COMMAND_DISGUISE, // covert op ordered to get an enemy uniform
BOT_COMMAND_SUPPORTFIRE, // lieutenant ordered to call airstrike or artillery
BOT_COMMAND_RECON, // bot goes on recon looking for enemies
BOT_COMMAND_COVERTHAT, // bot covers a location, doesn't move to it
BOT_COMMAND_GIVEHEALTH, // making the medic give health command an explicit state
BOT_COMMAND_GIVEAMMO, // similarly, making lieutenant give ammo command explicit as well
BOT_COMMAND_TEAM_HEALTH_AMMO, // devote yourself to giving health or ammo to the whole team - dependent on your class
BOT_COMMAND_DETECTMINES, // covert op looks for mines in a specified area
BOT_COMMAND_DISARM, // engineer disarm mine or dynamite
BOT_COMMAND_ATTACK, // an attack order, means we shouldn't break off from attacking our current target as easily
BOT_COMMAND_KNIFEATTACK, // covert ops special knife attack
// end TAT add
} botCommand_t;
//-----------------------------------------------------------------------------------------
// note: these must be kept in sync with the list in ai_script.c
typedef enum
{
BOT_REACTION_TIME,
BOT_AIM_ACCURACY,
BOT_WIMP_FACTOR,
//
BOT_MAX_ATTRIBUTES
} botAttributes_t;
// What is our position in our cover spot chain? Basically,
// are we unable tog o farther int he direction we want?
typedef enum
{
COVER_CHAIN_NONE,
COVER_CHAIN_NORMAL,
COVER_CHAIN_NOWHERE_TO_GO
} coverChainSpot_t;
#define MAX_IGNORE_GOALS 32
typedef struct
{
int entityNum;
int areanum; // goal areanum
vec3_t autonomyPos; // avoid it only if our autonomy position is the same as this
int expireTime;
} botIgnoreGoal_t;
typedef struct {
int ( *func )( struct bot_state_s *bs );
} botMatrixFunc_t;
typedef struct {
botMatrixFunc_t cells[NUM_BWA][NUM_BMA];
} botMatrix_t;
// TAT 1/8/2003 - we store this many of our previous seek cover seqs - used for retreating
#define MAX_STORED_SEEKCOVERS 3
//-----------------------------------------------------------------------------------------
//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[1024]; //last entity event time
//
bot_settings_t settings; //several bot settings
int ( *ainode )( struct bot_state_s *bs ); //current AI node
char *ainodeText;
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 enemysuicide; //true when the enemy of the bot suicides
int setupcount; //true when the bot has just been setup
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 chatto; //chat to all or team
float walker; //walker charactertic
// float ltime; //local bot 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 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_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
int arrive_time; //time arrived (at companion)
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
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
//
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 ltgtype; //long term goal type
//
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
//
bot_goal_t lead_teamgoal; //team goal while leading
float lead_time; //time leading someone
// 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
int numteammates; //number of team mates
int flagcarrier; //team mate carrying the enemy flag
char subteam[32]; //sub team name
// 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_waypoint_t *checkpoints; //check points
bot_waypoint_t *patrolpoints; //patrol points
bot_waypoint_t *curpatrolpoint; //current patrol point the bot is going for
//
int mpTeam, mpClass, mpWeapon; //kinda like cvar's for real players
int lastClassCheck;
//
bot_goal_t target_goal;
bot_goal_t avoid_goal; // the item we are avoiding
bot_goal_t alt_goal; // alternative route goal
bot_goal_t nearbygoal;
bot_goal_t defendgoal;
bot_goal_t hidegoal;
bot_goal_t messageGoal; // the message we must deliver - xkan, 10/28/2002
bot_goal_t activategoal; //goal to activate (buttons etc.)
//
clientSession_t sess; // copied from gclient_t for convenience
//
int viewtype, viewchangetime;
//
int ignore_specialgoal_time;
int give_health_time;
int blockent, blockentTime;
int last_fire;
//
bot_chat_t vchats[MAX_VCHATS]; // record of voice chats sent to us
//
int altenemy;
//
int last_findspecialgoal;
int last_voice_chat;
qboolean alreadySaidOutOfAmmo; // if we just ran out of ammo, have we said it?
//
int last_kill_time;
int shorterm_kill_count;
//
int last_checkvoice_health;
//
int last_helped_client;
int last_helped_time;
//
int last_checkemergencytargets;
int last_findspecialgoals;
int last_findenemy, last_findenemy_enemy;
int last_SparseDefense;
int last_avoiddangerarea;
int last_dangerousgoal;
int last_botcheckattack;
int last_botcheckattack_weapon;
int last_botcheckattack_enemy;
int last_pain;
int last_pain_client;
int last_enemysight;
int last_heardShooting; // xkan - the last time we heard shooting
int last_heardFootSteps; // xkan - the last time we heard people moving around
int last_attackShout; // xkan - the last time we shout attack/kill/etc.
int next_nearbygoal;
int mobileMG42ProneTime;
int nextRetreatCheck; // when should we check to see if we should retreat to the player -- TAT 12/12/2002
int lastRetreatTime; // the last time we retreated
float retreatLikeliness; // chance that we will retreat
qboolean shouldRetreat; // should we retreat to the player? -- TAT 12/12/2002
//
vec3_t defendgoal_origin;
//
int leader;
int leader_tagent; // follow this entity for formation only
// TAT 12/13/2002 - Need to keep track of when the player last moved, so storing their position,
// and we'll update the timer whenever it changes - only relevant in FollowLeader
vec3_t lastLeaderPosition;
int lastLeaderMoveTime;
int leaderStanceChangeTime; // time leader changed stance
int lastLeaderStance; // standing, prone, crouched
// vec3_t leader_lastvel; // last non-zero velocity
//
int avoid_spawnCount;
//
botIgnoreGoal_t ignoreGoals[MAX_IGNORE_GOALS];
//
// ATTRIBUTES
// Mad Doctor I, 12/8/2002. Trimmed most of the unused attributes out.
float attribs[BOT_MAX_ATTRIBUTES];
// SCRIPTING SYSTEM
bot_script_t script;
//
// COMMAND STATUS
int movementAutonomy;
vec3_t movementAutonomyPos;
// Mad Doctor I changes, 8/15/2002
// When did we enter the current AI Node?
int enteredCurrentAINodeTime;
// Has the bot seen an enemy yet?
aistateEnum_t alertState;
int alertStateChangeTime; // the time alert state was changed to the current state.
int alertStateSetTime; // the time we attempt to set alert state to the same state.
// when are we free to change alertState - required by scripting system
int alertStateAllowChangeTime;
// What is our scripted FOV?
float scriptedFieldOfView;
// What is our scripted hearing range?
float scriptedHearingRange;
// How far can this bot see for choosing attack targets?
float visionRange;
// This range is range to which we can see enemies, even if they
// are to far to attack
float farSeeingRange;
// When an enemy is this close, we can hear them even outside our
// field of view
float closeHearingRange;
// What weapon are the scripts telling us to use?
int scriptedWeapon;
// Have we been scripted to be asleep
qboolean scriptedSleep;
// Did our latest path planning fail?
qboolean movementFailedBadly;
// last time an anim was played using scripting
int scriptAnimTime;
// which anim was last played by the scripts
// When should we change to a new seek cover spot?
int whenToFindNewCombatSpot;
// The current spot we're looking for
int seekCoverSpot;
// Are we currently hiding?
qboolean amIHiding;
// When should we stop hiding
int toggleHidingTime;
// Do we have a specfic scripted cover spot
g_serverEntity_t *scriptedCoverSpot;
// Store the last few seek cover sequences -- TAT 1/8/2003
int lastSeekCoverSpots[MAX_STORED_SEEKCOVERS];
// What sort of spot are we in? Is it an end spot?
coverChainSpot_t coverSpotType;
// Scripted speed for the bot
float speedCoefficient;
// Is this bot selectable - it might be "hidden" from the player -- TAT 10/28/2002
qboolean isBotSelectable;
// TAT changes 8/20/2002
// Have we received a player command such that we should override any movement scripts?
qboolean overrideMovementScripts;
// Each bot is allowed to have 1 indicator for where it is going
gentity_t* indicator;
// Gordon: 27//11/02: are we a pow?
qboolean isPOW;
// TAT 9/23/2002
// keep track of recon info for a bot - have we seen an enemy, are we under attack
int reconInfo;
int returnToLeader; // Return to following this leader when our current goal is completed -- TAT 9/27/2002
int commandedWeapon; // if this bot has been commanded to use a particular weapon - this is it -- TAT 11/14/2002
// TAT 11/12/2002
// For Listen up/go go go
// We need to store info about the next command to execute
// Do we have a queued action? what type? 0 means no action, 1 means location, 2 means vchat
int haveQueuedCmd;
int queuedAction; // the botaction index - also could be used to store voice chat id
int queuedEntity; // the entity
int queuedSource; // which player gave the cmd?
vec3_t queuedLoc; // the location
vec3_t queuedPlayerLoc; // the player's loc at the time of the queuing
scriptAutonomy_t scriptAutonomy; // how much are we allowed to break from our scripted commands? -- TAT 12/5/2002
followModes_t followMode; // we don't want to switch between followmodes too frequently, so store the mode -- TAT 12/5/2002
int nextFollowModeTime; // nest time to update the followMode -- TAT 12/5/2002
//
// Goal/AI Matrix
botMatrix_t *objectiveMatrix;
botMatrix_t *behaviourMatrix;
botMatrix_t *engagementMatrix;
//
int lastAttackShared;
//
float fireRate; // the ratio of actual firing speed vs. maximum(normal) firing speed
int fireRateCheckTime; // the next time we should check for fire rate -xkan
int minFireRateCycleTime; // during a fire rate cycle, bot will fire for a duration of fireRate * cylcleTime
int maxFireRateCycleTime; // and will not fire for the rest of the cycle - (1-fireRate) * cycleTime
qboolean arrived; // Have we gottent to our next spot yet?
int clientCheckTime; // Gordon: pows check for enemies/friends nearby
} bot_state_t;
#define BFOFS( x ) ( (int)&( ( (bot_state_t *)0 )->x ) )
// Used in ai_team.c for BotClosestSeekCoverSpot_r
typedef qboolean ( *fCoverSpotCheck )( bot_state_t *bs, int leader, vec3_t leaderPos, g_serverEntity_t *coverSpot, float *bestDist );
//resets the whole bot state
void BotResetState( bot_state_t *bs );
//returns the number of bots in the game
int NumBots( void );
//returns info about the entity
void BotEntityInfo( int entnum, aas_entityinfo_t *info );
int BotAI_GetNumBots( void );
void BotAI_SetNumBots( int numbots );
gentity_t *BotFindEntityForName( char *name );
int BotTravelFlagsForClient( int client );
// BotScript declarations
// We need to support more than 64 bot scripts. Note that this doesn't mean more than
// 64 simultaneous bots, but separate bot scritps.
#define MAX_BOT_SCRIPT_CHARACTERS 256
extern bot_script_global_data_t botCharacterScriptData[MAX_BOT_SCRIPT_CHARACTERS];
void Bot_ScriptLoad( void );
void Bot_ScriptParse( bot_script_data_t *bsd, char **text );
qboolean Bot_ScriptInitBot( int entnum );
qboolean Bot_ScriptRun( bot_state_t *bs, qboolean force );
void Bot_ScriptLog_Entry( bot_state_t *bs, qboolean showDetails, char *preText, char *fmt, ... );
int Bot_Script_GetCurrentLine( bot_state_t *bs );
void Bot_ScriptThink( void );
int Bot_FindSriptGlobalData( bot_script_data_t *data );
// done.
/*
// Ridah, defines for AI Cast system
int AICast_ShutdownClient(int client);
void AICast_Init (void);
void AICast_StartFrame ( int time);
// done.
*/
//bot states
extern bot_state_t botstates[MAX_CLIENTS];
// from the game source
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 );
int BotAI_GetEntityState( int entityNum, entityState_t *state );
int BotAI_GetSnapshotEntity( int clientNum, int sequence, entityState_t *state );
// the static entity cache, to reduce load on G_Find()
// !!! NOTE: must be in synch with string list in ai_main.c
typedef enum {
BOTSTATICENTITY_CHECKPOINT,
BOTSTATICENTITY_FLAGONLY,
BOTSTATICENTITY_MG42,
BOTSTATICENTITY_OBJECTIVE_INFO,
BOTSTATICENTITY_CTF_REDFLAG,
BOTSTATICENTITY_CTF_BLUEFLAG,
BOTSTATICENTITY_FUNC_EXPLOSIVE,
BOTSTATICENTITY_FUNC_DOOR,
BOTSTATICENTITY_FUNC_DOOR_ROTATING,
BOTSTATICENTITY_FUNC_CONSTRUCTIBLE,
BOTSTATICENTITY_TRIGGER_MULTIPLE,
BOTSTATICENTITY_FLAGONLY_MULTIPLE,
BOTSTATICENTITY_BOT_LANDMINE_AREA,
BOTSTATICENTITY_BOT_ATTRACTOR,
BOTSTATICENTITY_BOT_SNIPERSPOT,
BOTSTATICENTITY_BOT_LANDMINESPOTINGSPOT,
//
NUM_BOTSTATICENTITY
} botStaticEntityEnum_t;
void BotBuildStaticEntityCache( void );
gentity_t *BotFindNextStaticEntity( gentity_t *start, botStaticEntityEnum_t entityEnum );
gentity_t *BotSpawnGameEntity( void );
//void BotInitBotGameEntities(void);
gentity_t *BotGetEntity( int entityNum );
/*
=================
FindBotByName
=================
Get the bot state of a named bot
*/
bot_state_t *FindBotByName( char * botName );
int BotGetTargetExplosives( team_t team, int *list, int listSize, qboolean ignoreDynamite );
int BotGetTargetsForSatchelCharge( team_t team, int *list, int listSize, qboolean ignoreDynamite );
int BotGetTargetDynamite( int *list, int listSize, gentity_t* target );
void BotDebugViewClient( int client );
// profiling vars
extern int botTime_EmergencyGoals;
extern int botTime_FindGoals;
extern int botTime_FindEnemy;
extern vmCvar_t bot_profile;
extern vmCvar_t bot_findgoal;
typedef enum botgoalFindType_e {
/* *cough* */
BFG_FOLLOW_LEADER = 0,
BFG_CONSTRUCT,
BFG_TRIGGER,
BFG_DESTRUCTION_EXPLOSIVE,
BFG_DESTRUCTION_BUILDING,
BFG_MG42_REPAIR,
BFG_MINE,
BFG_ATTRACTOR,
BFG_SNIPERSPOT,
BFG_MG42,
BFG_SCANFORMINES,
BFG_DESTRUCTION_SATCHEL,
BFG_NUMBOTGOALTYPES,
} botgoalFindType_t;
extern int botgoalMaxCloser[BFG_NUMBOTGOALTYPES];

60
src/botai/ai_matrix.h Normal file
View File

@@ -0,0 +1,60 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: ai_matrix.h
*
* desc: Wolf bot AI
*
*
*****************************************************************************/
//
// matrix definitions
//
extern botMatrix_t soldierBehaviourMatrix;
extern botMatrix_t soldierObjectiveMatrix;
extern botMatrix_t soldierEngagementMatrix;
extern botMatrix_t medicBehaviourMatrix;
extern botMatrix_t medicObjectiveMatrix;
extern botMatrix_t medicEngagementMatrix;
extern botMatrix_t ltBehaviourMatrix;
extern botMatrix_t ltObjectiveMatrix;
extern botMatrix_t ltEngagementMatrix;
extern botMatrix_t covertopsBehaviourMatrix;
extern botMatrix_t covertopsObjectiveMatrix;
extern botMatrix_t covertopsEngagementMatrix;
extern botMatrix_t engineerBehaviourMatrix;
extern botMatrix_t engineerObjectiveMatrix;
extern botMatrix_t engineerEngagementMatrix;

1171
src/botai/ai_script.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

3183
src/botai/ai_team.c Normal file

File diff suppressed because it is too large Load Diff

134
src/botai/ai_team.h Normal file
View File

@@ -0,0 +1,134 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: ai_team.h
*
* desc: Wolf bot AI
*
*
*****************************************************************************/
#ifndef BOT_SHOWTEXT
#define BOT_SHOWTEXT 2
typedef enum {
VCHAT_MEDIC,
VCHAT_NEEDAMMO,
VCHAT_NEEDBACKUP,
VCHAT_DYNAMITEPLANTED,
VCHAT_GREATSHOT,
VCHAT_HI,
VCHAT_THANKS,
VCHAT_FOLLOWME,
VCHAT_DROPFLAG,
} vchat_id_t;
#endif
///////////////////////////////////////////////////////////////////////////////
//
// STRUCT AI_Team
//
typedef struct AI_Team_s
{
// Last time we had a vo from this team
int last_voice_chat;
} AI_Team_t;
//
// STRUCT AI_Team
//
///////////////////////////////////////////////////////////////////////////////
qboolean BotCheckNeedEngineer( bot_state_t *bs, team_t team );
int BotSuggestClass( bot_state_t *bs, team_t team );
int BotFlagAtBase( int team, gentity_t **returnEnt );
qboolean BotCheckEmergencyTargets( bot_state_t *bs );
int BotFindSparseDefendArea( bot_state_t *bs, bot_goal_t *goal, qboolean force );
int BotNumTeamMatesWithTarget( bot_state_t *bs, int targetEntity, int *list, int maxList );
int BotNumTeamMatesWithTargetAndCloser( bot_state_t *bs, int targetEntity, int targetArea, int *list, int maxList, int playerType );
int BotNumTeamMatesWithTargetByClass( bot_state_t *bs, int targetEntity, int *list, int maxList, int playerType );
int BotNumTeamMates( bot_state_t *bs, int *list, int maxList );
gentity_t *BotGetEnemyFlagCarrier( bot_state_t *bs );
// Start - TAT 9/20/2002
// covert ops bot looks for nearby corpses
qboolean BotClass_CovertOpsCheckDisguises( bot_state_t *bs, int maxTravel, bot_goal_t *goal );
// End - TAT 9/20/2002
qboolean BotClass_MedicCheckRevives( bot_state_t *bs, int maxtravel, bot_goal_t *goal, qboolean lookForBots );
qboolean BotClass_MedicCheckGiveHealth( bot_state_t *bs, int maxTravelTime, bot_goal_t *goal );
qboolean BotClass_LtCheckGiveAmmo( bot_state_t *bs, int maxTravelTime, bot_goal_t *goal );
qboolean BotFindDroppedFlag( gentity_t **returnEnt );
void BotSendVoiceChat( bot_state_t *bs, const char *id, int mode, int delay, qboolean voiceonly, qboolean forceIfDead );
void BotCheckVoiceChatResponse( bot_state_t *bs );
void BotSpawnSpecialEntities( void );
int BotSuggestWeapon( bot_state_t *bs, team_t team );
int BotGetTeamFlagCarrier( bot_state_t *bs );
float *BotSortPlayersByDistance( vec3_t target, int *list, int numList );
float *BotSortPlayersByTraveltime( int areanum, int *list, int numList );
int BotGetLeader( bot_state_t *bs, qboolean onlyRequested );
void BotVoiceChatAfterIdleTime( int client, const char *id, int mode, int delay, qboolean voiceonly, int idleTime, qboolean forceIfDead );
void BotVoiceChatAfterTeamIdleTime( int client, const char *id, int mode, int delay, qboolean voiceonly, int idleTime, qboolean forceIfDead );
void BotSetLeaderTagEnt( bot_state_t *bs );
int BotEngagementFunc( bot_state_t *bs );
int BotBehaviourFunc( bot_state_t *bs );
int BotObjectiveFunc( bot_state_t *bs );
qboolean G_RequestedAmmo( bot_state_t *bs, int client, qboolean clear );
int BotGetConstructibles( team_t team, int *list, int listSize, qboolean ignoreBuilt );
int BotClosestSeekCoverSpot( bot_state_t *bs );
// OK, this one looks in the specified direction (retreat/advance) and
// find the next available spot.
// Returns the entity number of the spot, -1 if N/A.
int BotSquadGetNextAvailableSeekCoverSpot
(
// The info for the bot
bot_state_t *bs,
// Moving forwards or backwards?
qboolean advance,
// entity id of the player we should check being in a seek_cover_sequence
int entityId
);
// TAT 12/19/2002 - When a bot sees an enemy, he tells his squadmates
void BotSquadEnemySight( bot_state_t *bs, int enemy );
// TAT 12/10/2002
// If possible, find a seek cover spot marked as exposed that is a parent or child of the current seek cover spot
int BotGetAdjacentExposedCoverSpot( bot_state_t *bs );
// TAT 1/8/2003
// Get the next cover spot towards the retreatTo entity - used when retreating
int BotGetRetreatingCoverSpot( bot_state_t *bs, int retreatTo );
void AI_Team_Init_All_Teams();

110
src/botai/botai.h Normal file
View File

@@ -0,0 +1,110 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: botai.h
// Function: bot AI
// Programmer: Mr Elusive (MrElusive@idsoftware.com)
// Last update: 1999-08-18
// Tab Size: 3
//===========================================================================
//debug line colors
#define LINECOLOR_NONE -1
#define LINECOLOR_RED 1
#define LINECOLOR_GREEN 2
#define LINECOLOR_BLUE 3
#define LINECOLOR_YELLOW 4
#define LINECOLOR_ORANGE 5
//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
//some maxs
#define MAX_NETNAME 36
#define MAX_CLIENTSKINNAME 128
#define MAX_FILEPATH 144
#define MAX_CHARACTERNAME 144
#ifndef 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;
#define BSPTRACE
#endif // BSPTRACE
//
// 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( int clientNum );
void trap_BotFreeClient( int clientNum );
*/

159
src/botai/chars.h Normal file
View File

@@ -0,0 +1,159 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: chars.h
// Function: bot characteristics
// Programmer: digibob
// Last update: 2003-03-27
// Tab Size: 4 (real tabs)
//===========================================================================
//unless specified, the higher the number, the better the characteristic, or
//the greater the likelyhood of the characteristic occuring.
//also, if any characteristic is ommited, the default value will be used from
//the file in /bots/default_c.c
//========================================================
//========================================================
//name
#define CHARACTERISTIC_NAME 0 //string
//gender of the bot
#define CHARACTERISTIC_GENDER 1 //string ("male", "female", "it")
//attack skill
// > 0.0 && < 0.2 = don't move
// > 0.3 && < 1.0 = aim at enemy during retreat
// > 0.0 && < 0.4 = only move forward/backward
// >= 0.4 && < 1.0 = circle strafing
// > 0.7 && < 1.0 = random strafe direction change
#define CHARACTERISTIC_ATTACK_SKILL 2 //float [0, 1]
//weapon weight file
#define CHARACTERISTIC_WEAPONWEIGHTS 3 //string
//view angle difference to angle change factor
#define CHARACTERISTIC_VIEW_FACTOR 4 //float <0, 1]
//maximum view angle change
#define CHARACTERISTIC_VIEW_MAXCHANGE 5 //float [1, 360]
//reaction time in seconds
#define CHARACTERISTIC_REACTIONTIME 6 //float [0, 5]
//accuracy when aiming
#define CHARACTERISTIC_AIM_ACCURACY 7 //float [0, 1]
//weapon specific aim accuracy
#define CHARACTERISTIC_AIM_ACCURACY_MACHINEGUN 8 //float [0, 1]
#define CHARACTERISTIC_AIM_ACCURACY_SHOTGUN 9 //float [0, 1]
#define CHARACTERISTIC_AIM_ACCURACY_ROCKETLAUNCHER 10 //float [0, 1]
#define CHARACTERISTIC_AIM_ACCURACY_GRENADELAUNCHER 11 //float [0, 1]
#define CHARACTERISTIC_AIM_ACCURACY_FLAMETHROWER 12
#define CHARACTERISTIC_AIM_ACCURACY_SP5 13 //float [0, 1]
#define CHARACTERISTIC_AIM_ACCURACY_SNIPERRIFLE 14
#define CHARACTERISTIC_AIM_ACCURACY_BFG10K 15 //float [0, 1]
//skill when aiming
// > 0.0 && < 0.9 = aim is affected by enemy movement
// > 0.4 && <= 0.8 = enemy linear leading
// > 0.8 && <= 1.0 = enemy exact movement leading
// > 0.5 && <= 1.0 = prediction shots when enemy is not visible
// > 0.6 && <= 1.0 = splash damage by shooting nearby geometry
#define CHARACTERISTIC_AIM_SKILL 16 //float [0, 1]
//weapon specific aim skill
#define CHARACTERISTIC_AIM_SKILL_ROCKETLAUNCHER 17 //float [0, 1]
#define CHARACTERISTIC_AIM_SKILL_GRENADELAUNCHER 18 //float [0, 1]
#define CHARACTERISTIC_AIM_SKILL_SP5 19 //float [0, 1]
//#define CHARACTERISTIC_AIM_SKILL_BFG10K 20 //float [0, 1]
#define CHARACTERISTIC_AIM_SKILL_SNIPERRIFLE 20
//========================================================
//chat
//========================================================
//file with chats
#define CHARACTERISTIC_CHAT_FILE 21 //string
//name of the chat character
#define CHARACTERISTIC_CHAT_NAME 22 //string
//characters per minute type speed
#define CHARACTERISTIC_CHAT_CPM 23 //integer [1, 4000]
//tendency to insult/praise
#define CHARACTERISTIC_CHAT_INSULT 24 //float [0, 1]
//tendency to chat misc
#define CHARACTERISTIC_CHAT_MISC 25 //float [0, 1]
//tendency to chat at start or end of level
#define CHARACTERISTIC_CHAT_STARTENDLEVEL 26 //float [0, 1]
//tendency to chat entering or exiting the game
#define CHARACTERISTIC_CHAT_ENTEREXITGAME 27 //float [0, 1]
//tendency to chat when killed someone
#define CHARACTERISTIC_CHAT_KILL 28 //float [0, 1]
//tendency to chat when died
#define CHARACTERISTIC_CHAT_DEATH 29 //float [0, 1]
//tendency to chat when enemy suicides
#define CHARACTERISTIC_CHAT_ENEMYSUICIDE 30 //float [0, 1]
//tendency to chat when hit while talking
#define CHARACTERISTIC_CHAT_HITTALKING 31 //float [0, 1]
//tendency to chat when bot was hit but didn't dye
#define CHARACTERISTIC_CHAT_HITNODEATH 32 //float [0, 1]
//tendency to chat when bot hit the enemy but enemy didn't dye
#define CHARACTERISTIC_CHAT_HITNOKILL 33 //float [0, 1]
//tendency to randomly chat
#define CHARACTERISTIC_CHAT_RANDOM 34 //float [0, 1]
//tendency to reply
#define CHARACTERISTIC_CHAT_REPLY 35 //float [0, 1]
//========================================================
//movement
//========================================================
//tendency to crouch
#define CHARACTERISTIC_CROUCHER 36 //float [0, 1]
//tendency to jump
#define CHARACTERISTIC_JUMPER 37 //float [0, 1]
//tendency to walk
#define CHARACTERISTIC_WALKER 48 //float [0, 1]
//tendency to jump using a weapon
#define CHARACTERISTIC_WEAPONJUMPING 38 //float [0, 1]
//tendency to use the grapple hook when available
#define CHARACTERISTIC_GRAPPLE_USER 39 //float [0, 1] //use this!!
//========================================================
//goal
//========================================================
//item weight file
#define CHARACTERISTIC_ITEMWEIGHTS 40 //string
//the aggression of the bot
#define CHARACTERISTIC_AGGRESSION 41 //float [0, 1]
//the self preservation of the bot (rockets near walls etc.)
#define CHARACTERISTIC_SELFPRESERVATION 42 //float [0, 1]
//how likely the bot is to take revenge
#define CHARACTERISTIC_VENGEFULNESS 43 //float [0, 1] //use this!!
//tendency to camp
#define CHARACTERISTIC_CAMPER 44 //float [0, 1]
//========================================================
//========================================================
//tendency to get easy frags
#define CHARACTERISTIC_EASY_FRAGGER 45 //float [0, 1]
//how alert the bot is (view distance)
#define CHARACTERISTIC_ALERTNESS 46 //float [0, 1]
//how much the bot fires it's weapon
#define CHARACTERISTIC_FIRETHROTTLE 47 //float [0, 1]
//========================================================
//========================================================
// Gordon: adding new aim accuracies... this file needs cleaned up...
#define CHARACTERISTIC_AIM_ACCURACY_PRONEMG42 49 //float [0, 1]

138
src/botai/inv.h Normal file
View File

@@ -0,0 +1,138 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*
* name: inv.h
*
* desc:
*
*/
#define INVENTORY_NONE 0
//armor
#define INVENTORY_ARMOR 1
//weapons
#define INVENTORY_LUGER 4
#define INVENTORY_MP40 6
#define INVENTORY_DYNAMITE 7
#define INVENTORY_GRENADELAUNCHER 8
#define INVENTORY_FLAMETHROWER 10
#define INVENTORY_PANZERFAUST 11
#define INVENTORY_COLT 12
#define INVENTORY_THOMPSON 13
#define INVENTORY_GRENADE_PINEAPPLE 15
#define INVENTORY_STEN 17
//special "powers"
#define INVENTORY_MEDIC_SYRINGE 20
#define INVENTORY_AMMO 21
#define INVENTORY_MEDKIT 22
#define INVENTORY_PLIERS 23
#define INVENTORY_SMOKE_GRENADE 24
// please leave these open up to 27 (INVENTORY_9MM) (and double check defines when merging)
// the inventory max (MAX_ITEMS) is 256, so we aren't too concerned about running out of space
//ammo
#define INVENTORY_9MM 27
#define INVENTORY_45CAL 28
#define INVENTORY_PANZERFAUST_AMMO 33
#define INVENTORY_FUEL 34
#define INVENTORY_GRENADES 35
#define INVENTORY_GRENADES_AMERICAN 36
#define INVENTORY_DYNAMITE_AMMO 37
// Mad Doc - TDF
// @TODO make an inventory for whatever we decide to use for BAR ammo. Bots can't use M1?
// please leave these open up to 48 (INVENTORY_HEALTH) (and double check defines when merging)
// the inventory max (MAX_ITEMS) is 256, so we aren't too concerned about running out of space
//powerups
#define INVENTORY_HEALTH 48
#define INVENTORY_TELEPORTER 49
#define INVENTORY_QUAD 51
#define INVENTORY_ENVIRONMENTSUIT 52
#define INVENTORY_HASTE 53
#define INVENTORY_INVISIBILITY 54
#define INVENTORY_REGEN 55
#define INVENTORY_FLIGHT 56
#define INVENTORY_REDFLAG 57
#define INVENTORY_BLUEFLAG 58
//enemy stuff
#define ENEMY_HORIZONTAL_DIST 200
#define ENEMY_HEIGHT 201
#define NUM_VISIBLE_ENEMIES 202
#define NUM_VISIBLE_TEAMMATES 203
#define GOAL_TRAVELTIME 204
//item numbers (make sure they are in sync with bg_itemlist in bg_misc.c)
#define MODELINDEX_ARMORSHARD 1
#define MODELINDEX_ARMORCOMBAT 2
#define MODELINDEX_ARMORBODY 3
#define MODELINDEX_HEALTHSMALL 4
#define MODELINDEX_HEALTH 5
#define MODELINDEX_HEALTHLARGE 6
#define MODELINDEX_HEALTHMEGA 7
#define MODELINDEX_GAUNTLET 8
#define MODELINDEX_SHOTGUN 9
#define MODELINDEX_MACHINEGUN 10
#define MODELINDEX_GRENADELAUNCHER 11
#define MODELINDEX_ROCKETLAUNCHER 12
#define MODELINDEX_LIGHTNING 13
#define MODELINDEX_RAILGUN 14
#define MODELINDEX_SP5 15
#define MODELINDEX_BFG10K 16
#define MODELINDEX_GRAPPLINGHOOK 17
#define MODELINDEX_SHELLS 18
#define MODELINDEX_BULLETS 19
#define MODELINDEX_GRENADES 20
#define MODELINDEX_CELLS 21
#define MODELINDEX_LIGHTNINGAMMO 22
#define MODELINDEX_ROCKETS 23
#define MODELINDEX_SLUGS 24
#define MODELINDEX_BFGAMMO 25
#define MODELINDEX_TELEPORTER 26
#define MODELINDEX_MEDKIT 27
#define MODELINDEX_QUAD 28
#define MODELINDEX_ENVIRONMENTSUIT 29
#define MODELINDEX_HASTE 30
#define MODELINDEX_INVISIBILITY 31
#define MODELINDEX_REGEN 32
#define MODELINDEX_FLIGHT 33
#define MODELINDEX_REDFLAG 34
#define MODELINDEX_BLUEFLAG 35

134
src/botai/match.h Normal file
View File

@@ -0,0 +1,134 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: match.h
// Function: match template defines
// Programmer: Mr Elusive (MrElusive@idsoftware.com)
// Last update: 1999-10-01
// Tab Size: 4 (real tabs)
//
//===========================================================================
//match template contexts
#define MTCONTEXT_ENTERGAME 2
#define MTCONTEXT_INITIALTEAMCHAT 4
#define MTCONTEXT_TIME 8
#define MTCONTEXT_TEAMMATE 16
#define MTCONTEXT_ADDRESSEE 32
#define MTCONTEXT_PATROLKEYAREA 64
#define MTCONTEXT_REPLYCHAT 128
#define MTCONTEXT_CTF 256
//message types
#define MSG_ENTERGAME 2 //enter game message
#define MSG_HELP 3 //help someone
#define MSG_ACCOMPANY 4 //accompany someone
#define MSG_DEFENDKEYAREA 5 //defend a key area
#define MSG_RUSHBASE 6 //everyone rush to base
#define MSG_GETFLAG 7 //get the enemy flag
#define MSG_STARTTEAMLEADERSHIP 8 //someone wants to become the team leader
#define MSG_STOPTEAMLEADERSHIP 9 //someone wants to stop being the team leader
#define MSG_WHOISTEAMLAEDER 10 //who is the team leader
#define MSG_WAIT 11 //wait for someone
#define MSG_WHATAREYOUDOING 12 //what are you doing?
#define MSG_JOINSUBTEAM 13 //join a sub-team
#define MSG_LEAVESUBTEAM 14 //leave a sub-team
#define MSG_CREATENEWFORMATION 15 //create a new formation
#define MSG_FORMATIONPOSITION 16 //tell someone his/her position in a formation
#define MSG_FORMATIONSPACE 17 //set the formation intervening space
#define MSG_DOFORMATION 18 //form a known formation
#define MSG_DISMISS 19 //dismiss commanded team mates
#define MSG_CAMP 20 //camp somewhere
#define MSG_CHECKPOINT 21 //remember a check point
#define MSG_PATROL 22 //patrol between certain keypoints
#define MSG_LEADTHEWAY 23 //lead the way
#define MSG_GETITEM 24 //get an item
#define MSG_KILL 25 //kill someone
#define MSG_WHEREAREYOU 26 //where is someone
#define MSG_RETURNFLAG 27 //return the flag
#define MSG_WHATISMYCOMMAND 28 //ask the team leader what to do
#define MSG_WHICHTEAM 29 //ask which team a bot is in
//
#define MSG_ME 100
#define MSG_EVERYONE 101
#define MSG_MULTIPLENAMES 102
#define MSG_NAME 103
#define MSG_PATROLKEYAREA 104
#define MSG_MINUTES 105
#define MSG_SECONDS 106
#define MSG_FOREVER 107
//
#define MSG_CHATALL 200
#define MSG_CHATTEAM 201
//
#define MSG_CTF 300 //ctf message
//command sub types
#define ST_SOMEWHERE 0
#define ST_NEARITEM 1
#define ST_ADDRESSED 2
#define ST_METER 4
#define ST_FEET 8
#define ST_TIME 16
#define ST_HERE 32
#define ST_THERE 64
#define ST_I 128
#define ST_MORE 256
#define ST_BACK 512
#define ST_REVERSE 1024
#define ST_SOMEONE 2048
#define ST_GOTFLAG 4096
#define ST_CAPTUREDFLAG 8192
#define ST_RETURNEDFLAG 16384
#define ST_TEAM 32768
//word replacement variables
#define THE_ENEMY 7
#define THE_TEAM 7
//team message variables
#define NETNAME 0
#define PLACE 1
#define FLAG 1
#define MESSAGE 2
#define ADDRESSEE 2
#define ITEM 3
#define TEAMMATE 4
#define TEAMNAME 4
#define ENEMY 4
#define KEYAREA 5
#define FORMATION 5
#define POSITION 5
#define NUMBER 5
#define TIME 6
#define NAME 6
#define MORE 6

46
src/botai/syn.h Normal file
View File

@@ -0,0 +1,46 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: syn.h
// Function: synonyms
// Programmer: Mr Elusive (MrElusive@idsoftware.com)
// Last update: 1999-09-08
// Tab Size: 4 (real tabs)
// Notes: -
//===========================================================================
#define CONTEXT_ALL 0xFFFFFFFF
#define CONTEXT_NORMAL 1
#define CONTEXT_NEARBYITEM 2
#define CONTEXT_CTFREDTEAM 4
#define CONTEXT_CTFBLUETEAM 8
#define CONTEXT_REPLY 16
#define CONTEXT_NAMES 1024

285
src/botlib/aasfile.h Normal file
View File

@@ -0,0 +1,285 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//NOTE: int = default signed
// default long
#define AASID ( ( 'S' << 24 ) + ( 'A' << 16 ) + ( 'A' << 8 ) + 'E' )
#define AASVERSION 8
//presence types
#define PRESENCE_NONE 1
#define PRESENCE_NORMAL 2
#define PRESENCE_CROUCH 4
//travel types
#define MAX_TRAVELTYPES 32
#define TRAVEL_INVALID 1 //temporary not possible
#define TRAVEL_WALK 2 //walking
#define TRAVEL_CROUCH 3 //crouching
#define TRAVEL_BARRIERJUMP 4 //jumping onto a barrier
#define TRAVEL_JUMP 5 //jumping
#define TRAVEL_LADDER 6 //climbing a ladder
#define TRAVEL_WALKOFFLEDGE 7 //walking of a ledge
#define TRAVEL_SWIM 8 //swimming
#define TRAVEL_WATERJUMP 9 //jump out of the water
#define TRAVEL_TELEPORT 10 //teleportation
#define TRAVEL_ELEVATOR 11 //travel by elevator
#define TRAVEL_ROCKETJUMP 12 //rocket jumping required for travel
#define TRAVEL_BFGJUMP 13 //bfg jumping required for travel
#define TRAVEL_GRAPPLEHOOK 14 //grappling hook required for travel
#define TRAVEL_DOUBLEJUMP 15 //double jump
#define TRAVEL_RAMPJUMP 16 //ramp jump
#define TRAVEL_STRAFEJUMP 17 //strafe jump
#define TRAVEL_JUMPPAD 18 //jump pad
#define TRAVEL_FUNCBOB 19 //func bob
//additional travel flags
#define TRAVELTYPE_MASK 0xFFFFFF
#define TRAVELFLAG_NOTTEAM1 ( 1 << 24 )
#define TRAVELFLAG_NOTTEAM2 ( 2 << 24 )
//face flags
#define FACE_SOLID 1 //just solid at the other side
#define FACE_LADDER 2 //ladder
#define FACE_GROUND 4 //standing on ground when in this face
#define FACE_GAP 8 //gap in the ground
#define FACE_LIQUID 16
#define FACE_LIQUIDSURFACE 32
//area contents
#define AREACONTENTS_WATER 1
#define AREACONTENTS_LAVA 2
#define AREACONTENTS_SLIME 4
#define AREACONTENTS_CLUSTERPORTAL 8
#define AREACONTENTS_TELEPORTAL 16
#define AREACONTENTS_ROUTEPORTAL 32
#define AREACONTENTS_TELEPORTER 64
#define AREACONTENTS_JUMPPAD 128
#define AREACONTENTS_DONOTENTER 256
#define AREACONTENTS_VIEWPORTAL 512
// Rafael - nopass
#define AREACONTENTS_DONOTENTER_LARGE 1024
#define AREACONTENTS_MOVER 2048
//number of model of the mover inside this area
#define AREACONTENTS_MODELNUMSHIFT 24
#define AREACONTENTS_MAXMODELNUM 0xFF
#define AREACONTENTS_MODELNUM ( AREACONTENTS_MAXMODELNUM << AREACONTENTS_MODELNUMSHIFT )
//area flags
#define AREA_GROUNDED 1 //bot can stand on the ground
#define AREA_LADDER 2 //area contains one or more ladder faces
#define AREA_LIQUID 4 //area contains a liquid
// Ridah
#define AREA_DISABLED 8
#define AREA_AVOID 16
#define AREA_TEAM_AXIS 32
#define AREA_TEAM_ALLIES 64
#define AREA_TEAM_AXIS_DISGUISED 128
#define AREA_TEAM_ALLIES_DISGUISED 256
#define AREA_USEFORROUTING 1024
#define AREA_AVOID_AXIS 2048 // death area
#define AREA_AVOID_ALLIES 4096 // death area
#define AREA_TEAM_FLAGS ( AREA_TEAM_AXIS | AREA_TEAM_ALLIES | AREA_TEAM_AXIS_DISGUISED | AREA_TEAM_ALLIES_DISGUISED | AREA_AVOID_AXIS | AREA_AVOID_ALLIES )
//aas file header lumps
#define AAS_LUMPS 14
#define AASLUMP_BBOXES 0
#define AASLUMP_VERTEXES 1
#define AASLUMP_PLANES 2
#define AASLUMP_EDGES 3
#define AASLUMP_EDGEINDEX 4
#define AASLUMP_FACES 5
#define AASLUMP_FACEINDEX 6
#define AASLUMP_AREAS 7
#define AASLUMP_AREASETTINGS 8
#define AASLUMP_REACHABILITY 9
#define AASLUMP_NODES 10
#define AASLUMP_PORTALS 11
#define AASLUMP_PORTALINDEX 12
#define AASLUMP_CLUSTERS 13
//========== bounding box =========
//bounding box
typedef struct aas_bbox_s
{
int presencetype;
int flags;
vec3_t mins, maxs;
} aas_bbox_t;
//============ settings ===========
//reachability to another area
typedef struct aas_reachability_s
{
int areanum; //number of the reachable area
int facenum; //number of the face towards the other area
int edgenum; //number of the edge towards the other area
vec3_t start; //start point of inter area movement
vec3_t end; //end point of inter area movement
int traveltype; //type of travel required to get to the area
unsigned short int traveltime; //travel time of the inter area movement
} aas_reachability_t;
//area settings
typedef struct aas_areasettings_s
{
//could also add all kind of statistic fields
int contents; //contents of the convex area
int areaflags; //several area flags
int presencetype; //how a bot can be present in this convex area
int cluster; //cluster the area belongs to, if negative it's a portal
int clusterareanum; //number of the area in the cluster
int numreachableareas; //number of reachable areas from this one
int firstreachablearea; //first reachable area in the reachable area index
// Ridah, add a ground steepness stat, so we can avoid terrain when we can take a close-by flat route
float groundsteepness; // 0 = flat, 1 = steep
} aas_areasettings_t;
//cluster portal
typedef struct aas_portal_s
{
int areanum; //area that is the actual portal
int frontcluster; //cluster at front of portal
int backcluster; //cluster at back of portal
int clusterareanum[2]; //number of the area in the front and back cluster
} aas_portal_t;
//cluster portal index
typedef int aas_portalindex_t;
//cluster
typedef struct aas_cluster_s
{
int numareas; //number of areas in the cluster
int numreachabilityareas; //number of areas with reachabilities
int numportals; //number of cluster portals
int firstportal; //first cluster portal in the index
} aas_cluster_t;
//============ 3d definition ============
typedef vec3_t aas_vertex_t;
//just a plane in the third dimension
typedef struct aas_plane_s
{
vec3_t normal; //normal vector of the plane
float dist; //distance of the plane (normal vector * distance = point in plane)
int type;
} aas_plane_t;
//edge
typedef struct aas_edge_s
{
int v[2]; //numbers of the vertexes of this edge
} aas_edge_t;
//edge index, negative if vertexes are reversed
typedef int aas_edgeindex_t;
//a face bounds a convex area, often it will also seperate two convex areas
typedef struct aas_face_s
{
int planenum; //number of the plane this face is in
int faceflags; //face flags (no use to create face settings for just this field)
int numedges; //number of edges in the boundary of the face
int firstedge; //first edge in the edge index
int frontarea; //convex area at the front of this face
int backarea; //convex area at the back of this face
} aas_face_t;
//face index, stores a negative index if backside of face
typedef int aas_faceindex_t;
//convex area with a boundary of faces
typedef struct aas_area_s
{
int areanum; //number of this area
//3d definition
int numfaces; //number of faces used for the boundary of the convex area
int firstface; //first face in the face index used for the boundary of the convex area
vec3_t mins; //mins of the convex area
vec3_t maxs; //maxs of the convex area
vec3_t center; //'center' of the convex area
} aas_area_t;
//nodes of the bsp tree
typedef struct aas_node_s
{
int planenum;
int children[2]; //child nodes of this node, or convex areas as leaves when negative
//when a child is zero it's a solid leaf
} aas_node_t;
//=========== aas file ===============
//header lump
typedef struct
{
int fileofs;
int filelen;
} aas_lump_t;
//aas file header
typedef struct aas_header_s
{
int ident;
int version;
int bspchecksum;
//data entries
aas_lump_t lumps[AAS_LUMPS];
} aas_header_t;
//====== additional information ======
/*
- when a node child is a solid leaf the node child number is zero
- two adjacent areas (sharing a plane at opposite sides) share a face
this face is a portal between the areas
- when an area uses a face from the faceindex with a positive index
then the face plane normal points into the area
- the face edges are stored counter clockwise using the edgeindex
- two adjacent convex areas (sharing a face) only share One face
this is a simple result of the areas being convex
- the convex areas can't have a mixture of ground and gap faces
other mixtures of faces in one area are allowed
- areas with the AREACONTENTS_CLUSTERPORTAL in the settings have
cluster number zero
- edge zero is a dummy
- face zero is a dummy
- area zero is a dummy
- node zero is a dummy
*/

95
src/botlib/be_aas_bsp.h Normal file
View File

@@ -0,0 +1,95 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_bsp.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
//loads the given BSP file
int AAS_LoadBSPFile( void );
//dump the loaded BSP data
void AAS_DumpBSPData( void );
//unlink the given entity from the bsp tree leaves
void AAS_UnlinkFromBSPLeaves( bsp_link_t *leaves );
//link the given entity to the bsp tree leaves of the given model
bsp_link_t *AAS_BSPLinkEntity( vec3_t absmins,
vec3_t absmaxs,
int entnum,
int modelnum );
//calculates collision with given entity
qboolean AAS_EntityCollision( int entnum,
vec3_t start,
vec3_t boxmins,
vec3_t boxmaxs,
vec3_t end,
int contentmask,
bsp_trace_t *trace );
//for debugging
void AAS_PrintFreeBSPLinks( char *str );
//
#endif //AASINTERN
#define MAX_EPAIRKEY 128
//trace through the world
bsp_trace_t AAS_Trace( vec3_t start,
vec3_t mins,
vec3_t maxs,
vec3_t end,
int passent,
int contentmask );
//returns the contents at the given point
int AAS_PointContents( vec3_t point );
//returns true when p2 is in the PVS of p1
qboolean AAS_inPVS( vec3_t p1, vec3_t p2 );
//returns true when p2 is in the PHS of p1
qboolean AAS_inPHS( vec3_t p1, vec3_t p2 );
//returns true if the given areas are connected
qboolean AAS_AreasConnected( int area1, int area2 );
//creates a list with entities totally or partly within the given box
int AAS_BoxEntities( vec3_t absmins, vec3_t absmaxs, int *list, int maxcount );
//gets the mins, maxs and origin of a BSP model
void AAS_BSPModelMinsMaxsOrigin( int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin );
//handle to the next bsp entity
int AAS_NextBSPEntity( int ent );
//return the value of the BSP epair key
int AAS_ValueForBSPEpairKey( int ent, char *key, char *value, int size );
//get a vector for the BSP epair key
int AAS_VectorForBSPEpairKey( int ent, char *key, vec3_t v );
//get a float for the BSP epair key
int AAS_FloatForBSPEpairKey( int ent, char *key, float *value );
//get an integer for the BSP epair key
int AAS_IntForBSPEpairKey( int ent, char *key, int *value );

529
src/botlib/be_aas_bspq3.c Normal file
View File

@@ -0,0 +1,529 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_bspq3.c
*
* desc: BSP, Environment Sampling
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_aas_def.h"
extern botlib_import_t botimport;
//#define TRACE_DEBUG
#define ON_EPSILON 0.005
//#define DEG2RAD( a ) (( a * M_PI ) / 180.0F)
#define MAX_BSPENTITIES 4096
typedef struct rgb_s
{
int red;
int green;
int blue;
} rgb_t;
//bsp entity epair
typedef struct bsp_epair_s
{
char *key;
char *value;
struct bsp_epair_s *next;
} bsp_epair_t;
//bsp data entity
typedef struct bsp_entity_s
{
bsp_epair_t *epairs;
} bsp_entity_t;
//id Sofware BSP data
typedef struct bsp_s
{
//true when bsp file is loaded
int loaded;
//entity data
int entdatasize;
char *dentdata;
//bsp entities
int numentities;
bsp_entity_t entities[MAX_BSPENTITIES];
//memory used for strings and epairs
byte *ebuffer;
} bsp_t;
//global bsp
bsp_t bspworld;
#ifdef BSP_DEBUG
typedef struct cname_s
{
int value;
char *name;
} cname_t;
cname_t contentnames[] =
{
{CONTENTS_SOLID,"CONTENTS_SOLID"},
{CONTENTS_WINDOW,"CONTENTS_WINDOW"},
{CONTENTS_AUX,"CONTENTS_AUX"},
{CONTENTS_LAVA,"CONTENTS_LAVA"},
{CONTENTS_SLIME,"CONTENTS_SLIME"},
{CONTENTS_WATER,"CONTENTS_WATER"},
{CONTENTS_MIST,"CONTENTS_MIST"},
{LAST_VISIBLE_CONTENTS,"LAST_VISIBLE_CONTENTS"},
{CONTENTS_AREAPORTAL,"CONTENTS_AREAPORTAL"},
{CONTENTS_PLAYERCLIP,"CONTENTS_PLAYERCLIP"},
{CONTENTS_MONSTERCLIP,"CONTENTS_MONSTERCLIP"},
{CONTENTS_CURRENT_0,"CONTENTS_CURRENT_0"},
{CONTENTS_CURRENT_90,"CONTENTS_CURRENT_90"},
{CONTENTS_CURRENT_180,"CONTENTS_CURRENT_180"},
{CONTENTS_CURRENT_270,"CONTENTS_CURRENT_270"},
{CONTENTS_CURRENT_UP,"CONTENTS_CURRENT_UP"},
{CONTENTS_CURRENT_DOWN,"CONTENTS_CURRENT_DOWN"},
{CONTENTS_ORIGIN,"CONTENTS_ORIGIN"},
{CONTENTS_MONSTER,"CONTENTS_MONSTER"},
{CONTENTS_DEADMONSTER,"CONTENTS_DEADMONSTER"},
{CONTENTS_DETAIL,"CONTENTS_DETAIL"},
{CONTENTS_TRANSLUCENT,"CONTENTS_TRANSLUCENT"},
{CONTENTS_LADDER,"CONTENTS_LADDER"},
{0, 0}
};
void PrintContents( int contents ) {
int i;
for ( i = 0; contentnames[i].value; i++ )
{
if ( contents & contentnames[i].value ) {
botimport.Print( PRT_MESSAGE, "%s\n", contentnames[i].name );
} //end if
} //end for
} //end of the function PrintContents
#endif //BSP_DEBUG
//===========================================================================
// traces axial boxes of any size through the world
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bsp_trace_t AAS_Trace( vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask ) {
bsp_trace_t bsptrace;
botimport.Trace( &bsptrace, start, mins, maxs, end, passent, contentmask );
return bsptrace;
} //end of the function AAS_Trace
//===========================================================================
// returns the contents at the given point
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_PointContents( vec3_t point ) {
return botimport.PointContents( point );
} //end of the function AAS_PointContents
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_EntityCollision( int entnum,
vec3_t start, vec3_t boxmins, vec3_t boxmaxs, vec3_t end,
int contentmask, bsp_trace_t *trace ) {
bsp_trace_t enttrace;
botimport.EntityTrace( &enttrace, start, boxmins, boxmaxs, end, entnum, contentmask );
if ( enttrace.fraction < trace->fraction ) {
memcpy( trace, &enttrace, sizeof( bsp_trace_t ) );
return qtrue;
} //end if
return qfalse;
} //end of the function AAS_EntityCollision
//===========================================================================
// returns true if in Potentially Hearable Set
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_inPVS( vec3_t p1, vec3_t p2 ) {
return botimport.inPVS( p1, p2 );
} //end of the function AAS_InPVS
//===========================================================================
// returns true if in Potentially Visible Set
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_inPHS( vec3_t p1, vec3_t p2 ) {
return qtrue;
} //end of the function AAS_inPHS
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_BSPModelMinsMaxsOrigin( int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin ) {
botimport.BSPModelMinsMaxsOrigin( modelnum, angles, mins, maxs, origin );
} //end of the function AAS_BSPModelMinsMaxs
//===========================================================================
// unlinks the entity from all leaves
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UnlinkFromBSPLeaves( bsp_link_t *leaves ) {
} //end of the function AAS_UnlinkFromBSPLeaves
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bsp_link_t *AAS_BSPLinkEntity( vec3_t absmins, vec3_t absmaxs, int entnum, int modelnum ) {
return NULL;
} //end of the function AAS_BSPLinkEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BoxEntities( vec3_t absmins, vec3_t absmaxs, int *list, int maxcount ) {
return 0;
} //end of the function AAS_BoxEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_NextBSPEntity( int ent ) {
ent++;
if ( ent >= 1 && ent < bspworld.numentities ) {
return ent;
}
return 0;
} //end of the function AAS_NextBSPEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BSPEntityInRange( int ent ) {
if ( ent <= 0 || ent >= bspworld.numentities ) {
botimport.Print( PRT_MESSAGE, "bsp entity out of range\n" );
return qfalse;
} //end if
return qtrue;
} //end of the function AAS_BSPEntityInRange
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_ValueForBSPEpairKey( int ent, char *key, char *value, int size ) {
bsp_epair_t *epair;
value[0] = '\0';
if ( !AAS_BSPEntityInRange( ent ) ) {
return qfalse;
}
for ( epair = bspworld.entities[ent].epairs; epair; epair = epair->next )
{
if ( !strcmp( epair->key, key ) ) {
strncpy( value, epair->value, size - 1 );
value[size - 1] = '\0';
return qtrue;
} //end if
} //end for
return qfalse;
} //end of the function AAS_FindBSPEpair
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_VectorForBSPEpairKey( int ent, char *key, vec3_t v ) {
char buf[MAX_EPAIRKEY];
double v1, v2, v3;
VectorClear( v );
if ( !AAS_ValueForBSPEpairKey( ent, key, buf, MAX_EPAIRKEY ) ) {
return qfalse;
}
//scanf into doubles, then assign, so it is vec_t size independent
v1 = v2 = v3 = 0;
sscanf( buf, "%lf %lf %lf", &v1, &v2, &v3 );
v[0] = v1;
v[1] = v2;
v[2] = v3;
return qtrue;
} //end of the function AAS_VectorForBSPEpairKey
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_FloatForBSPEpairKey( int ent, char *key, float *value ) {
char buf[MAX_EPAIRKEY];
*value = 0;
if ( !AAS_ValueForBSPEpairKey( ent, key, buf, MAX_EPAIRKEY ) ) {
return qfalse;
}
*value = atof( buf );
return qtrue;
} //end of the function AAS_FloatForBSPEpairKey
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_IntForBSPEpairKey( int ent, char *key, int *value ) {
char buf[MAX_EPAIRKEY];
*value = 0;
if ( !AAS_ValueForBSPEpairKey( ent, key, buf, MAX_EPAIRKEY ) ) {
return qfalse;
}
*value = atoi( buf );
return qtrue;
} //end of the function AAS_IntForBSPEpairKey
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_FreeBSPEntities( void ) {
// RF, optimized memory allocation
/*
int i;
bsp_entity_t *ent;
bsp_epair_t *epair, *nextepair;
for (i = 1; i < bspworld.numentities; i++)
{
ent = &bspworld.entities[i];
for (epair = ent->epairs; epair; epair = nextepair)
{
nextepair = epair->next;
//
if (epair->key) FreeMemory(epair->key);
if (epair->value) FreeMemory(epair->value);
FreeMemory(epair);
} //end for
} //end for
*/
if ( bspworld.ebuffer ) {
FreeMemory( bspworld.ebuffer );
}
bspworld.numentities = 0;
} //end of the function AAS_FreeBSPEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ParseBSPEntities( void ) {
script_t *script;
token_t token;
bsp_entity_t *ent;
bsp_epair_t *epair;
byte *buffer, *buftrav;
int bufsize;
// RF, modified this, so that it first gathers up memory requirements, then allocates a single chunk,
// and places the strings all in there
bspworld.ebuffer = NULL;
script = LoadScriptMemory( bspworld.dentdata, bspworld.entdatasize, "entdata" );
SetScriptFlags( script, SCFL_NOSTRINGWHITESPACES | SCFL_NOSTRINGESCAPECHARS ); //SCFL_PRIMITIVE);
bufsize = 0;
while ( PS_ReadToken( script, &token ) )
{
if ( strcmp( token.string, "{" ) ) {
ScriptError( script, "invalid %s\n", token.string );
AAS_FreeBSPEntities();
FreeScript( script );
return;
} //end if
if ( bspworld.numentities >= MAX_BSPENTITIES ) {
botimport.Print( PRT_MESSAGE, "too many entities in BSP file\n" );
break;
} //end if
while ( PS_ReadToken( script, &token ) )
{
if ( !strcmp( token.string, "}" ) ) {
break;
}
bufsize += sizeof( bsp_epair_t );
if ( token.type != TT_STRING ) {
ScriptError( script, "invalid %s\n", token.string );
AAS_FreeBSPEntities();
FreeScript( script );
return;
} //end if
StripDoubleQuotes( token.string );
bufsize += strlen( token.string ) + 1;
if ( !PS_ExpectTokenType( script, TT_STRING, 0, &token ) ) {
AAS_FreeBSPEntities();
FreeScript( script );
return;
} //end if
StripDoubleQuotes( token.string );
bufsize += strlen( token.string ) + 1;
} //end while
if ( strcmp( token.string, "}" ) ) {
ScriptError( script, "missing }\n" );
AAS_FreeBSPEntities();
FreeScript( script );
return;
} //end if
} //end while
FreeScript( script );
buffer = (byte *)GetClearedHunkMemory( bufsize );
buftrav = buffer;
bspworld.ebuffer = buffer;
// RF, now parse the entities into memory
// RF, NOTE: removed error checks for speed, no need to do them twice
script = LoadScriptMemory( bspworld.dentdata, bspworld.entdatasize, "entdata" );
SetScriptFlags( script, SCFL_NOSTRINGWHITESPACES | SCFL_NOSTRINGESCAPECHARS ); //SCFL_PRIMITIVE);
bspworld.numentities = 1;
while ( PS_ReadToken( script, &token ) )
{
ent = &bspworld.entities[bspworld.numentities];
bspworld.numentities++;
ent->epairs = NULL;
while ( PS_ReadToken( script, &token ) )
{
if ( !strcmp( token.string, "}" ) ) {
break;
}
epair = (bsp_epair_t *) buftrav; buftrav += sizeof( bsp_epair_t );
epair->next = ent->epairs;
ent->epairs = epair;
StripDoubleQuotes( token.string );
epair->key = (char *) buftrav; buftrav += ( strlen( token.string ) + 1 );
strcpy( epair->key, token.string );
if ( !PS_ExpectTokenType( script, TT_STRING, 0, &token ) ) {
AAS_FreeBSPEntities();
FreeScript( script );
return;
} //end if
StripDoubleQuotes( token.string );
epair->value = (char *) buftrav; buftrav += ( strlen( token.string ) + 1 );
strcpy( epair->value, token.string );
} //end while
} //end while
FreeScript( script );
} //end of the function AAS_ParseBSPEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BSPTraceLight( vec3_t start, vec3_t end, vec3_t endpos, int *red, int *green, int *blue ) {
return 0;
} //end of the function AAS_BSPTraceLight
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DumpBSPData( void ) {
AAS_FreeBSPEntities();
if ( bspworld.dentdata ) {
FreeMemory( bspworld.dentdata );
}
bspworld.dentdata = NULL;
bspworld.entdatasize = 0;
//
bspworld.loaded = qfalse;
memset( &bspworld, 0, sizeof( bspworld ) );
} //end of the function AAS_DumpBSPData
//===========================================================================
// load an bsp file
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_LoadBSPFile( void ) {
AAS_DumpBSPData();
bspworld.entdatasize = strlen( botimport.BSPEntityData() ) + 1;
bspworld.dentdata = (char *) GetClearedHunkMemory( bspworld.entdatasize );
memcpy( bspworld.dentdata, botimport.BSPEntityData(), bspworld.entdatasize );
AAS_ParseBSPEntities();
bspworld.loaded = qtrue;
return BLERR_NOERROR;
} //end of the function AAS_LoadBSPFile
void AAS_InitBSP( void ) {
memset( &bspworld, 0, sizeof( bspworld ) );
}

1611
src/botlib/be_aas_cluster.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_cluster.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
//initialize the AAS clustering
void AAS_InitClustering( void );
#endif //AASINTERN

688
src/botlib/be_aas_debug.c Normal file
View File

@@ -0,0 +1,688 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_debug.c
*
* desc: AAS debug code
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_libvar.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_interface.h"
#include "be_aas_funcs.h"
#include "be_aas_def.h"
#define MAX_DEBUGLINES 1024
int debuglines[MAX_DEBUGLINES];
int debuglinevisible[MAX_DEBUGLINES];
int numdebuglines;
static bot_debugpoly_t* debugpolygons[MAX_DEBUGPOLYS];
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ClearShownPolygons( void ) {
int i;
for ( i = 0; i < MAX_DEBUGPOLYS; i++ ) {
if ( debugpolygons[i] ) {
botimport.DebugPolygonDeletePointer( debugpolygons[i] );
}
debugpolygons[i] = NULL;
}
} //end of the function AAS_ClearShownPolygons
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_debugpoly_t* AAS_GetDebugPolygon( void ) {
int i;
for ( i = 0; i < MAX_DEBUGPOLYS; i++ ) {
if ( !debugpolygons[i] ) {
debugpolygons[i] = botimport.DebugPolygonGetFree();
return debugpolygons[i];
}
}
return NULL;
} //end of the function AAS_GetDebugPolygon
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ClearShownDebugLines( void ) {
int i;
//make all lines invisible
for ( i = 0; i < MAX_DEBUGLINES; i++ )
{
if ( debuglines[i] ) {
//botimport.DebugLineShow(debuglines[i], NULL, NULL, LINECOLOR_NONE);
botimport.DebugLineDelete( debuglines[i] );
debuglines[i] = 0;
debuglinevisible[i] = qfalse;
} //end if
} //end for
} //end of the function AAS_ClearShownDebugLines
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DebugLine( vec3_t start, vec3_t end, int color ) {
int line;
for ( line = 0; line < MAX_DEBUGLINES; line++ )
{
if ( !debuglines[line] ) {
debuglines[line] = botimport.DebugLineCreate();
debuglinevisible[line] = qfalse;
numdebuglines++;
} //end if
if ( !debuglinevisible[line] ) {
botimport.DebugLineShow( debuglines[line], start, end, color );
debuglinevisible[line] = qtrue;
return;
} //end else
} //end for
} //end of the function AAS_DebugLine
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_PermanentLine( vec3_t start, vec3_t end, int color ) {
int line;
line = botimport.DebugLineCreate();
botimport.DebugLineShow( line, start, end, color );
} //end of the function AAS_PermenentLine
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DrawPermanentCross( vec3_t origin, float size, int color ) {
int i, debugline;
vec3_t start, end;
for ( i = 0; i < 3; i++ )
{
VectorCopy( origin, start );
start[i] += size;
VectorCopy( origin, end );
end[i] -= size;
AAS_DebugLine( start, end, color );
debugline = botimport.DebugLineCreate();
botimport.DebugLineShow( debugline, start, end, color );
} //end for
} //end of the function AAS_DrawPermanentCross
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DrawPlaneCross( vec3_t point, vec3_t normal, float dist, int type, int color ) {
int n0, n1, n2, j, line, lines[2];
vec3_t start1, end1, start2, end2;
//make a cross in the hit plane at the hit point
VectorCopy( point, start1 );
VectorCopy( point, end1 );
VectorCopy( point, start2 );
VectorCopy( point, end2 );
n0 = type % 3;
n1 = ( type + 1 ) % 3;
n2 = ( type + 2 ) % 3;
start1[n1] -= 6;
start1[n2] -= 6;
end1[n1] += 6;
end1[n2] += 6;
start2[n1] += 6;
start2[n2] -= 6;
end2[n1] -= 6;
end2[n2] += 6;
start1[n0] = ( dist - ( start1[n1] * normal[n1] +
start1[n2] * normal[n2] ) ) / normal[n0];
end1[n0] = ( dist - ( end1[n1] * normal[n1] +
end1[n2] * normal[n2] ) ) / normal[n0];
start2[n0] = ( dist - ( start2[n1] * normal[n1] +
start2[n2] * normal[n2] ) ) / normal[n0];
end2[n0] = ( dist - ( end2[n1] * normal[n1] +
end2[n2] * normal[n2] ) ) / normal[n0];
for ( j = 0, line = 0; j < 2 && line < MAX_DEBUGLINES; line++ )
{
if ( !debuglines[line] ) {
debuglines[line] = botimport.DebugLineCreate();
lines[j++] = debuglines[line];
debuglinevisible[line] = qtrue;
numdebuglines++;
} //end if
else if ( !debuglinevisible[line] ) {
lines[j++] = debuglines[line];
debuglinevisible[line] = qtrue;
} //end else
} //end for
botimport.DebugLineShow( lines[0], start1, end1, color );
botimport.DebugLineShow( lines[1], start2, end2, color );
} //end of the function AAS_DrawPlaneCross
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShowBoundingBox( vec3_t origin, vec3_t mins, vec3_t maxs ) {
vec3_t bboxcorners[8];
int lines[3];
int i, j, line;
//upper corners
bboxcorners[0][0] = origin[0] + maxs[0];
bboxcorners[0][1] = origin[1] + maxs[1];
bboxcorners[0][2] = origin[2] + maxs[2];
//
bboxcorners[1][0] = origin[0] + mins[0];
bboxcorners[1][1] = origin[1] + maxs[1];
bboxcorners[1][2] = origin[2] + maxs[2];
//
bboxcorners[2][0] = origin[0] + mins[0];
bboxcorners[2][1] = origin[1] + mins[1];
bboxcorners[2][2] = origin[2] + maxs[2];
//
bboxcorners[3][0] = origin[0] + maxs[0];
bboxcorners[3][1] = origin[1] + mins[1];
bboxcorners[3][2] = origin[2] + maxs[2];
//lower corners
memcpy( bboxcorners[4], bboxcorners[0], sizeof( vec3_t ) * 4 );
for ( i = 0; i < 4; i++ ) bboxcorners[4 + i][2] = origin[2] + mins[2];
//draw bounding box
for ( i = 0; i < 4; i++ )
{
for ( j = 0, line = 0; j < 3 && line < MAX_DEBUGLINES; line++ )
{
if ( !debuglines[line] ) {
debuglines[line] = botimport.DebugLineCreate();
lines[j++] = debuglines[line];
debuglinevisible[line] = qtrue;
numdebuglines++;
} //end if
else if ( !debuglinevisible[line] ) {
lines[j++] = debuglines[line];
debuglinevisible[line] = qtrue;
} //end else
} //end for
//top plane
botimport.DebugLineShow( lines[0], bboxcorners[i],
bboxcorners[( i + 1 ) & 3], LINECOLOR_RED );
//bottom plane
botimport.DebugLineShow( lines[1], bboxcorners[4 + i],
bboxcorners[4 + ( ( i + 1 ) & 3 )], LINECOLOR_RED );
//vertical lines
botimport.DebugLineShow( lines[2], bboxcorners[i],
bboxcorners[4 + i], LINECOLOR_RED );
} //end for
} //end of the function AAS_ShowBoundingBox
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShowFace( int facenum ) {
int i, color, edgenum;
aas_edge_t *edge;
aas_face_t *face;
aas_plane_t *plane;
vec3_t start, end;
color = LINECOLOR_YELLOW;
//check if face number is in range
if ( facenum >= ( *aasworld ).numfaces ) {
botimport.Print( PRT_ERROR, "facenum %d out of range\n", facenum );
} //end if
face = &( *aasworld ).faces[facenum];
//walk through the edges of the face
for ( i = 0; i < face->numedges; i++ )
{
//edge number
edgenum = abs( ( *aasworld ).edgeindex[face->firstedge + i] );
//check if edge number is in range
if ( edgenum >= ( *aasworld ).numedges ) {
botimport.Print( PRT_ERROR, "edgenum %d out of range\n", edgenum );
} //end if
edge = &( *aasworld ).edges[edgenum];
if ( color == LINECOLOR_RED ) {
color = LINECOLOR_GREEN;
} else if ( color == LINECOLOR_GREEN ) {
color = LINECOLOR_BLUE;
} else if ( color == LINECOLOR_BLUE ) {
color = LINECOLOR_YELLOW;
} else { color = LINECOLOR_RED;}
AAS_DebugLine( ( *aasworld ).vertexes[edge->v[0]],
( *aasworld ).vertexes[edge->v[1]],
color );
} //end for
plane = &( *aasworld ).planes[face->planenum];
edgenum = abs( ( *aasworld ).edgeindex[face->firstedge] );
edge = &( *aasworld ).edges[edgenum];
VectorCopy( ( *aasworld ).vertexes[edge->v[0]], start );
VectorMA( start, 20, plane->normal, end );
AAS_DebugLine( start, end, LINECOLOR_RED );
} //end of the function AAS_ShowFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShowFacePolygon( int facenum, int color, int flip ) {
int i, edgenum;
aas_edge_t *edge;
aas_face_t *face;
vec3_t points[128];
int numpoints = 0;
//check if face number is in range
if ( facenum >= aasworld->numfaces ) {
botimport.Print( PRT_ERROR, "facenum %d out of range\n", facenum );
}
//walk through the edges of the face
face = &( aasworld->faces[facenum] );
if ( flip ) {
for ( i = face->numedges - 1; i >= 0; i-- ) {
edgenum = aasworld->edgeindex[face->firstedge + i];
edge = &( aasworld->edges[abs( edgenum )] );
VectorCopy( aasworld->vertexes[edge->v[edgenum < 0]], points[numpoints] );
numpoints++;
} //end for
} else {
for ( i = 0; i < face->numedges; i++ ) {
edgenum = aasworld->edgeindex[face->firstedge + i];
edge = &( aasworld->edges[abs( edgenum )] );
VectorCopy( aasworld->vertexes[edge->v[edgenum < 0]], points[numpoints] );
numpoints++;
}
}
botimport.BotDrawPolygon( color, numpoints, (float*) points );
} //end of the function AAS_ShowFacePolygon
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShowArea( int areanum, int groundfacesonly ) {
int areaedges[MAX_DEBUGLINES];
int numareaedges, i, j, n, color = 0, line;
int facenum, edgenum;
aas_area_t *area;
aas_face_t *face;
aas_edge_t *edge;
//
numareaedges = 0;
//
if ( areanum < 0 || areanum >= ( *aasworld ).numareas ) {
botimport.Print( PRT_ERROR, "area %d out of range [0, %d]\n",
areanum, ( *aasworld ).numareas );
return;
} //end if
//pointer to the convex area
area = &( *aasworld ).areas[areanum];
//walk through the faces of the area
for ( i = 0; i < area->numfaces; i++ )
{
facenum = abs( ( *aasworld ).faceindex[area->firstface + i] );
//check if face number is in range
if ( facenum >= ( *aasworld ).numfaces ) {
botimport.Print( PRT_ERROR, "facenum %d out of range\n", facenum );
} //end if
face = &( *aasworld ).faces[facenum];
//ground faces only
if ( groundfacesonly ) {
if ( !( face->faceflags & ( FACE_GROUND | FACE_LADDER ) ) ) {
continue;
}
} //end if
//walk through the edges of the face
for ( j = 0; j < face->numedges; j++ )
{
//edge number
edgenum = abs( ( *aasworld ).edgeindex[face->firstedge + j] );
//check if edge number is in range
if ( edgenum >= ( *aasworld ).numedges ) {
botimport.Print( PRT_ERROR, "edgenum %d out of range\n", edgenum );
} //end if
//check if the edge is stored already
for ( n = 0; n < numareaedges; n++ )
{
if ( areaedges[n] == edgenum ) {
break;
}
} //end for
if ( n == numareaedges && numareaedges < MAX_DEBUGLINES ) {
areaedges[numareaedges++] = edgenum;
} //end if
} //end for
//AAS_ShowFace(facenum);
} //end for
//draw all the edges
for ( n = 0; n < numareaedges; n++ )
{
for ( line = 0; line < MAX_DEBUGLINES; line++ )
{
if ( !debuglines[line] ) {
debuglines[line] = botimport.DebugLineCreate();
debuglinevisible[line] = qfalse;
numdebuglines++;
} //end if
if ( !debuglinevisible[line] ) {
break;
} //end else
} //end for
if ( line >= MAX_DEBUGLINES ) {
return;
}
edge = &( *aasworld ).edges[areaedges[n]];
if ( color == LINECOLOR_RED ) {
color = LINECOLOR_BLUE;
} else if ( color == LINECOLOR_BLUE ) {
color = LINECOLOR_GREEN;
} else if ( color == LINECOLOR_GREEN ) {
color = LINECOLOR_YELLOW;
} else { color = LINECOLOR_RED;}
botimport.DebugLineShow( debuglines[line],
( *aasworld ).vertexes[edge->v[0]],
( *aasworld ).vertexes[edge->v[1]],
color );
debuglinevisible[line] = qtrue;
} //end for*/
} //end of the function AAS_ShowArea
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShowAreaPolygons( int areanum, int color, int groundfacesonly ) {
int i, facenum;
aas_area_t *area;
aas_face_t *face;
if ( areanum < 0 || areanum >= aasworld->numareas ) {
botimport.Print( PRT_ERROR, "area %d out of range [0, %d]\n", areanum, aasworld->numareas );
return;
}
//pointer to the convex area
area = &( aasworld->areas[areanum] );
//walk through the faces of the area
for ( i = 0; i < area->numfaces; i++ ) {
facenum = abs( aasworld->faceindex[area->firstface + i] );
//check if face number is in range
if ( facenum >= aasworld->numfaces ) {
botimport.Print( PRT_ERROR, "facenum %d out of range\n", facenum );
}
face = &( aasworld->faces[facenum] );
//ground faces only
if ( groundfacesonly ) {
if ( !( face->faceflags & ( FACE_GROUND | FACE_LADDER ) ) ) {
continue;
}
}
AAS_ShowFacePolygon( facenum, color, face->frontarea != areanum );
}
} //end of the function AAS_ShowAreaPolygons
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DrawCross( vec3_t origin, float size, int color ) {
int i;
vec3_t start, end;
for ( i = 0; i < 3; i++ )
{
VectorCopy( origin, start );
start[i] += size;
VectorCopy( origin, end );
end[i] -= size;
AAS_DebugLine( start, end, color );
} //end for
} //end of the function AAS_DrawCross
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_PrintTravelType( int traveltype ) {
#ifdef DEBUG
char *str;
//
switch ( traveltype )
{
case TRAVEL_INVALID: str = "TRAVEL_INVALID"; break;
case TRAVEL_WALK: str = "TRAVEL_WALK"; break;
case TRAVEL_CROUCH: str = "TRAVEL_CROUCH"; break;
case TRAVEL_BARRIERJUMP: str = "TRAVEL_BARRIERJUMP"; break;
case TRAVEL_JUMP: str = "TRAVEL_JUMP"; break;
case TRAVEL_LADDER: str = "TRAVEL_LADDER"; break;
case TRAVEL_WALKOFFLEDGE: str = "TRAVEL_WALKOFFLEDGE"; break;
case TRAVEL_SWIM: str = "TRAVEL_SWIM"; break;
case TRAVEL_WATERJUMP: str = "TRAVEL_WATERJUMP"; break;
case TRAVEL_TELEPORT: str = "TRAVEL_TELEPORT"; break;
case TRAVEL_ELEVATOR: str = "TRAVEL_ELEVATOR"; break;
case TRAVEL_ROCKETJUMP: str = "TRAVEL_ROCKETJUMP"; break;
case TRAVEL_BFGJUMP: str = "TRAVEL_BFGJUMP"; break;
case TRAVEL_GRAPPLEHOOK: str = "TRAVEL_GRAPPLEHOOK"; break;
case TRAVEL_JUMPPAD: str = "TRAVEL_JUMPPAD"; break;
case TRAVEL_FUNCBOB: str = "TRAVEL_FUNCBOB"; break;
default: str = "UNKNOWN TRAVEL TYPE"; break;
} //end switch
botimport.Print( PRT_MESSAGE, "%s", str );
#endif //DEBUG
} //end of the function AAS_PrintTravelType
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DrawArrow( vec3_t start, vec3_t end, int linecolor, int arrowcolor ) {
vec3_t dir, cross, p1, p2, up = {0, 0, 1};
float dot;
VectorSubtract( end, start, dir );
VectorNormalize( dir );
dot = DotProduct( dir, up );
if ( dot > 0.99 || dot < -0.99 ) {
VectorSet( cross, 1, 0, 0 );
} else { CrossProduct( dir, up, cross );}
VectorMA( end, -6, dir, p1 );
VectorCopy( p1, p2 );
VectorMA( p1, 6, cross, p1 );
VectorMA( p2, -6, cross, p2 );
AAS_DebugLine( start, end, linecolor );
AAS_DebugLine( p1, end, arrowcolor );
AAS_DebugLine( p2, end, arrowcolor );
} //end of the function AAS_DrawArrow
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShowReachability( aas_reachability_t *reach ) {
vec3_t dir, cmdmove, velocity;
float speed, zvel;
aas_clientmove_t move;
AAS_ShowAreaPolygons( reach->areanum, 5, qtrue );
//AAS_ShowArea(reach->areanum, qtrue);
AAS_DrawArrow( reach->start, reach->end, LINECOLOR_BLUE, LINECOLOR_YELLOW );
//
if ( reach->traveltype == TRAVEL_JUMP || reach->traveltype == TRAVEL_WALKOFFLEDGE ) {
AAS_HorizontalVelocityForJump( aassettings.sv_jumpvel, reach->start, reach->end, &speed );
//
VectorSubtract( reach->end, reach->start, dir );
dir[2] = 0;
VectorNormalize( dir );
//set the velocity
VectorScale( dir, speed, velocity );
//set the command movement
VectorClear( cmdmove );
cmdmove[2] = aassettings.sv_jumpvel;
//
AAS_PredictClientMovement( &move, -1, reach->start, PRESENCE_NORMAL, qtrue,
velocity, cmdmove, 3, 30, 0.1,
SE_HITGROUND | SE_ENTERWATER | SE_ENTERSLIME |
SE_ENTERLAVA | SE_HITGROUNDDAMAGE, 0, qtrue );
//
if ( reach->traveltype == TRAVEL_JUMP ) {
AAS_JumpReachRunStart( reach, dir );
AAS_DrawCross( dir, 4, LINECOLOR_BLUE );
} //end if
} //end if
else if ( reach->traveltype == TRAVEL_ROCKETJUMP ) {
zvel = AAS_RocketJumpZVelocity( reach->start );
AAS_HorizontalVelocityForJump( zvel, reach->start, reach->end, &speed );
//
VectorSubtract( reach->end, reach->start, dir );
dir[2] = 0;
VectorNormalize( dir );
//get command movement
VectorScale( dir, speed, cmdmove );
VectorSet( velocity, 0, 0, zvel );
//
AAS_PredictClientMovement( &move, -1, reach->start, PRESENCE_NORMAL, qtrue,
velocity, cmdmove, 30, 30, 0.1,
SE_ENTERWATER | SE_ENTERSLIME |
SE_ENTERLAVA | SE_HITGROUNDDAMAGE |
SE_TOUCHJUMPPAD | SE_HITGROUNDAREA, reach->areanum, qtrue );
} //end else if
else if ( reach->traveltype == TRAVEL_JUMPPAD ) {
VectorSet( cmdmove, 0, 0, 0 );
//
VectorSubtract( reach->end, reach->start, dir );
dir[2] = 0;
VectorNormalize( dir );
//set the velocity
//NOTE: the edgenum is the horizontal velocity
VectorScale( dir, reach->edgenum, velocity );
//NOTE: the facenum is the Z velocity
velocity[2] = reach->facenum;
//
AAS_PredictClientMovement( &move, -1, reach->start, PRESENCE_NORMAL, qtrue,
velocity, cmdmove, 30, 30, 0.1,
SE_ENTERWATER | SE_ENTERSLIME |
SE_ENTERLAVA | SE_HITGROUNDDAMAGE |
SE_TOUCHJUMPPAD | SE_HITGROUNDAREA, reach->areanum, qtrue );
} //end else if
} //end of the function AAS_ShowReachability
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShowReachableAreas( int areanum ) {
aas_areasettings_t *settings;
static aas_reachability_t reach;
static int index, lastareanum;
static float lasttime;
if ( areanum != lastareanum ) {
index = 0;
lastareanum = areanum;
} //end if
settings = &( *aasworld ).areasettings[areanum];
//
if ( !settings->numreachableareas ) {
return;
}
//
if ( index >= settings->numreachableareas ) {
index = 0;
}
//
if ( AAS_Time() - lasttime > 1.5 ) {
memcpy( &reach, &( *aasworld ).reachability[settings->firstreachablearea + index], sizeof( aas_reachability_t ) );
index++;
lasttime = AAS_Time();
AAS_PrintTravelType( reach.traveltype );
botimport.Print( PRT_MESSAGE, "(traveltime: %i)\n", reach.traveltime );
} //end if
AAS_ShowReachability( &reach );
} //end of the function ShowReachableAreas

68
src/botlib/be_aas_debug.h Normal file
View File

@@ -0,0 +1,68 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_debug.h
*
* desc: AAS
*
*
*****************************************************************************/
//clear the shown debug lines
void AAS_ClearShownDebugLines( void );
//
void AAS_ClearShownPolygons( void );
//show a debug line
void AAS_DebugLine( vec3_t start, vec3_t end, int color );
//show a permenent line
void AAS_PermanentLine( vec3_t start, vec3_t end, int color );
//show a permanent cross
void AAS_DrawPermanentCross( vec3_t origin, float size, int color );
//draw a cross in the plane
void AAS_DrawPlaneCross( vec3_t point, vec3_t normal, float dist, int type, int color );
//show a bounding box
void AAS_ShowBoundingBox( vec3_t origin, vec3_t mins, vec3_t maxs );
//show a face
void AAS_ShowFace( int facenum );
//show an area
void AAS_ShowArea( int areanum, int groundfacesonly );
//
void AAS_ShowAreaPolygons( int areanum, int color, int groundfacesonly );
//draw a cros
void AAS_DrawCross( vec3_t origin, float size, int color );
//print the travel type
void AAS_PrintTravelType( int traveltype );
//draw an arrow
void AAS_DrawArrow( vec3_t start, vec3_t end, int linecolor, int arrowcolor );
//visualize the given reachability
void AAS_ShowReachability( struct aas_reachability_s *reach );
//show the reachable areas from the given area
void AAS_ShowReachableAreas( int areanum );

303
src/botlib/be_aas_def.h Normal file
View File

@@ -0,0 +1,303 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_def.h
*
* desc: AAS
*
*
*****************************************************************************/
//debugging on
#define AAS_DEBUG
#define DF_AASENTNUMBER( x ) ( x - ( *aasworlds ).entities )
#define DF_NUMBERAASENT( x ) ( &( *aasworlds ).entities[x] )
#define DF_AASENTCLIENT( x ) ( x - ( *aasworlds ).entities - 1 )
#define DF_CLIENTAASENT( x ) ( &( *aasworlds ).entities[x + 1] )
#ifndef MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
//string index (for model, sound and image index)
typedef struct aas_stringindex_s
{
int numindexes;
char **index;
} aas_stringindex_t;
//structure to link entities to areas and areas to entities
typedef struct aas_link_s
{
int entnum;
int areanum;
struct aas_link_s *next_ent, *prev_ent;
struct aas_link_s *next_area, *prev_area;
} aas_link_t;
//structure to link entities to leaves and leaves to entities
typedef struct bsp_link_s
{
int entnum;
int leafnum;
struct bsp_link_s *next_ent, *prev_ent;
struct bsp_link_s *next_leaf, *prev_leaf;
} bsp_link_t;
typedef struct bsp_entdata_s
{
vec3_t origin;
vec3_t angles;
vec3_t absmins;
vec3_t absmaxs;
int solid;
int modelnum;
} bsp_entdata_t;
//entity
typedef struct aas_entity_s
{
//entity info
aas_entityinfo_t i;
//links into the AAS areas
aas_link_t *areas;
//links into the BSP leaves
bsp_link_t *leaves;
} aas_entity_t;
typedef struct aas_settings_s
{
float sv_friction;
float sv_stopspeed;
float sv_gravity;
float sv_waterfriction;
float sv_watergravity;
float sv_maxvelocity;
float sv_maxwalkvelocity;
float sv_maxcrouchvelocity;
float sv_maxswimvelocity;
float sv_walkaccelerate;
float sv_airaccelerate;
float sv_swimaccelerate;
float sv_maxstep;
float sv_maxsteepness;
float sv_maxwaterjump;
float sv_maxbarrier;
float sv_jumpvel;
qboolean sv_allowladders;
} aas_settings_t;
//routing cache
typedef struct aas_routingcache_s
{
int size; //size of the routing cache
float time; //last time accessed or updated
int cluster; //cluster the cache is for
int areanum; //area the cache is created for
vec3_t origin; //origin within the area
float starttraveltime; //travel time to start with
int travelflags; //combinations of the travel flags
struct aas_routingcache_s *prev, *next;
unsigned char *reachabilities; //reachabilities used for routing
unsigned short int traveltimes[1]; //travel time for every area (variable sized)
} aas_routingcache_t;
//fields for the routing algorithm
typedef struct aas_routingupdate_s
{
int cluster;
int areanum; //area number of the update
vec3_t start; //start point the area was entered
unsigned short int tmptraveltime; //temporary travel time
unsigned short int *areatraveltimes; //travel times within the area
qboolean inlist; //true if the update is in the list
struct aas_routingupdate_s *next;
struct aas_routingupdate_s *prev;
} aas_routingupdate_t;
//reversed reachability link
typedef struct aas_reversedlink_s
{
int linknum; //the aas_areareachability_t
int areanum; //reachable from this area
struct aas_reversedlink_s *next; //next link
} aas_reversedlink_t;
//reversed area reachability
typedef struct aas_reversedreachability_s
{
int numlinks;
aas_reversedlink_t *first;
} aas_reversedreachability_t;
// Ridah, route-tables
#include "be_aas_routetable.h"
// done.
typedef struct aas_s
{
int loaded; //true when an AAS file is loaded
int initialized; //true when AAS has been initialized
int savefile; //set true when file should be saved
int bspchecksum;
//current time
float time;
int numframes;
//name of the aas file
char filename[MAX_PATH];
char mapname[MAX_PATH];
//bounding boxes
int numbboxes;
aas_bbox_t *bboxes;
//vertexes
int numvertexes;
aas_vertex_t *vertexes;
//planes
int numplanes;
aas_plane_t *planes;
//edges
int numedges;
aas_edge_t *edges;
//edge index
int edgeindexsize;
aas_edgeindex_t *edgeindex;
//faces
int numfaces;
aas_face_t *faces;
//face index
int faceindexsize;
aas_faceindex_t *faceindex;
//convex areas
int numareas;
aas_area_t *areas;
//convex area settings
int numareasettings;
aas_areasettings_t *areasettings;
//reachablity list
int reachabilitysize;
aas_reachability_t *reachability;
//nodes of the bsp tree
int numnodes;
aas_node_t *nodes;
//cluster portals
int numportals;
aas_portal_t *portals;
//cluster portal index
int portalindexsize;
aas_portalindex_t *portalindex;
//clusters
int numclusters;
aas_cluster_t *clusters;
//
int reachabilityareas;
float reachabilitytime;
//enities linked in the areas
aas_link_t *linkheap; //heap with link structures
int linkheapsize; //size of the link heap
aas_link_t *freelinks; //first free link
aas_link_t **arealinkedentities; //entities linked into areas
//entities
int maxentities;
int maxclients;
aas_entity_t *entities;
//string indexes
char *configstrings[MAX_CONFIGSTRINGS];
int indexessetup;
//index to retrieve travel flag for a travel type
int travelflagfortype[MAX_TRAVELTYPES];
//routing update
aas_routingupdate_t *areaupdate;
aas_routingupdate_t *portalupdate;
//number of routing updates during a frame (reset every frame)
int frameroutingupdates;
//reversed reachability links
aas_reversedreachability_t *reversedreachability;
//travel times within the areas
unsigned short ***areatraveltimes;
//array of size numclusters with cluster cache
aas_routingcache_t ***clusterareacache;
aas_routingcache_t **portalcache;
//maximum travel time through portals
int *portalmaxtraveltimes;
// Ridah, pointer to Route-Table information
aas_rt_t *routetable;
//hide travel times
unsigned short int *hidetraveltimes;
// Distance from Dangerous areas
unsigned short int *distanceFromDanger;
// Priority Queue Implementation
unsigned short int *PQ_accumulator;
// How many items are in the PQ
int PQ_size;
//vis data
byte *decompressedvis;
int decompressedvisarea;
byte **areavisibility;
// done.
// Ridah, store the area's waypoint for hidepos calculations (center traced downwards)
vec3_t *areawaypoints;
// Ridah, so we can cache the areas that have already been tested for visibility/attackability
byte *visCache;
// RF, cluster team flags (-1 means not calculated)
int *clusterTeamTravelFlags;
// RF, last time a death influenced this area. Seperate lists for axis/allies
int *teamDeathTime;
// RF, number of deaths accumulated before the time expired
byte *teamDeathCount;
// RF, areas that are influenced by a death count
byte *teamDeathAvoid;
} aas_t;
#define AASINTERN
#ifndef BSPCINCLUDE
#include "be_aas_main.h"
#include "be_aas_entity.h"
#include "be_aas_sample.h"
#include "be_aas_cluster.h"
#include "be_aas_reach.h"
#include "be_aas_route.h"
#include "be_aas_routealt.h"
#include "be_aas_debug.h"
#include "be_aas_file.h"
#include "be_aas_optimize.h"
#include "be_aas_bsp.h"
#include "be_aas_move.h"
// Ridah, route-tables
#include "be_aas_routetable.h"
#endif //BSPCINCLUDE

530
src/botlib/be_aas_entity.c Normal file
View File

@@ -0,0 +1,530 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_entity.c
*
* desc: AAS entities
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_utils.h"
#include "l_log.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
#define MASK_SOLID CONTENTS_PLAYERCLIP
// Ridah, always use the default world for entities
extern aas_t aasworlds[MAX_AAS_WORLDS];
aas_t *defaultaasworld = aasworlds;
//FIXME: these might change
/*enum {
ET_GENERAL,
ET_PLAYER,
ET_ITEM,
ET_MISSILE,
ET_MOVER
};*/
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_UpdateEntity( int entnum, bot_entitystate_t *state ) {
int relink;
aas_entity_t *ent;
vec3_t absmins, absmaxs;
if ( !( *defaultaasworld ).loaded ) {
botimport.Print( PRT_MESSAGE, "AAS_UpdateEntity: not loaded\n" );
return BLERR_NOAASFILE;
} //end if
ent = &( *defaultaasworld ).entities[entnum];
ent->i.update_time = AAS_Time() - ent->i.ltime;
ent->i.type = state->type;
ent->i.flags = state->flags;
ent->i.ltime = AAS_Time();
VectorCopy( ent->i.origin, ent->i.lastvisorigin );
VectorCopy( state->old_origin, ent->i.old_origin );
ent->i.solid = state->solid;
ent->i.groundent = state->groundent;
ent->i.modelindex = state->modelindex;
ent->i.modelindex2 = state->modelindex2;
ent->i.frame = state->frame;
//ent->i.event = state->event;
ent->i.eventParm = state->eventParm;
ent->i.powerups = state->powerups;
ent->i.weapon = state->weapon;
ent->i.legsAnim = state->legsAnim;
ent->i.torsoAnim = state->torsoAnim;
// ent->i.weapAnim = state->weapAnim; //----(SA)
//----(SA) didn't want to comment in as I wasn't sure of any implications of changing the aas_entityinfo_t and bot_entitystate_t structures.
//number of the entity
ent->i.number = entnum;
//updated so set valid flag
ent->i.valid = qtrue;
//link everything the first frame
if ( ( *defaultaasworld ).numframes == 1 ) {
relink = qtrue;
} else {
relink = qfalse;
}
//
if ( ent->i.solid == SOLID_BSP ) {
//if the angles of the model changed
if ( !VectorCompare( state->angles, ent->i.angles ) ) {
VectorCopy( state->angles, ent->i.angles );
relink = qtrue;
} //end if
//get the mins and maxs of the model
//FIXME: rotate mins and maxs
// RF, this is broken, just use the state bounds
//AAS_BSPModelMinsMaxsOrigin(ent->i.modelindex, ent->i.angles, ent->i.mins, ent->i.maxs, NULL);
VectorCopy( state->mins, ent->i.mins );
VectorCopy( state->maxs, ent->i.maxs );
} //end if
else if ( ent->i.solid == SOLID_BBOX ) {
//if the bounding box size changed
if ( !VectorCompare( state->mins, ent->i.mins ) ||
!VectorCompare( state->maxs, ent->i.maxs ) ) {
VectorCopy( state->mins, ent->i.mins );
VectorCopy( state->maxs, ent->i.maxs );
relink = qtrue;
} //end if
} //end if
//if the origin changed
if ( !VectorCompare( state->origin, ent->i.origin ) ) {
VectorCopy( state->origin, ent->i.origin );
relink = qtrue;
} //end if
//if the entity should be relinked
if ( relink ) {
//don't link the world model
if ( entnum != ENTITYNUM_WORLD ) {
//absolute mins and maxs
VectorAdd( ent->i.mins, ent->i.origin, absmins );
VectorAdd( ent->i.maxs, ent->i.origin, absmaxs );
//unlink the entity
AAS_UnlinkFromAreas( ent->areas );
//relink the entity to the AAS areas (use the larges bbox)
ent->areas = AAS_LinkEntityClientBBox( absmins, absmaxs, entnum, PRESENCE_NORMAL );
//unlink the entity from the BSP leaves
AAS_UnlinkFromBSPLeaves( ent->leaves );
//link the entity to the world BSP tree
ent->leaves = AAS_BSPLinkEntity( absmins, absmaxs, entnum, 0 );
} //end if
} //end if
return BLERR_NOERROR;
} //end of the function AAS_UpdateEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntityInfo( int entnum, aas_entityinfo_t *info ) {
// Gordon: lets not spam this message making it impossible to see anything on the console
static qboolean debug_msg_done = qfalse;
if ( !( *defaultaasworld ).initialized ) {
if ( !debug_msg_done ) {
debug_msg_done = qtrue;
botimport.Print( PRT_FATAL, "AAS_EntityInfo: (*defaultaasworld) not initialized\n" );
memset( info, 0, sizeof( aas_entityinfo_t ) );
}
return;
} //end if
if ( entnum < 0 || entnum >= ( *defaultaasworld ).maxentities ) {
// if it's not a bot game entity, then report it
if ( !( entnum >= ( *defaultaasworld ).maxentities && entnum < ( *defaultaasworld ).maxentities + NUM_BOTGAMEENTITIES ) ) {
botimport.Print( PRT_FATAL, "AAS_EntityInfo: entnum %d out of range\n", entnum );
}
memset( info, 0, sizeof( aas_entityinfo_t ) );
return;
} //end if
memcpy( info, &( *defaultaasworld ).entities[entnum].i, sizeof( aas_entityinfo_t ) );
} //end of the function AAS_EntityInfo
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntityOrigin( int entnum, vec3_t origin ) {
if ( entnum < 0 || entnum >= ( *defaultaasworld ).maxentities ) {
botimport.Print( PRT_FATAL, "AAS_EntityOrigin: entnum %d out of range\n", entnum );
VectorClear( origin );
return;
} //end if
VectorCopy( ( *defaultaasworld ).entities[entnum].i.origin, origin );
} //end of the function AAS_EntityOrigin
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_EntityModelindex( int entnum ) {
if ( entnum < 0 || entnum >= ( *defaultaasworld ).maxentities ) {
botimport.Print( PRT_FATAL, "AAS_EntityModelindex: entnum %d out of range\n", entnum );
return 0;
} //end if
return ( *defaultaasworld ).entities[entnum].i.modelindex;
} //end of the function AAS_EntityModelindex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_EntityType( int entnum ) {
if ( !( *defaultaasworld ).initialized ) {
return 0;
}
if ( entnum < 0 || entnum >= ( *defaultaasworld ).maxentities ) {
botimport.Print( PRT_FATAL, "AAS_EntityType: entnum %d out of range\n", entnum );
return 0;
} //end if
return ( *defaultaasworld ).entities[entnum].i.type;
} //end of the AAS_EntityType
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_EntityModelNum( int entnum ) {
if ( !( *defaultaasworld ).initialized ) {
return 0;
}
if ( entnum < 0 || entnum >= ( *defaultaasworld ).maxentities ) {
botimport.Print( PRT_FATAL, "AAS_EntityModelNum: entnum %d out of range\n", entnum );
return 0;
} //end if
return ( *defaultaasworld ).entities[entnum].i.modelindex;
} //end of the function AAS_EntityModelNum
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_OriginOfEntityWithModelNum( int modelnum, vec3_t origin ) {
int i;
aas_entity_t *ent;
for ( i = 0; i < ( *defaultaasworld ).maxentities; i++ )
{
ent = &( *defaultaasworld ).entities[i];
if ( ent->i.type == ET_MOVER ) {
if ( ent->i.modelindex == modelnum ) {
VectorCopy( ent->i.origin, origin );
return qtrue;
} //end if
}
} //end for
return qfalse;
} //end of the function AAS_OriginOfEntityWithModelNum
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntitySize( int entnum, vec3_t mins, vec3_t maxs ) {
aas_entity_t *ent;
if ( !( *defaultaasworld ).initialized ) {
return;
}
if ( entnum < 0 || entnum >= ( *defaultaasworld ).maxentities ) {
botimport.Print( PRT_FATAL, "AAS_EntitySize: entnum %d out of range\n", entnum );
return;
} //end if
ent = &( *defaultaasworld ).entities[entnum];
VectorCopy( ent->i.mins, mins );
VectorCopy( ent->i.maxs, maxs );
} //end of the function AAS_EntitySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EntityBSPData( int entnum, bsp_entdata_t *entdata ) {
aas_entity_t *ent;
ent = &( *defaultaasworld ).entities[entnum];
VectorCopy( ent->i.origin, entdata->origin );
VectorCopy( ent->i.angles, entdata->angles );
VectorAdd( ent->i.origin, ent->i.mins, entdata->absmins );
VectorAdd( ent->i.origin, ent->i.maxs, entdata->absmaxs );
entdata->solid = ent->i.solid;
entdata->modelnum = ent->i.modelindex - 1;
} //end of the function AAS_EntityBSPData
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ResetEntityLinks( void ) {
int i;
for ( i = 0; i < ( *defaultaasworld ).maxentities; i++ )
{
( *defaultaasworld ).entities[i].areas = NULL;
( *defaultaasworld ).entities[i].leaves = NULL;
} //end for
} //end of the function AAS_ResetEntityLinks
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_InvalidateEntities( void ) {
int i;
for ( i = 0; i < ( *defaultaasworld ).maxentities; i++ )
{
( *defaultaasworld ).entities[i].i.valid = qfalse;
( *defaultaasworld ).entities[i].i.number = i;
} //end for
} //end of the function AAS_InvalidateEntities
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_NearestEntity( vec3_t origin, int modelindex ) {
int i, bestentnum;
float dist, bestdist;
aas_entity_t *ent;
vec3_t dir;
bestentnum = 0;
bestdist = 99999;
for ( i = 0; i < ( *defaultaasworld ).maxentities; i++ )
{
ent = &( *defaultaasworld ).entities[i];
if ( ent->i.modelindex != modelindex ) {
continue;
}
VectorSubtract( ent->i.origin, origin, dir );
if ( abs( dir[0] ) < 40 ) {
if ( abs( dir[1] ) < 40 ) {
dist = VectorLength( dir );
if ( dist < bestdist ) {
bestdist = dist;
bestentnum = i;
} //end if
} //end if
} //end if
} //end for
return bestentnum;
} //end of the function AAS_NearestEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_BestReachableEntityArea( int entnum ) {
aas_entity_t *ent;
ent = &( *defaultaasworld ).entities[entnum];
return AAS_BestReachableLinkArea( ent->areas );
} //end of the function AAS_BestReachableEntityArea
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_NextEntity( int entnum ) {
if ( !( *defaultaasworld ).loaded ) {
return 0;
}
if ( entnum < 0 ) {
entnum = -1;
}
while ( ++entnum < ( *defaultaasworld ).maxentities )
{
if ( ( *defaultaasworld ).entities[entnum].i.valid ) {
return entnum;
}
} //end while
return 0;
} //end of the function AAS_NextEntity
// Ridah, used to find out if there is an entity touching the given area, if so, try and avoid it
/*
============
AAS_EntityInArea
============
*/
int AAS_IsEntityInArea( int entnumIgnore, int entnumIgnore2, int areanum ) {
aas_link_t *link;
aas_entity_t *ent;
for ( link = ( *aasworld ).arealinkedentities[areanum]; link; link = link->next_ent )
{
//ignore the pass entity
if ( link->entnum == entnumIgnore ) {
continue;
}
if ( link->entnum == entnumIgnore2 ) {
continue;
}
//
ent = &( *defaultaasworld ).entities[link->entnum];
if ( !ent->i.valid ) {
continue;
}
if ( !ent->i.solid ) {
continue;
}
return qtrue;
}
/*
ent = (*defaultaasworld).entities;
for (i = 0; i < (*defaultaasworld).maxclients; i++, ent++)
{
if (!ent->i.valid)
continue;
if (!ent->i.solid)
continue;
if (i == entnumIgnore)
continue;
if (i == entnumIgnore2)
continue;
for (link = ent->areas; link; link = link->next_area)
{
if (link->areanum == areanum)
{
return qtrue;
} //end if
} //end for
}
*/
return qfalse;
}
/*
=============
AAS_SetAASBlockingEntity
=============
*/
int AAS_EnableRoutingArea( int areanum, int enable );
void AAS_SetAASBlockingEntity( vec3_t absmin, vec3_t absmax, int blocking ) {
int areas[1024];
int numareas, i, w;
qboolean mover, changed = qfalse;
//
// check for resetting AAS blocking
if ( VectorCompare( absmin, absmax ) && blocking < 0 ) {
for ( w = 0; w < MAX_AAS_WORLDS; w++ ) {
AAS_SetCurrentWorld( w );
//
if ( !( *aasworld ).loaded ) {
continue;
}
// now clear blocking status
for ( i = 1; i < ( *aasworld ).numareas; i++ ) {
AAS_EnableRoutingArea( i, qtrue );
}
}
//
return;
}
//
if ( blocking & BLOCKINGFLAG_MOVER ) {
mover = qtrue;
blocking &= ~BLOCKINGFLAG_MOVER;
} else {
mover = qfalse;
}
//
areas_again:
//
for ( w = 0; w < MAX_AAS_WORLDS; w++ ) {
AAS_SetCurrentWorld( w );
//
if ( !( *aasworld ).loaded ) {
continue;
}
// grab the list of areas
numareas = AAS_BBoxAreas( absmin, absmax, areas, 1024 );
// now set their blocking status
for ( i = 0; i < numareas; i++ ) {
if ( mover ) {
if ( !( aasworld->areasettings[areas[i]].contents & AREACONTENTS_MOVER ) ) {
continue; // this isn't a mover area, so ignore it
}
}
AAS_EnableRoutingArea( areas[i], ( blocking & ~0x1 ) | !( blocking & 1 ) );
changed = qtrue;
}
}
//
if ( mover && !changed ) { // map must not be compiled with MOVER flags enabled, so redo the old way
mover = qfalse;
goto areas_again;
}
}

View File

@@ -0,0 +1,68 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_entity.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
//invalidates all entity infos
void AAS_InvalidateEntities( void );
//resets the entity AAS and BSP links (sets areas and leaves pointers to NULL)
void AAS_ResetEntityLinks( void );
//updates an entity
int AAS_UpdateEntity( int ent, bot_entitystate_t *state );
//gives the entity data used for collision detection
void AAS_EntityBSPData( int entnum, bsp_entdata_t *entdata );
#endif //AASINTERN
//returns the size of the entity bounding box in mins and maxs
void AAS_EntitySize( int entnum, vec3_t mins, vec3_t maxs );
//returns the BSP model number of the entity
int AAS_EntityModelNum( int entnum );
//returns the origin of an entity with the given model number
int AAS_OriginOfEntityWithModelNum( int modelnum, vec3_t origin );
//returns the best reachable area the entity is situated in
int AAS_BestReachableEntityArea( int entnum );
//returns the info of the given entity
void AAS_EntityInfo( int entnum, aas_entityinfo_t *info );
//returns the next entity
int AAS_NextEntity( int entnum );
//returns the origin of the entity
void AAS_EntityOrigin( int entnum, vec3_t origin );
//returns the entity type
int AAS_EntityType( int entnum );
//returns the model index of the entity
int AAS_EntityModelindex( int entnum );
// Ridah
int AAS_IsEntityInArea( int entnumIgnore, int entnumIgnore2, int areanum );

681
src/botlib/be_aas_file.c Normal file
View File

@@ -0,0 +1,681 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_file.c
*
* desc: AAS file loading/writing
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_libvar.h"
#include "l_utils.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
//#define AASFILEDEBUG
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_SwapAASData( void ) {
int i, j;
// Ridah, no need to do anything if this OS doesn't need byte swapping
if ( LittleLong( 1 ) == 1 ) {
return;
}
// done.
//bounding boxes
for ( i = 0; i < ( *aasworld ).numbboxes; i++ )
{
( *aasworld ).bboxes[i].presencetype = LittleLong( ( *aasworld ).bboxes[i].presencetype );
( *aasworld ).bboxes[i].flags = LittleLong( ( *aasworld ).bboxes[i].flags );
for ( j = 0; j < 3; j++ )
{
( *aasworld ).bboxes[i].mins[j] = LittleLong( ( *aasworld ).bboxes[i].mins[j] );
( *aasworld ).bboxes[i].maxs[j] = LittleLong( ( *aasworld ).bboxes[i].maxs[j] );
} //end for
} //end for
//vertexes
for ( i = 0; i < ( *aasworld ).numvertexes; i++ )
{
for ( j = 0; j < 3; j++ )
( *aasworld ).vertexes[i][j] = LittleFloat( ( *aasworld ).vertexes[i][j] );
} //end for
//planes
for ( i = 0; i < ( *aasworld ).numplanes; i++ )
{
for ( j = 0; j < 3; j++ )
( *aasworld ).planes[i].normal[j] = LittleFloat( ( *aasworld ).planes[i].normal[j] );
( *aasworld ).planes[i].dist = LittleFloat( ( *aasworld ).planes[i].dist );
( *aasworld ).planes[i].type = LittleLong( ( *aasworld ).planes[i].type );
} //end for
//edges
for ( i = 0; i < ( *aasworld ).numedges; i++ )
{
( *aasworld ).edges[i].v[0] = LittleLong( ( *aasworld ).edges[i].v[0] );
( *aasworld ).edges[i].v[1] = LittleLong( ( *aasworld ).edges[i].v[1] );
} //end for
//edgeindex
for ( i = 0; i < ( *aasworld ).edgeindexsize; i++ )
{
( *aasworld ).edgeindex[i] = LittleLong( ( *aasworld ).edgeindex[i] );
} //end for
//faces
for ( i = 0; i < ( *aasworld ).numfaces; i++ )
{
( *aasworld ).faces[i].planenum = LittleLong( ( *aasworld ).faces[i].planenum );
( *aasworld ).faces[i].faceflags = LittleLong( ( *aasworld ).faces[i].faceflags );
( *aasworld ).faces[i].numedges = LittleLong( ( *aasworld ).faces[i].numedges );
( *aasworld ).faces[i].firstedge = LittleLong( ( *aasworld ).faces[i].firstedge );
( *aasworld ).faces[i].frontarea = LittleLong( ( *aasworld ).faces[i].frontarea );
( *aasworld ).faces[i].backarea = LittleLong( ( *aasworld ).faces[i].backarea );
} //end for
//face index
for ( i = 0; i < ( *aasworld ).faceindexsize; i++ )
{
( *aasworld ).faceindex[i] = LittleLong( ( *aasworld ).faceindex[i] );
} //end for
//convex areas
for ( i = 0; i < ( *aasworld ).numareas; i++ )
{
( *aasworld ).areas[i].areanum = LittleLong( ( *aasworld ).areas[i].areanum );
( *aasworld ).areas[i].numfaces = LittleLong( ( *aasworld ).areas[i].numfaces );
( *aasworld ).areas[i].firstface = LittleLong( ( *aasworld ).areas[i].firstface );
for ( j = 0; j < 3; j++ )
{
( *aasworld ).areas[i].mins[j] = LittleFloat( ( *aasworld ).areas[i].mins[j] );
( *aasworld ).areas[i].maxs[j] = LittleFloat( ( *aasworld ).areas[i].maxs[j] );
( *aasworld ).areas[i].center[j] = LittleFloat( ( *aasworld ).areas[i].center[j] );
} //end for
} //end for
//area settings
for ( i = 0; i < ( *aasworld ).numareasettings; i++ )
{
( *aasworld ).areasettings[i].contents = LittleLong( ( *aasworld ).areasettings[i].contents );
( *aasworld ).areasettings[i].areaflags = LittleLong( ( *aasworld ).areasettings[i].areaflags );
( *aasworld ).areasettings[i].presencetype = LittleLong( ( *aasworld ).areasettings[i].presencetype );
( *aasworld ).areasettings[i].cluster = LittleLong( ( *aasworld ).areasettings[i].cluster );
( *aasworld ).areasettings[i].clusterareanum = LittleLong( ( *aasworld ).areasettings[i].clusterareanum );
( *aasworld ).areasettings[i].numreachableareas = LittleLong( ( *aasworld ).areasettings[i].numreachableareas );
( *aasworld ).areasettings[i].firstreachablearea = LittleLong( ( *aasworld ).areasettings[i].firstreachablearea );
( *aasworld ).areasettings[i].groundsteepness = LittleFloat( ( *aasworld ).areasettings[i].groundsteepness );
} //end for
//area reachability
for ( i = 0; i < ( *aasworld ).reachabilitysize; i++ )
{
( *aasworld ).reachability[i].areanum = LittleLong( ( *aasworld ).reachability[i].areanum );
( *aasworld ).reachability[i].facenum = LittleLong( ( *aasworld ).reachability[i].facenum );
( *aasworld ).reachability[i].edgenum = LittleLong( ( *aasworld ).reachability[i].edgenum );
for ( j = 0; j < 3; j++ )
{
( *aasworld ).reachability[i].start[j] = LittleFloat( ( *aasworld ).reachability[i].start[j] );
( *aasworld ).reachability[i].end[j] = LittleFloat( ( *aasworld ).reachability[i].end[j] );
} //end for
( *aasworld ).reachability[i].traveltype = LittleLong( ( *aasworld ).reachability[i].traveltype );
( *aasworld ).reachability[i].traveltime = LittleShort( ( *aasworld ).reachability[i].traveltime );
} //end for
//nodes
for ( i = 0; i < ( *aasworld ).numnodes; i++ )
{
( *aasworld ).nodes[i].planenum = LittleLong( ( *aasworld ).nodes[i].planenum );
( *aasworld ).nodes[i].children[0] = LittleLong( ( *aasworld ).nodes[i].children[0] );
( *aasworld ).nodes[i].children[1] = LittleLong( ( *aasworld ).nodes[i].children[1] );
} //end for
//cluster portals
for ( i = 0; i < ( *aasworld ).numportals; i++ )
{
( *aasworld ).portals[i].areanum = LittleLong( ( *aasworld ).portals[i].areanum );
( *aasworld ).portals[i].frontcluster = LittleLong( ( *aasworld ).portals[i].frontcluster );
( *aasworld ).portals[i].backcluster = LittleLong( ( *aasworld ).portals[i].backcluster );
( *aasworld ).portals[i].clusterareanum[0] = LittleLong( ( *aasworld ).portals[i].clusterareanum[0] );
( *aasworld ).portals[i].clusterareanum[1] = LittleLong( ( *aasworld ).portals[i].clusterareanum[1] );
} //end for
//cluster portal index
for ( i = 0; i < ( *aasworld ).portalindexsize; i++ )
{
( *aasworld ).portalindex[i] = LittleLong( ( *aasworld ).portalindex[i] );
} //end for
//cluster
for ( i = 0; i < ( *aasworld ).numclusters; i++ )
{
( *aasworld ).clusters[i].numareas = LittleLong( ( *aasworld ).clusters[i].numareas );
( *aasworld ).clusters[i].numreachabilityareas = LittleLong( ( *aasworld ).clusters[i].numreachabilityareas );
( *aasworld ).clusters[i].numportals = LittleLong( ( *aasworld ).clusters[i].numportals );
( *aasworld ).clusters[i].firstportal = LittleLong( ( *aasworld ).clusters[i].firstportal );
} //end for
} //end of the function AAS_SwapAASData
//===========================================================================
// dump the current loaded aas file
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DumpAASData( void ) {
( *aasworld ).numbboxes = 0;
if ( ( *aasworld ).bboxes ) {
FreeMemory( ( *aasworld ).bboxes );
}
( *aasworld ).bboxes = NULL;
( *aasworld ).numvertexes = 0;
if ( ( *aasworld ).vertexes ) {
FreeMemory( ( *aasworld ).vertexes );
}
( *aasworld ).vertexes = NULL;
( *aasworld ).numplanes = 0;
if ( ( *aasworld ).planes ) {
FreeMemory( ( *aasworld ).planes );
}
( *aasworld ).planes = NULL;
( *aasworld ).numedges = 0;
if ( ( *aasworld ).edges ) {
FreeMemory( ( *aasworld ).edges );
}
( *aasworld ).edges = NULL;
( *aasworld ).edgeindexsize = 0;
if ( ( *aasworld ).edgeindex ) {
FreeMemory( ( *aasworld ).edgeindex );
}
( *aasworld ).edgeindex = NULL;
( *aasworld ).numfaces = 0;
if ( ( *aasworld ).faces ) {
FreeMemory( ( *aasworld ).faces );
}
( *aasworld ).faces = NULL;
( *aasworld ).faceindexsize = 0;
if ( ( *aasworld ).faceindex ) {
FreeMemory( ( *aasworld ).faceindex );
}
( *aasworld ).faceindex = NULL;
( *aasworld ).numareas = 0;
if ( ( *aasworld ).areas ) {
FreeMemory( ( *aasworld ).areas );
}
( *aasworld ).areas = NULL;
( *aasworld ).numareasettings = 0;
if ( ( *aasworld ).areasettings ) {
FreeMemory( ( *aasworld ).areasettings );
}
( *aasworld ).areasettings = NULL;
( *aasworld ).reachabilitysize = 0;
if ( ( *aasworld ).reachability ) {
FreeMemory( ( *aasworld ).reachability );
}
( *aasworld ).reachability = NULL;
( *aasworld ).numnodes = 0;
if ( ( *aasworld ).nodes ) {
FreeMemory( ( *aasworld ).nodes );
}
( *aasworld ).nodes = NULL;
( *aasworld ).numportals = 0;
if ( ( *aasworld ).portals ) {
FreeMemory( ( *aasworld ).portals );
}
( *aasworld ).portals = NULL;
( *aasworld ).numportals = 0;
if ( ( *aasworld ).portalindex ) {
FreeMemory( ( *aasworld ).portalindex );
}
( *aasworld ).portalindex = NULL;
( *aasworld ).portalindexsize = 0;
if ( ( *aasworld ).clusters ) {
FreeMemory( ( *aasworld ).clusters );
}
( *aasworld ).clusters = NULL;
( *aasworld ).numclusters = 0;
//
( *aasworld ).loaded = qfalse;
( *aasworld ).initialized = qfalse;
( *aasworld ).savefile = qfalse;
} //end of the function AAS_DumpAASData
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef AASFILEDEBUG
void AAS_FileInfo( void ) {
int i, n, optimized;
botimport.Print( PRT_MESSAGE, "version = %d\n", AASVERSION );
botimport.Print( PRT_MESSAGE, "numvertexes = %d\n", ( *aasworld ).numvertexes );
botimport.Print( PRT_MESSAGE, "numplanes = %d\n", ( *aasworld ).numplanes );
botimport.Print( PRT_MESSAGE, "numedges = %d\n", ( *aasworld ).numedges );
botimport.Print( PRT_MESSAGE, "edgeindexsize = %d\n", ( *aasworld ).edgeindexsize );
botimport.Print( PRT_MESSAGE, "numfaces = %d\n", ( *aasworld ).numfaces );
botimport.Print( PRT_MESSAGE, "faceindexsize = %d\n", ( *aasworld ).faceindexsize );
botimport.Print( PRT_MESSAGE, "numareas = %d\n", ( *aasworld ).numareas );
botimport.Print( PRT_MESSAGE, "numareasettings = %d\n", ( *aasworld ).numareasettings );
botimport.Print( PRT_MESSAGE, "reachabilitysize = %d\n", ( *aasworld ).reachabilitysize );
botimport.Print( PRT_MESSAGE, "numnodes = %d\n", ( *aasworld ).numnodes );
botimport.Print( PRT_MESSAGE, "numportals = %d\n", ( *aasworld ).numportals );
botimport.Print( PRT_MESSAGE, "portalindexsize = %d\n", ( *aasworld ).portalindexsize );
botimport.Print( PRT_MESSAGE, "numclusters = %d\n", ( *aasworld ).numclusters );
//
for ( n = 0, i = 0; i < ( *aasworld ).numareasettings; i++ )
{
if ( ( *aasworld ).areasettings[i].areaflags & AREA_GROUNDED ) {
n++;
}
} //end for
botimport.Print( PRT_MESSAGE, "num grounded areas = %d\n", n );
//
botimport.Print( PRT_MESSAGE, "planes size %d bytes\n", ( *aasworld ).numplanes * sizeof( aas_plane_t ) );
botimport.Print( PRT_MESSAGE, "areas size %d bytes\n", ( *aasworld ).numareas * sizeof( aas_area_t ) );
botimport.Print( PRT_MESSAGE, "areasettings size %d bytes\n", ( *aasworld ).numareasettings * sizeof( aas_areasettings_t ) );
botimport.Print( PRT_MESSAGE, "nodes size %d bytes\n", ( *aasworld ).numnodes * sizeof( aas_node_t ) );
botimport.Print( PRT_MESSAGE, "reachability size %d bytes\n", ( *aasworld ).reachabilitysize * sizeof( aas_reachability_t ) );
botimport.Print( PRT_MESSAGE, "portals size %d bytes\n", ( *aasworld ).numportals * sizeof( aas_portal_t ) );
botimport.Print( PRT_MESSAGE, "clusters size %d bytes\n", ( *aasworld ).numclusters * sizeof( aas_cluster_t ) );
optimized = ( *aasworld ).numplanes * sizeof( aas_plane_t ) +
( *aasworld ).numareas * sizeof( aas_area_t ) +
( *aasworld ).numareasettings * sizeof( aas_areasettings_t ) +
( *aasworld ).numnodes * sizeof( aas_node_t ) +
( *aasworld ).reachabilitysize * sizeof( aas_reachability_t ) +
( *aasworld ).numportals * sizeof( aas_portal_t ) +
( *aasworld ).numclusters * sizeof( aas_cluster_t );
botimport.Print( PRT_MESSAGE, "optimzed size %d KB\n", optimized >> 10 );
} //end of the function AAS_FileInfo
#endif //AASFILEDEBUG
//===========================================================================
// allocate memory and read a lump of a AAS file
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *AAS_LoadAASLump( fileHandle_t fp, int offset, int length, int *lastoffset ) {
char *buf;
//
if ( !length ) {
return NULL;
}
//seek to the data
if ( offset != *lastoffset ) {
botimport.Print( PRT_WARNING, "AAS file not sequentially read\n" );
if ( botimport.FS_Seek( fp, offset, FS_SEEK_SET ) ) {
AAS_Error( "can't seek to aas lump\n" );
AAS_DumpAASData();
botimport.FS_FCloseFile( fp );
return 0;
} //end if
} //end if
//allocate memory
buf = (char *) GetClearedHunkMemory( length + 1 );
//read the data
if ( length ) {
botimport.FS_Read( buf, length, fp );
*lastoffset += length;
} //end if
return buf;
} //end of the function AAS_LoadAASLump
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_DData( unsigned char *data, int size ) {
int i;
for ( i = 0; i < size; i++ )
{
data[i] ^= (unsigned char) i * 119;
} //end for
} //end of the function AAS_DData
//===========================================================================
// load an aas file
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_LoadAASFile( char *filename ) {
fileHandle_t fp;
aas_header_t header;
int offset, length, lastoffset;
int nocrc;
botimport.Print( PRT_MESSAGE, "trying to load %s\n", filename );
//dump current loaded aas file
AAS_DumpAASData();
//open the file
botimport.FS_FOpenFile( filename, &fp, FS_READ );
if ( !fp ) {
AAS_Error( "can't open %s\n", filename );
return BLERR_CANNOTOPENAASFILE;
} //end if
//read the header
botimport.FS_Read( &header, sizeof( aas_header_t ), fp );
lastoffset = sizeof( aas_header_t );
//check header identification
header.ident = LittleLong( header.ident );
if ( header.ident != AASID ) {
AAS_Error( "%s is not an AAS file\n", filename );
botimport.FS_FCloseFile( fp );
return BLERR_WRONGAASFILEID;
} //end if
//check the version
header.version = LittleLong( header.version );
//
if ( header.version != AASVERSION ) {
AAS_Error( "aas file %s is version %i, not %i\n", filename, header.version, AASVERSION );
botimport.FS_FCloseFile( fp );
return BLERR_WRONGAASFILEVERSION;
} //end if
//
//RF, checksum of -1 always passes, hack to fix commercial maps without having to distribute new bsps
nocrc = 0;
if ( LittleLong( header.bspchecksum ) == -1 ) {
nocrc = 1;
}
//
if ( header.version == AASVERSION ) {
AAS_DData( (unsigned char *) &header + 8, sizeof( aas_header_t ) - 8 );
} //end if
//
( *aasworld ).bspchecksum = atoi( LibVarGetString( "sv_mapChecksum" ) );
if ( !nocrc && LittleLong( header.bspchecksum ) != ( *aasworld ).bspchecksum ) {
AAS_Error( "aas file %s is out of date\n", filename );
botimport.FS_FCloseFile( fp );
return BLERR_WRONGAASFILEVERSION;
} //end if
//load the lumps:
//bounding boxes
offset = LittleLong( header.lumps[AASLUMP_BBOXES].fileofs );
length = LittleLong( header.lumps[AASLUMP_BBOXES].filelen );
( *aasworld ).bboxes = (aas_bbox_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numbboxes = length / sizeof( aas_bbox_t );
if ( ( *aasworld ).numbboxes && !( *aasworld ).bboxes ) {
return BLERR_CANNOTREADAASLUMP;
}
//vertexes
offset = LittleLong( header.lumps[AASLUMP_VERTEXES].fileofs );
length = LittleLong( header.lumps[AASLUMP_VERTEXES].filelen );
( *aasworld ).vertexes = (aas_vertex_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numvertexes = length / sizeof( aas_vertex_t );
if ( ( *aasworld ).numvertexes && !( *aasworld ).vertexes ) {
return BLERR_CANNOTREADAASLUMP;
}
//planes
offset = LittleLong( header.lumps[AASLUMP_PLANES].fileofs );
length = LittleLong( header.lumps[AASLUMP_PLANES].filelen );
( *aasworld ).planes = (aas_plane_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numplanes = length / sizeof( aas_plane_t );
if ( ( *aasworld ).numplanes && !( *aasworld ).planes ) {
return BLERR_CANNOTREADAASLUMP;
}
//edges
offset = LittleLong( header.lumps[AASLUMP_EDGES].fileofs );
length = LittleLong( header.lumps[AASLUMP_EDGES].filelen );
( *aasworld ).edges = (aas_edge_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numedges = length / sizeof( aas_edge_t );
if ( ( *aasworld ).numedges && !( *aasworld ).edges ) {
return BLERR_CANNOTREADAASLUMP;
}
//edgeindex
offset = LittleLong( header.lumps[AASLUMP_EDGEINDEX].fileofs );
length = LittleLong( header.lumps[AASLUMP_EDGEINDEX].filelen );
( *aasworld ).edgeindex = (aas_edgeindex_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).edgeindexsize = length / sizeof( aas_edgeindex_t );
if ( ( *aasworld ).edgeindexsize && !( *aasworld ).edgeindex ) {
return BLERR_CANNOTREADAASLUMP;
}
//faces
offset = LittleLong( header.lumps[AASLUMP_FACES].fileofs );
length = LittleLong( header.lumps[AASLUMP_FACES].filelen );
( *aasworld ).faces = (aas_face_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numfaces = length / sizeof( aas_face_t );
if ( ( *aasworld ).numfaces && !( *aasworld ).faces ) {
return BLERR_CANNOTREADAASLUMP;
}
//faceindex
offset = LittleLong( header.lumps[AASLUMP_FACEINDEX].fileofs );
length = LittleLong( header.lumps[AASLUMP_FACEINDEX].filelen );
( *aasworld ).faceindex = (aas_faceindex_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).faceindexsize = length / sizeof( int );
if ( ( *aasworld ).faceindexsize && !( *aasworld ).faceindex ) {
return BLERR_CANNOTREADAASLUMP;
}
//convex areas
offset = LittleLong( header.lumps[AASLUMP_AREAS].fileofs );
length = LittleLong( header.lumps[AASLUMP_AREAS].filelen );
( *aasworld ).areas = (aas_area_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numareas = length / sizeof( aas_area_t );
if ( ( *aasworld ).numareas && !( *aasworld ).areas ) {
return BLERR_CANNOTREADAASLUMP;
}
//area settings
offset = LittleLong( header.lumps[AASLUMP_AREASETTINGS].fileofs );
length = LittleLong( header.lumps[AASLUMP_AREASETTINGS].filelen );
( *aasworld ).areasettings = (aas_areasettings_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numareasettings = length / sizeof( aas_areasettings_t );
if ( ( *aasworld ).numareasettings && !( *aasworld ).areasettings ) {
return BLERR_CANNOTREADAASLUMP;
}
//reachability list
offset = LittleLong( header.lumps[AASLUMP_REACHABILITY].fileofs );
length = LittleLong( header.lumps[AASLUMP_REACHABILITY].filelen );
( *aasworld ).reachability = (aas_reachability_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).reachabilitysize = length / sizeof( aas_reachability_t );
if ( ( *aasworld ).reachabilitysize && !( *aasworld ).reachability ) {
return BLERR_CANNOTREADAASLUMP;
}
//nodes
offset = LittleLong( header.lumps[AASLUMP_NODES].fileofs );
length = LittleLong( header.lumps[AASLUMP_NODES].filelen );
( *aasworld ).nodes = (aas_node_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numnodes = length / sizeof( aas_node_t );
if ( ( *aasworld ).numnodes && !( *aasworld ).nodes ) {
return BLERR_CANNOTREADAASLUMP;
}
//cluster portals
offset = LittleLong( header.lumps[AASLUMP_PORTALS].fileofs );
length = LittleLong( header.lumps[AASLUMP_PORTALS].filelen );
( *aasworld ).portals = (aas_portal_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numportals = length / sizeof( aas_portal_t );
if ( ( *aasworld ).numportals && !( *aasworld ).portals ) {
return BLERR_CANNOTREADAASLUMP;
}
//cluster portal index
offset = LittleLong( header.lumps[AASLUMP_PORTALINDEX].fileofs );
length = LittleLong( header.lumps[AASLUMP_PORTALINDEX].filelen );
( *aasworld ).portalindex = (aas_portalindex_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).portalindexsize = length / sizeof( aas_portalindex_t );
if ( ( *aasworld ).portalindexsize && !( *aasworld ).portalindex ) {
return BLERR_CANNOTREADAASLUMP;
}
//clusters
offset = LittleLong( header.lumps[AASLUMP_CLUSTERS].fileofs );
length = LittleLong( header.lumps[AASLUMP_CLUSTERS].filelen );
( *aasworld ).clusters = (aas_cluster_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
( *aasworld ).numclusters = length / sizeof( aas_cluster_t );
if ( ( *aasworld ).numclusters && !( *aasworld ).clusters ) {
return BLERR_CANNOTREADAASLUMP;
}
//swap everything
AAS_SwapAASData();
//aas file is loaded
( *aasworld ).loaded = qtrue;
//close the file
botimport.FS_FCloseFile( fp );
//
#ifdef AASFILEDEBUG
AAS_FileInfo();
#endif //AASFILEDEBUG
//
{
int j = 0;
int i;
for ( i = 1; i < aasworld->numareas; i++ ) {
j += aasworld->areasettings[i].numreachableareas;
}
if ( j > aasworld->reachabilitysize ) {
Com_Error( ERR_DROP, "aas reachabilitysize incorrect\n" );
}
}
return BLERR_NOERROR;
} //end of the function AAS_LoadAASFile
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
static int AAS_WriteAASLump_offset;
int AAS_WriteAASLump( fileHandle_t fp, aas_header_t *h, int lumpnum, void *data, int length ) {
aas_lump_t *lump;
lump = &h->lumps[lumpnum];
lump->fileofs = LittleLong( AAS_WriteAASLump_offset ); //LittleLong(ftell(fp));
lump->filelen = LittleLong( length );
if ( length > 0 ) {
botimport.FS_Write( data, length, fp );
} //end if
AAS_WriteAASLump_offset += length;
return qtrue;
} //end of the function AAS_WriteAASLump
//===========================================================================
// aas data is useless after writing to file because it is byte swapped
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean AAS_WriteAASFile( char *filename ) {
aas_header_t header;
fileHandle_t fp;
botimport.Print( PRT_MESSAGE, "writing %s\n", filename );
//swap the aas data
AAS_SwapAASData();
//initialize the file header
memset( &header, 0, sizeof( aas_header_t ) );
header.ident = LittleLong( AASID );
header.version = LittleLong( AASVERSION );
header.bspchecksum = LittleLong( ( *aasworld ).bspchecksum );
//open a new file
botimport.FS_FOpenFile( filename, &fp, FS_WRITE );
if ( !fp ) {
botimport.Print( PRT_ERROR, "error opening %s\n", filename );
return qfalse;
} //end if
//write the header
botimport.FS_Write( &header, sizeof( aas_header_t ), fp );
AAS_WriteAASLump_offset = sizeof( aas_header_t );
//add the data lumps to the file
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_BBOXES, ( *aasworld ).bboxes,
( *aasworld ).numbboxes * sizeof( aas_bbox_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_VERTEXES, ( *aasworld ).vertexes,
( *aasworld ).numvertexes * sizeof( aas_vertex_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_PLANES, ( *aasworld ).planes,
( *aasworld ).numplanes * sizeof( aas_plane_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_EDGES, ( *aasworld ).edges,
( *aasworld ).numedges * sizeof( aas_edge_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_EDGEINDEX, ( *aasworld ).edgeindex,
( *aasworld ).edgeindexsize * sizeof( aas_edgeindex_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_FACES, ( *aasworld ).faces,
( *aasworld ).numfaces * sizeof( aas_face_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_FACEINDEX, ( *aasworld ).faceindex,
( *aasworld ).faceindexsize * sizeof( aas_faceindex_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_AREAS, ( *aasworld ).areas,
( *aasworld ).numareas * sizeof( aas_area_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_AREASETTINGS, ( *aasworld ).areasettings,
( *aasworld ).numareasettings * sizeof( aas_areasettings_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_REACHABILITY, ( *aasworld ).reachability,
( *aasworld ).reachabilitysize * sizeof( aas_reachability_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_NODES, ( *aasworld ).nodes,
( *aasworld ).numnodes * sizeof( aas_node_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_PORTALS, ( *aasworld ).portals,
( *aasworld ).numportals * sizeof( aas_portal_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_PORTALINDEX, ( *aasworld ).portalindex,
( *aasworld ).portalindexsize * sizeof( aas_portalindex_t ) ) ) {
return qfalse;
}
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_CLUSTERS, ( *aasworld ).clusters,
( *aasworld ).numclusters * sizeof( aas_cluster_t ) ) ) {
return qfalse;
}
//rewrite the header with the added lumps
botimport.FS_Seek( fp, 0, FS_SEEK_SET );
botimport.FS_Write( &header, sizeof( aas_header_t ), fp );
//close the file
botimport.FS_FCloseFile( fp );
return qtrue;
} //end of the function AAS_WriteAASFile

48
src/botlib/be_aas_file.h Normal file
View File

@@ -0,0 +1,48 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_file.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
//loads the AAS file with the given name
int AAS_LoadAASFile( char *filename );
//writes an AAS file with the given name
qboolean AAS_WriteAASFile( char *filename );
//dumps the loaded AAS data
void AAS_DumpAASData( void );
//print AAS file information
void AAS_FileInfo( void );
#endif //AASINTERN

56
src/botlib/be_aas_funcs.h Normal file
View File

@@ -0,0 +1,56 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_funcs.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifndef BSPCINCLUDE
#include "be_aas_main.h"
#include "be_aas_entity.h"
#include "be_aas_sample.h"
#include "be_aas_cluster.h"
#include "be_aas_reach.h"
#include "be_aas_route.h"
#include "be_aas_routealt.h"
#include "be_aas_debug.h"
#include "be_aas_file.h"
#include "be_aas_optimize.h"
#include "be_aas_bsp.h"
#include "be_aas_move.h"
// Ridah, route-tables
#include "be_aas_routetable.h"
#endif //BSPCINCLUDE

491
src/botlib/be_aas_main.c Normal file
View File

@@ -0,0 +1,491 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_main.c
*
* desc: AAS
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_libvar.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_log.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
aas_t aasworlds[MAX_AAS_WORLDS];
aas_t *aasworld;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void QDECL AAS_Error( char *fmt, ... ) {
char str[1024];
va_list arglist;
va_start( arglist, fmt );
Q_vsnprintf( str, sizeof( str ), fmt, arglist );
va_end( arglist );
botimport.Print( PRT_FATAL, str );
} //end of the function AAS_Error
// Ridah, multiple AAS worlds
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_SetCurrentWorld( int index ) {
if ( index >= MAX_AAS_WORLDS || index < 0 ) {
AAS_Error( "AAS_SetCurrentWorld: index out of range\n" );
return;
}
// set the current world pointer
aasworld = &aasworlds[index];
}
// done.
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *AAS_StringFromIndex( char *indexname, char *stringindex[], int numindexes, int index ) {
if ( !( *aasworld ).indexessetup ) {
botimport.Print( PRT_ERROR, "%s: index %d not setup\n", indexname, index );
return "";
} //end if
if ( index < 0 || index >= numindexes ) {
botimport.Print( PRT_ERROR, "%s: index %d out of range\n", indexname, index );
return "";
} //end if
if ( !stringindex[index] ) {
if ( index ) {
botimport.Print( PRT_ERROR, "%s: reference to unused index %d\n", indexname, index );
} //end if
return "";
} //end if
return stringindex[index];
} //end of the function AAS_StringFromIndex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_IndexFromString( char *indexname, char *stringindex[], int numindexes, char *string ) {
int i;
if ( !( *aasworld ).indexessetup ) {
botimport.Print( PRT_ERROR, "%s: index not setup \"%s\"\n", indexname, string );
return 0;
} //end if
for ( i = 0; i < numindexes; i++ )
{
if ( !stringindex[i] ) {
continue;
}
if ( !Q_stricmp( stringindex[i], string ) ) {
return i;
}
} //end for
return 0;
} //end of the function AAS_IndexFromString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *AAS_ModelFromIndex( int index ) {
// return AAS_StringFromIndex("ModelFromIndex", &(*aasworld).configstrings[CS_MODELS], MAX_MODELS, index);
return 0; // removed so the CS_ defines could be removed from be_aas_def.h
} //end of the function AAS_ModelFromIndex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_IndexFromModel( char *modelname ) {
// return AAS_IndexFromString("IndexFromModel", &(*aasworld).configstrings[CS_MODELS], MAX_MODELS, modelname);
return 0; // removed so the CS_ defines could be removed from be_aas_def.h
} //end of the function AAS_IndexFromModel
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_UpdateStringIndexes( int numconfigstrings, char *configstrings[] ) {
int i;
//set string pointers and copy the strings
for ( i = 0; i < numconfigstrings; i++ )
{
if ( configstrings[i] ) {
//if ((*aasworld).configstrings[i]) FreeMemory((*aasworld).configstrings[i]);
( *aasworld ).configstrings[i] = (char *) GetMemory( strlen( configstrings[i] ) + 1 );
strcpy( ( *aasworld ).configstrings[i], configstrings[i] );
} //end if
} //end for
( *aasworld ).indexessetup = qtrue;
} //end of the function AAS_UpdateStringIndexes
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_Loaded( void ) {
return ( *aasworld ).loaded;
} //end of the function AAS_Loaded
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_Initialized( void ) {
return ( *aasworld ).initialized;
} //end of the function AAS_Initialized
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_SetInitialized( void ) {
( *aasworld ).initialized = qtrue;
botimport.Print( PRT_MESSAGE, "AAS initialized.\n" );
#ifdef DEBUG
//create all the routing cache
//AAS_CreateAllRoutingCache();
//
//AAS_RoutingInfo();
#endif
// Ridah, build/load the route-table
AAS_RT_BuildRouteTable();
// done.
AAS_InitTeamDeath();
} //end of the function AAS_SetInitialized
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ContinueInit( float time ) {
//if no AAS file loaded
if ( !( *aasworld ).loaded ) {
return;
}
//if AAS is already initialized
if ( ( *aasworld ).initialized ) {
return;
}
//calculate reachability, if not finished return
if ( AAS_ContinueInitReachability( time ) ) {
return;
}
//initialize clustering for the new map
AAS_InitClustering();
//if reachability has been calculated and an AAS file should be written
//or there is a forced data optimization
if ( ( *aasworld ).savefile || ( (int)LibVarGetValue( "forcewrite" ) ) ) {
//optimize the AAS data
if ( !( (int)LibVarValue( "nooptimize", "1" ) ) ) {
AAS_Optimize();
}
//save the AAS file
if ( AAS_WriteAASFile( ( *aasworld ).filename ) ) {
botimport.Print( PRT_MESSAGE, "%s written succesfully\n", ( *aasworld ).filename );
} else {
botimport.Print( PRT_ERROR, "couldn't write %s\n", ( *aasworld ).filename );
} //end else
} //end if
//initialize the routing
AAS_InitRouting();
//at this point AAS is initialized
AAS_SetInitialized();
} //end of the function AAS_ContinueInit
//===========================================================================
// called at the start of every frame
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_StartFrame( float time ) {
// Ridah, do each of the aasworlds
int i;
for ( i = 0; i < MAX_AAS_WORLDS; i++ )
{
AAS_SetCurrentWorld( i );
( *aasworld ).time = time;
//invalidate the entities
AAS_InvalidateEntities();
//initialize AAS
AAS_ContinueInit( time );
//update team deaths
AAS_UpdateTeamDeath();
//
( *aasworld ).frameroutingupdates = 0;
//
/* Ridah, disabled for speed
if (LibVarGetValue("showcacheupdates"))
{
AAS_RoutingInfo();
LibVarSet("showcacheupdates", "0");
} //end if
if (LibVarGetValue("showmemoryusage"))
{
PrintUsedMemorySize();
LibVarSet("showmemoryusage", "0");
} //end if
if (LibVarGetValue("memorydump"))
{
PrintMemoryLabels();
LibVarSet("memorydump", "0");
} //end if
*/
} //end if
( *aasworld ).numframes++;
return BLERR_NOERROR;
} //end of the function AAS_StartFrame
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float AAS_Time( void ) {
return aasworld->time;
}
//===========================================================================
// basedir = Quake2 console basedir
// gamedir = Quake2 console gamedir
// mapname = name of the map without extension (.bsp)
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_LoadFiles( const char *mapname ) {
int errnum;
char aasfile[MAX_PATH];
// char bspfile[MAX_PATH];
strcpy( ( *aasworld ).mapname, mapname );
//NOTE: first reset the entity links into the AAS areas and BSP leaves
// the AAS link heap and BSP link heap are reset after respectively the
// AAS file and BSP file are loaded
AAS_ResetEntityLinks();
//
// load bsp info
AAS_LoadBSPFile();
//load the aas file
Com_sprintf( aasfile, MAX_PATH, "maps/%s.aas", mapname );
errnum = AAS_LoadAASFile( aasfile );
if ( errnum != BLERR_NOERROR ) {
return errnum;
}
botimport.Print( PRT_MESSAGE, "loaded %s\n", aasfile );
strncpy( ( *aasworld ).filename, aasfile, MAX_PATH );
return BLERR_NOERROR;
} //end of the function AAS_LoadFiles
//===========================================================================
// called everytime a map changes
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
// Ridah, modified this for multiple AAS files
int AAS_LoadMap( const char *mapname ) {
int errnum;
int i;
char this_mapname[256]; //, intstr[4];
qboolean loaded = qfalse;
int missingErrNum = 0;
for ( i = 0; i < MAX_AAS_WORLDS; i++ )
{
AAS_SetCurrentWorld( i );
strncpy( this_mapname, mapname, 256 );
//strncat( this_mapname, "_b", 256 );
//sprintf( intstr, "%i", i );
//strncat( this_mapname, intstr, 256 );
//if no mapname is provided then the string indexes are updated
if ( !mapname ) {
return 0;
} //end if
//
( *aasworld ).initialized = qfalse;
//NOTE: free the routing caches before loading a new map because
// to free the caches the old number of areas, number of clusters
// and number of areas in a clusters must be available
AAS_FreeRoutingCaches();
//load the map
errnum = AAS_LoadFiles( this_mapname );
if ( errnum != BLERR_NOERROR ) {
( *aasworld ).loaded = qfalse;
// RF, we are allowed to skip one of the files, but not both
//return errnum;
missingErrNum = errnum;
continue;
} //end if
//
loaded = qtrue;
//
AAS_InitSettings();
//initialize the AAS link heap for the new map
AAS_InitAASLinkHeap();
//initialize the AAS linked entities for the new map
AAS_InitAASLinkedEntities();
//initialize reachability for the new map
AAS_InitReachability();
//initialize the alternative routing
AAS_InitAlternativeRouting();
}
if ( !loaded ) {
return missingErrNum;
}
//everything went ok
return 0;
} //end of the function AAS_LoadMap
// done.
//===========================================================================
// called when the library is first loaded
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_Setup( void ) {
// Ridah, just use the default world for entities
AAS_SetCurrentWorld( 0 );
( *aasworlds ).maxclients = (int) LibVarValue( "maxclients", "128" );
( *aasworlds ).maxentities = (int) LibVarValue( "maxentities", "1024" );
//allocate memory for the entities
if ( ( *aasworld ).entities ) {
FreeMemory( ( *aasworld ).entities );
}
( *aasworld ).entities = (aas_entity_t *) GetClearedHunkMemory( ( *aasworld ).maxentities * sizeof( aas_entity_t ) );
//invalidate all the entities
AAS_InvalidateEntities();
//force some recalculations
//LibVarSet("forceclustering", "1"); //force clustering calculation
//LibVarSet("forcereachability", "1"); //force reachability calculation
( *aasworld ).numframes = 0;
return BLERR_NOERROR;
} //end of the function AAS_Setup
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_Shutdown( void ) {
// Ridah, do each of the worlds
int i;
for ( i = 0; i < MAX_AAS_WORLDS; i++ )
{
AAS_SetCurrentWorld( i );
// Ridah, kill the route-table data
AAS_RT_ShutdownRouteTable();
AAS_ShutdownAlternativeRouting();
AAS_DumpBSPData();
//free routing caches
AAS_FreeRoutingCaches();
//free aas link heap
AAS_FreeAASLinkHeap();
//free aas linked entities
AAS_FreeAASLinkedEntities();
//free the aas data
AAS_DumpAASData();
if ( i == 0 ) {
//free the entities
if ( ( *aasworld ).entities ) {
FreeMemory( ( *aasworld ).entities );
}
}
//clear the (*aasworld) structure
memset( &( *aasworld ), 0, sizeof( aas_t ) );
//aas has not been initialized
( *aasworld ).initialized = qfalse;
}
//NOTE: as soon as a new .bsp file is loaded the .bsp file memory is
// freed an reallocated, so there's no need to free that memory here
//print shutdown
botimport.Print( PRT_MESSAGE, "AAS shutdown.\n" );
} //end of the function AAS_Shutdown

69
src/botlib/be_aas_main.h Normal file
View File

@@ -0,0 +1,69 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_main.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
extern aas_t( *aasworld );
//AAS error message
void QDECL AAS_Error( char *fmt, ... );
//set AAS initialized
void AAS_SetInitialized( void );
//setup AAS with the given number of entities and clients
int AAS_Setup( void );
//shutdown AAS
void AAS_Shutdown( void );
//start a new map
int AAS_LoadMap( const char *mapname );
//start a new time frame
int AAS_StartFrame( float time );
#endif //AASINTERN
//returns true if AAS is initialized
int AAS_Initialized( void );
//returns true if the AAS file is loaded
int AAS_Loaded( void );
//returns the model name from the given index
char *AAS_ModelFromIndex( int index );
//returns the index from the given model name
int AAS_IndexFromModel( char *modelname );
//returns the current time
float AAS_Time( void );
// Ridah
void AAS_SetCurrentWorld( int index );
// done.

1026
src/botlib/be_aas_move.c Normal file

File diff suppressed because it is too large Load Diff

69
src/botlib/be_aas_move.h Normal file
View File

@@ -0,0 +1,69 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_move.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
extern aas_settings_t aassettings;
#endif //AASINTERN
//movement prediction
int AAS_PredictClientMovement( struct aas_clientmove_s *move,
int entnum, vec3_t origin,
int presencetype, int onground,
vec3_t velocity, vec3_t cmdmove,
int cmdframes,
int maxframes, float frametime,
int stopevent, int stopareanum, int visualize );
//returns true if on the ground at the given origin
int AAS_OnGround( vec3_t origin, int presencetype, int passent );
//returns true if swimming at the given origin
int AAS_Swimming( vec3_t origin );
//returns the jump reachability run start point
void AAS_JumpReachRunStart( struct aas_reachability_s *reach, vec3_t runstart );
//returns true if against a ladder at the given origin
int AAS_AgainstLadder( vec3_t origin, int ms_areanum );
//rocket jump Z velocity when rocket-jumping at origin
float AAS_RocketJumpZVelocity( vec3_t origin );
//bfg jump Z velocity when bfg-jumping at origin
float AAS_BFGJumpZVelocity( vec3_t origin );
//calculates the horizontal velocity needed for a jump and returns true this velocity could be calculated
int AAS_HorizontalVelocityForJump( float zvel, vec3_t start, vec3_t end, float *velocity );
//
void AAS_SetMovedir( vec3_t angles, vec3_t movedir );
//
int AAS_DropToFloor( vec3_t origin, vec3_t mins, vec3_t maxs );
//
void AAS_InitSettings( void );

View File

@@ -0,0 +1,657 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_optimize.c
*
* desc: decreases the .aas file size after the reachabilities have
* been calculated, just dumps all the faces, edges and vertexes
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_libvar.h"
//#include "l_utils.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
typedef struct optimized_s
{
//vertixes
int numvertexes;
aas_vertex_t *vertexes;
//edges
int numedges;
aas_edge_t *edges;
//edge index
int edgeindexsize;
aas_edgeindex_t *edgeindex;
//faces
int numfaces;
aas_face_t *faces;
//face index
int faceindexsize;
aas_faceindex_t *faceindex;
//convex areas
int numareas;
aas_area_t *areas;
///
// RF, addition of removal of non-reachability areas
//
//convex area settings
int numareasettings;
aas_areasettings_t *areasettings;
//reachablity list
int reachabilitysize;
aas_reachability_t *reachability;
/* //nodes of the bsp tree
int numnodes;
aas_node_t *nodes;
//cluster portals
int numportals;
aas_portal_t *portals;
//clusters
int numclusters;
aas_cluster_t *clusters;
*/ //
int *vertexoptimizeindex;
int *edgeoptimizeindex;
int *faceoptimizeindex;
//
int *areakeep;
int *arearemap;
int *removedareas;
int *reachabilityremap;
} optimized_t;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_KeepEdge( aas_edge_t *edge ) {
return 1;
} //end of the function AAS_KeepFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_OptimizeEdge( optimized_t *optimized, int edgenum ) {
int i, optedgenum;
aas_edge_t *edge, *optedge;
edge = &( *aasworld ).edges[abs( edgenum )];
if ( !AAS_KeepEdge( edge ) ) {
return 0;
}
optedgenum = optimized->edgeoptimizeindex[abs( edgenum )];
if ( optedgenum ) {
//keep the edge reversed sign
if ( edgenum > 0 ) {
return optedgenum;
} else { return -optedgenum;}
} //end if
optedge = &optimized->edges[optimized->numedges];
for ( i = 0; i < 2; i++ )
{
if ( optimized->vertexoptimizeindex[edge->v[i]] ) {
optedge->v[i] = optimized->vertexoptimizeindex[edge->v[i]];
} //end if
else
{
VectorCopy( ( *aasworld ).vertexes[edge->v[i]], optimized->vertexes[optimized->numvertexes] );
optedge->v[i] = optimized->numvertexes;
optimized->vertexoptimizeindex[edge->v[i]] = optimized->numvertexes;
optimized->numvertexes++;
} //end else
} //end for
optimized->edgeoptimizeindex[abs( edgenum )] = optimized->numedges;
optedgenum = optimized->numedges;
optimized->numedges++;
//keep the edge reversed sign
if ( edgenum > 0 ) {
return optedgenum;
} else { return -optedgenum;}
} //end of the function AAS_OptimizeEdge
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_KeepFace( aas_face_t *face ) {
if ( !( face->faceflags & FACE_LADDER ) ) {
return 0;
} else { return 1;}
} //end of the function AAS_KeepFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_OptimizeFace( optimized_t *optimized, int facenum ) {
int i, edgenum, optedgenum, optfacenum;
aas_face_t *face, *optface;
face = &( *aasworld ).faces[abs( facenum )];
if ( !AAS_KeepFace( face ) ) {
return 0;
}
optfacenum = optimized->faceoptimizeindex[abs( facenum )];
if ( optfacenum ) {
//keep the face side sign
if ( facenum > 0 ) {
return optfacenum;
} else { return -optfacenum;}
} //end if
optface = &optimized->faces[optimized->numfaces];
memcpy( optface, face, sizeof( aas_face_t ) );
optface->numedges = 0;
optface->firstedge = optimized->edgeindexsize;
for ( i = 0; i < face->numedges; i++ )
{
edgenum = ( *aasworld ).edgeindex[face->firstedge + i];
optedgenum = AAS_OptimizeEdge( optimized, edgenum );
if ( optedgenum ) {
optimized->edgeindex[optface->firstedge + optface->numedges] = optedgenum;
optface->numedges++;
optimized->edgeindexsize++;
} //end if
} //end for
optimized->faceoptimizeindex[abs( facenum )] = optimized->numfaces;
optfacenum = optimized->numfaces;
optimized->numfaces++;
//keep the face side sign
if ( facenum > 0 ) {
return optfacenum;
} else { return -optfacenum;}
} //end of the function AAS_OptimizeFace
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_OptimizeArea( optimized_t *optimized, int areanum ) {
int i, facenum, optfacenum;
aas_area_t *area, *optarea;
area = &( *aasworld ).areas[areanum];
optarea = &optimized->areas[areanum];
memcpy( optarea, area, sizeof( aas_area_t ) );
optarea->numfaces = 0;
optarea->firstface = optimized->faceindexsize;
for ( i = 0; i < area->numfaces; i++ )
{
facenum = ( *aasworld ).faceindex[area->firstface + i];
optfacenum = AAS_OptimizeFace( optimized, facenum );
if ( optfacenum ) {
optimized->faceindex[optarea->firstface + optarea->numfaces] = optfacenum;
optarea->numfaces++;
optimized->faceindexsize++;
} //end if
} //end for
} //end of the function AAS_OptimizeArea
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_OptimizeAlloc( optimized_t *optimized ) {
optimized->vertexes = (aas_vertex_t *) GetClearedMemory( ( *aasworld ).numvertexes * sizeof( aas_vertex_t ) );
optimized->numvertexes = 0;
optimized->edges = (aas_edge_t *) GetClearedMemory( ( *aasworld ).numedges * sizeof( aas_edge_t ) );
optimized->numedges = 1; //edge zero is a dummy
optimized->edgeindex = (aas_edgeindex_t *) GetClearedMemory( ( *aasworld ).edgeindexsize * sizeof( aas_edgeindex_t ) );
optimized->edgeindexsize = 0;
optimized->faces = (aas_face_t *) GetClearedMemory( ( *aasworld ).numfaces * sizeof( aas_face_t ) );
optimized->numfaces = 1; //face zero is a dummy
optimized->faceindex = (aas_faceindex_t *) GetClearedMemory( ( *aasworld ).faceindexsize * sizeof( aas_faceindex_t ) );
optimized->faceindexsize = 0;
optimized->areas = (aas_area_t *) GetClearedMemory( ( *aasworld ).numareas * sizeof( aas_area_t ) );
optimized->numareas = ( *aasworld ).numareas;
//
optimized->vertexoptimizeindex = (int *) GetClearedMemory( ( *aasworld ).numvertexes * sizeof( int ) );
optimized->edgeoptimizeindex = (int *) GetClearedMemory( ( *aasworld ).numedges * sizeof( int ) );
optimized->faceoptimizeindex = (int *) GetClearedMemory( ( *aasworld ).numfaces * sizeof( int ) );
} //end of the function AAS_OptimizeAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_OptimizeStore( optimized_t *optimized ) {
//store the optimized vertexes
if ( ( *aasworld ).vertexes ) {
FreeMemory( ( *aasworld ).vertexes );
}
( *aasworld ).vertexes = optimized->vertexes;
( *aasworld ).numvertexes = optimized->numvertexes;
//store the optimized edges
if ( ( *aasworld ).edges ) {
FreeMemory( ( *aasworld ).edges );
}
( *aasworld ).edges = optimized->edges;
( *aasworld ).numedges = optimized->numedges;
//store the optimized edge index
if ( ( *aasworld ).edgeindex ) {
FreeMemory( ( *aasworld ).edgeindex );
}
( *aasworld ).edgeindex = optimized->edgeindex;
( *aasworld ).edgeindexsize = optimized->edgeindexsize;
//store the optimized faces
if ( ( *aasworld ).faces ) {
FreeMemory( ( *aasworld ).faces );
}
( *aasworld ).faces = optimized->faces;
( *aasworld ).numfaces = optimized->numfaces;
//store the optimized face index
if ( ( *aasworld ).faceindex ) {
FreeMemory( ( *aasworld ).faceindex );
}
( *aasworld ).faceindex = optimized->faceindex;
( *aasworld ).faceindexsize = optimized->faceindexsize;
//store the optimized areas
if ( ( *aasworld ).areas ) {
FreeMemory( ( *aasworld ).areas );
}
( *aasworld ).areas = optimized->areas;
( *aasworld ).numareas = optimized->numareas;
//free optimize indexes
FreeMemory( optimized->vertexoptimizeindex );
FreeMemory( optimized->edgeoptimizeindex );
FreeMemory( optimized->faceoptimizeindex );
} //end of the function AAS_OptimizeStore
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_Optimize( void ) {
int i, sign;
optimized_t optimized;
AAS_OptimizeAlloc( &optimized );
for ( i = 1; i < ( *aasworld ).numareas; i++ )
{
AAS_OptimizeArea( &optimized, i );
} //end for
//reset the reachability face pointers
for ( i = 0; i < ( *aasworld ).reachabilitysize; i++ )
{
//NOTE: for TRAVEL_ELEVATOR the facenum is the model number of
// the elevator
if ( ( *aasworld ).reachability[i].traveltype == TRAVEL_ELEVATOR ) {
continue;
}
//NOTE: for TRAVEL_JUMPPAD the facenum is the Z velocity and the edgenum is the hor velocity
if ( ( *aasworld ).reachability[i].traveltype == TRAVEL_JUMPPAD ) {
continue;
}
//NOTE: for TRAVEL_FUNCBOB the facenum and edgenum contain other coded information
if ( ( *aasworld ).reachability[i].traveltype == TRAVEL_FUNCBOB ) {
continue;
}
//
sign = ( *aasworld ).reachability[i].facenum;
( *aasworld ).reachability[i].facenum = optimized.faceoptimizeindex[abs( ( *aasworld ).reachability[i].facenum )];
if ( sign < 0 ) {
( *aasworld ).reachability[i].facenum = -( *aasworld ).reachability[i].facenum;
}
sign = ( *aasworld ).reachability[i].edgenum;
( *aasworld ).reachability[i].edgenum = optimized.edgeoptimizeindex[abs( ( *aasworld ).reachability[i].edgenum )];
if ( sign < 0 ) {
( *aasworld ).reachability[i].edgenum = -( *aasworld ).reachability[i].edgenum;
}
} //end for
//store the optimized AAS data into (*aasworld)
AAS_OptimizeStore( &optimized );
//print some nice stuff :)
botimport.Print( PRT_MESSAGE, "AAS data optimized.\n" );
} //end of the function AAS_Optimize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_RemoveNonReachabilityAlloc( optimized_t *optimized ) {
optimized->areas = (aas_area_t *) GetClearedMemory( ( *aasworld ).numareas * sizeof( aas_area_t ) );
//
optimized->areasettings = (aas_areasettings_t *) GetClearedMemory( ( *aasworld ).numareas * sizeof( aas_areasettings_t ) );
//
optimized->reachability = (aas_reachability_t *) GetClearedMemory( ( *aasworld ).reachabilitysize * sizeof( aas_reachability_t ) );
optimized->reachabilitysize = ( *aasworld ).reachabilitysize;
/* //
optimized->nodes = (aas_node_t *) GetClearedMemory((*aasworld).numnodes * sizeof(aas_node_t));
optimized->numnodes = (*aasworld).numnodes;
//
optimized->portals = (aas_portals_t *) GetClearedMemory((*aasworld).numportals * sizeof(aas_portal_t));
optimized->numportals = (*aasworld).numportals;
//
optimized->clusters = (aas_cluster_t *) GetClearedMemory((*aasworld).numclusters * sizeof(aas_cluster_t));
optimized->numclusters = (*aasworld).numclusters;
*/ //
optimized->areakeep = (int *) GetClearedMemory( ( *aasworld ).numareas * sizeof( int ) );
optimized->arearemap = (int *) GetClearedMemory( ( *aasworld ).numareas * sizeof( int ) );
optimized->removedareas = (int *) GetClearedMemory( ( *aasworld ).numareas * sizeof( int ) );
optimized->reachabilityremap = (int *) GetClearedMemory( ( *aasworld ).reachabilitysize * sizeof( int ) );
} //end of the function AAS_OptimizeAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_NumberClusterAreas( int clusternum );
void AAS_RemoveNonReachability( void ) {
int i, j;
optimized_t optimized;
int removed = 0, valid = 0, numoriginalareas;
int validreach = 0;
aas_face_t *face;
AAS_RemoveNonReachabilityAlloc( &optimized );
// mark portal areas as non-removable
if ( aasworld->numportals ) {
for ( i = 0; i < aasworld->numportals; i++ )
{
optimized.areakeep[aasworld->portals[i].areanum] = qtrue;
}
}
// remove non-reachability areas
numoriginalareas = aasworld->numareas;
for ( i = 1; i < ( *aasworld ).numareas; i++ )
{
// is this a reachability area?
if ( optimized.areakeep[i] || aasworld->areasettings[i].numreachableareas ) {
optimized.arearemap[i] = ++valid;
// copy it to the optimized areas
optimized.areas[valid] = ( *aasworld ).areas[i];
optimized.areas[valid].areanum = valid;
continue;
}
// yes it is if it made it to here
removed++;
optimized.removedareas[i] = qtrue;
}
optimized.numareas = valid + 1;
// store the new areas
if ( ( *aasworld ).areas ) {
FreeMemory( ( *aasworld ).areas );
}
( *aasworld ).areas = optimized.areas;
( *aasworld ).numareas = optimized.numareas;
//
// remove reachabilities that are no longer required
validreach = 1;
for ( i = 1; i < aasworld->reachabilitysize; i++ )
{
optimized.reachabilityremap[i] = validreach;
if ( optimized.removedareas[aasworld->reachability[i].areanum] ) {
continue;
}
// save this reachability
optimized.reachability[validreach] = aasworld->reachability[i];
optimized.reachability[validreach].areanum = optimized.arearemap[optimized.reachability[validreach].areanum];
//
validreach++;
}
optimized.reachabilitysize = validreach;
// store the reachabilities
if ( ( *aasworld ).reachability ) {
FreeMemory( ( *aasworld ).reachability );
}
( *aasworld ).reachability = optimized.reachability;
( *aasworld ).reachabilitysize = optimized.reachabilitysize;
//
// remove and update areasettings
for ( i = 1; i < numoriginalareas; i++ )
{
if ( optimized.removedareas[i] ) {
continue;
}
j = optimized.arearemap[i];
optimized.areasettings[j] = aasworld->areasettings[i];
optimized.areasettings[j].firstreachablearea = optimized.reachabilityremap[aasworld->areasettings[i].firstreachablearea];
optimized.areasettings[j].numreachableareas = 1 + optimized.reachabilityremap[aasworld->areasettings[i].firstreachablearea + aasworld->areasettings[i].numreachableareas - 1] - optimized.areasettings[j].firstreachablearea;
}
//
// update faces (TODO: remove unused)
for ( i = 1, face = &aasworld->faces[1]; i < aasworld->numfaces; i++, face++ )
{
if ( !optimized.removedareas[face->backarea] ) {
face->backarea = optimized.arearemap[face->backarea];
} else { // now points to a void
face->backarea = 0;
}
if ( !optimized.removedareas[face->frontarea] ) {
face->frontarea = optimized.arearemap[face->frontarea];
} else {
face->frontarea = 0;
}
}
// store the areasettings
if ( ( *aasworld ).areasettings ) {
FreeMemory( ( *aasworld ).areasettings );
}
( *aasworld ).areasettings = optimized.areasettings;
( *aasworld ).numareasettings = optimized.numareas;
//
// update nodes
for ( i = 1; i < ( *aasworld ).numnodes; i++ )
{
for ( j = 0; j < 2; j++ )
{
if ( aasworld->nodes[i].children[j] < 0 ) {
if ( optimized.removedareas[-aasworld->nodes[i].children[j]] ) {
aasworld->nodes[i].children[j] = 0; //make it solid
} else { // remap
aasworld->nodes[i].children[j] = -optimized.arearemap[-aasworld->nodes[i].children[j]];
}
}
}
}
//
// update portal areanums
for ( i = 0; i < aasworld->numportals; i++ )
{
aasworld->portals[i].areanum = optimized.arearemap[aasworld->portals[i].areanum];
}
// update clusters and portals
for ( i = 0; i < ( *aasworld ).numclusters; i++ )
{
AAS_NumberClusterAreas( i );
}
// free temporary memory
FreeMemory( optimized.areakeep );
FreeMemory( optimized.arearemap );
FreeMemory( optimized.removedareas );
FreeMemory( optimized.reachabilityremap );
//print some nice stuff :)
botimport.Print( PRT_MESSAGE, "%i non-reachability areas removed, %i remain.\n", removed, valid );
} //end of the function AAS_Optimize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_RemoveNonGrounded( void ) {
int i, j;
optimized_t optimized;
int removed = 0, valid = 0, numoriginalareas;
int validreach = 0;
aas_face_t *face;
AAS_RemoveNonReachabilityAlloc( &optimized );
// mark portal areas as non-removable
if ( aasworld->numportals ) {
for ( i = 0; i < aasworld->numportals; i++ )
{
optimized.areakeep[aasworld->portals[i].areanum] = qtrue;
}
}
// remove non-reachability areas
numoriginalareas = aasworld->numareas;
for ( i = 1; i < ( *aasworld ).numareas; i++ )
{
// is this a grounded area?
if ( optimized.areakeep[i] || ( aasworld->areasettings[i].areaflags & ( AREA_GROUNDED | AREA_LADDER ) ) ) {
optimized.arearemap[i] = ++valid;
// copy it to the optimized areas
optimized.areas[valid] = ( *aasworld ).areas[i];
optimized.areas[valid].areanum = valid;
continue;
}
// yes it is if it made it to here
removed++;
optimized.removedareas[i] = qtrue;
}
optimized.numareas = valid + 1;
// store the new areas
if ( ( *aasworld ).areas ) {
FreeMemory( ( *aasworld ).areas );
}
( *aasworld ).areas = optimized.areas;
( *aasworld ).numareas = optimized.numareas;
//
// remove reachabilities that are no longer required
validreach = 1;
for ( i = 1; i < aasworld->reachabilitysize; i++ )
{
optimized.reachabilityremap[i] = validreach;
if ( optimized.removedareas[aasworld->reachability[i].areanum] ) {
continue;
}
// save this reachability
optimized.reachability[validreach] = aasworld->reachability[i];
optimized.reachability[validreach].areanum = optimized.arearemap[optimized.reachability[validreach].areanum];
//
validreach++;
}
optimized.reachabilitysize = validreach;
// store the reachabilities
if ( ( *aasworld ).reachability ) {
FreeMemory( ( *aasworld ).reachability );
}
( *aasworld ).reachability = optimized.reachability;
( *aasworld ).reachabilitysize = optimized.reachabilitysize;
//
// remove and update areasettings
for ( i = 1; i < numoriginalareas; i++ )
{
if ( optimized.removedareas[i] ) {
continue;
}
j = optimized.arearemap[i];
optimized.areasettings[j] = aasworld->areasettings[i];
optimized.areasettings[j].firstreachablearea = optimized.reachabilityremap[aasworld->areasettings[i].firstreachablearea];
optimized.areasettings[j].numreachableareas = 1 + optimized.reachabilityremap[aasworld->areasettings[i].firstreachablearea + aasworld->areasettings[i].numreachableareas - 1] - optimized.areasettings[j].firstreachablearea;
}
//
// update faces (TODO: remove unused)
for ( i = 1, face = &aasworld->faces[1]; i < aasworld->numfaces; i++, face++ )
{
if ( !optimized.removedareas[face->backarea] ) {
face->backarea = optimized.arearemap[face->backarea];
} else { // now points to a void
face->backarea = 0;
}
if ( !optimized.removedareas[face->frontarea] ) {
face->frontarea = optimized.arearemap[face->frontarea];
} else {
face->frontarea = 0;
}
}
// store the areasettings
if ( ( *aasworld ).areasettings ) {
FreeMemory( ( *aasworld ).areasettings );
}
( *aasworld ).areasettings = optimized.areasettings;
( *aasworld ).numareasettings = optimized.numareas;
//
// update nodes
for ( i = 1; i < ( *aasworld ).numnodes; i++ )
{
for ( j = 0; j < 2; j++ )
{
if ( aasworld->nodes[i].children[j] < 0 ) {
if ( optimized.removedareas[-aasworld->nodes[i].children[j]] ) {
aasworld->nodes[i].children[j] = 0; //make it solid
} else { // remap
aasworld->nodes[i].children[j] = -optimized.arearemap[-aasworld->nodes[i].children[j]];
}
}
}
}
//
// update portal areanums
for ( i = 0; i < aasworld->numportals; i++ )
{
aasworld->portals[i].areanum = optimized.arearemap[aasworld->portals[i].areanum];
}
// update clusters and portals
for ( i = 0; i < ( *aasworld ).numclusters; i++ )
{
AAS_NumberClusterAreas( i );
}
// free temporary memory
FreeMemory( optimized.areakeep );
FreeMemory( optimized.arearemap );
FreeMemory( optimized.removedareas );
FreeMemory( optimized.reachabilityremap );
//print some nice stuff :)
botimport.Print( PRT_MESSAGE, "%i non-grounded areas removed, %i remain.\n", removed, valid );
} //end of the function AAS_Optimize

View File

@@ -0,0 +1,40 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_optimize.h
*
* desc: AAS
*
*
*****************************************************************************/
void AAS_Optimize( void );
void AAS_RemoveNonReachability( void );
void AAS_RemoveNonGrounded( void );

4634
src/botlib/be_aas_reach.c Normal file

File diff suppressed because it is too large Load Diff

80
src/botlib/be_aas_reach.h Normal file
View File

@@ -0,0 +1,80 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_reach.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
//initialize calculating the reachabilities
void AAS_InitReachability( void );
//continue calculating the reachabilities
int AAS_ContinueInitReachability( float time );
//
int AAS_BestReachableLinkArea( aas_link_t *areas );
#endif //AASINTERN
//returns true if the are has reachabilities to other areas
int AAS_AreaReachability( int areanum );
//returns the best reachable area and goal origin for a bounding box at the given origin
int AAS_BestReachableArea( vec3_t origin, vec3_t mins, vec3_t maxs, vec3_t goalorigin );
//returns the next reachability using the given model
int AAS_NextModelReachability( int num, int modelnum );
//returns the total area of the ground faces of the given area
float AAS_AreaGroundFaceArea( int areanum );
//returns true if the area is crouch only
//int AAS_AreaCrouch(int areanum);
#define AAS_AreaCrouch( areanum ) ( ( !( aasworld->areasettings[areanum].presencetype & PRESENCE_NORMAL ) ) ? qtrue : qfalse )
//returns true if a player can swim in this area
//int AAS_AreaSwim(int areanum);
#define AAS_AreaSwim( areanum ) ( ( aasworld->areasettings[areanum].areaflags & AREA_LIQUID ) ? qtrue : qfalse )
//returns true if the area is filled with a liquid
int AAS_AreaLiquid( int areanum );
//returns true if the area contains lava
int AAS_AreaLava( int areanum );
//returns true if the area contains slime
int AAS_AreaSlime( int areanum );
//returns true if the area has one or more ground faces
int AAS_AreaGrounded( int areanum );
//returns true if the area has one or more ladder faces
int AAS_AreaLadder( int areanum );
//returns true if the area is a jump pad
int AAS_AreaJumpPad( int areanum );
//returns true if the area is donotenter
int AAS_AreaDoNotEnter( int areanum );
//returns true if the area is donotenterlarge
int AAS_AreaDoNotEnterLarge( int areanum );

3704
src/botlib/be_aas_route.c Normal file

File diff suppressed because it is too large Load Diff

68
src/botlib/be_aas_route.h Normal file
View File

@@ -0,0 +1,68 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_route.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
//initialize the AAS routing
void AAS_InitRouting( void );
//free the AAS routing caches
void AAS_FreeRoutingCaches( void );
//returns the travel time from start to end in the given area
unsigned short int AAS_AreaTravelTime( int areanum, vec3_t start, vec3_t end );
//
void AAS_CreateAllRoutingCache( void );
//
void AAS_RoutingInfo( void );
#endif //AASINTERN
//returns the travel flag for the given travel type
int AAS_TravelFlagForType( int traveltype );
//
int AAS_AreaContentsTravelFlag( int areanum );
//returns the index of the next reachability for the given area
int AAS_NextAreaReachability( int areanum, int reachnum );
//returns the reachability with the given index
void AAS_ReachabilityFromNum( int num, struct aas_reachability_s *reach );
//returns a random goal area and goal origin
int AAS_RandomGoalArea( int areanum, int travelflags, int *goalareanum, vec3_t goalorigin );
//returns the travel time within the given area from start to end
unsigned short int AAS_AreaTravelTime( int areanum, vec3_t start, vec3_t end );
//returns the travel time from the area to the goal area using the given travel flags
int AAS_AreaTravelTimeToGoalArea( int areanum, vec3_t origin, int goalareanum, int travelflags );
void AAS_InitTeamDeath( void );
void AAS_RecordTeamDeathArea( vec3_t srcpos, int srcarea, int team, int teamCount, int travelflags );
void AAS_UpdateTeamDeath( void );

View File

@@ -0,0 +1,294 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_routealt.c
*
* desc: AAS
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_utils.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_aas_def.h"
#define ENABLE_ALTROUTING
typedef struct midrangearea_s
{
int valid;
unsigned short starttime;
unsigned short goaltime;
} midrangearea_t;
midrangearea_t *midrangeareas;
int *clusterareas;
int numclusterareas;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_AltRoutingFloodCluster_r( int areanum ) {
int i, otherareanum;
aas_area_t *area;
aas_face_t *face;
//add the current area to the areas of the current cluster
clusterareas[numclusterareas] = areanum;
numclusterareas++;
//remove the area from the mid range areas
midrangeareas[areanum].valid = qfalse;
//flood to other areas through the faces of this area
area = &( *aasworld ).areas[areanum];
for ( i = 0; i < area->numfaces; i++ )
{
face = &( *aasworld ).faces[abs( ( *aasworld ).faceindex[area->firstface + i] )];
//get the area at the other side of the face
if ( face->frontarea == areanum ) {
otherareanum = face->backarea;
} else { otherareanum = face->frontarea;}
//if there is an area at the other side of this face
if ( !otherareanum ) {
continue;
}
//if the other area is not a midrange area
if ( !midrangeareas[otherareanum].valid ) {
continue;
}
//
AAS_AltRoutingFloodCluster_r( otherareanum );
} //end for
} //end of the function AAS_AltRoutingFloodCluster_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_AreaRouteToGoalArea( int areanum, vec3_t origin, int goalareanum, int travelflags, int *traveltime, int *reachnum );
int AAS_AlternativeRouteGoals( vec3_t start, vec3_t goal, int travelflags,
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
int color ) {
#ifndef ENABLE_ALTROUTING
return 0;
#else
int i, j, startareanum, goalareanum, bestareanum;
int numaltroutegoals, nummidrangeareas;
int starttime, goaltime, goaltraveltime;
float dist, bestdist;
vec3_t mid, dir;
int reachnum, time;
int a1, a2;
/*#ifdef DEBUG
int startmillisecs;
startmillisecs = Sys_MilliSeconds();
#endif*/
startareanum = AAS_PointAreaNum( start );
if ( !startareanum ) {
return 0;
}
goalareanum = AAS_PointAreaNum( goal );
if ( !goalareanum ) {
VectorCopy( goal, dir );
dir[2] += 30;
goalareanum = AAS_PointAreaNum( dir );
if ( !goalareanum ) {
return 0;
}
}
//travel time towards the goal area
goaltraveltime = AAS_AreaTravelTimeToGoalArea( startareanum, start, goalareanum, travelflags );
//clear the midrange areas
memset( midrangeareas, 0, ( *aasworld ).numareas * sizeof( midrangearea_t ) );
numaltroutegoals = 0;
//
nummidrangeareas = 0;
//
for ( i = 1; i < ( *aasworld ).numareas; i++ )
{
//
if ( !( ( *aasworld ).areasettings[i].contents & AREACONTENTS_ROUTEPORTAL ) &&
!( ( *aasworld ).areasettings[i].contents & AREACONTENTS_CLUSTERPORTAL ) ) {
continue;
}
//if the area has no reachabilities
if ( !AAS_AreaReachability( i ) ) {
continue;
}
//tavel time from the area to the start area
starttime = AAS_AreaTravelTimeToGoalArea( startareanum, start, i, travelflags );
if ( !starttime ) {
continue;
}
//if the travel time from the start to the area is greater than the shortest goal travel time
if ( starttime > 500 + 3.0 * goaltraveltime ) {
continue;
}
//travel time from the area to the goal area
goaltime = AAS_AreaTravelTimeToGoalArea( i, NULL, goalareanum, travelflags );
if ( !goaltime ) {
continue;
}
//if the travel time from the area to the goal is greater than the shortest goal travel time
if ( goaltime > 500 + 3.0 * goaltraveltime ) {
continue;
}
//this is a mid range area
midrangeareas[i].valid = qtrue;
midrangeareas[i].starttime = starttime;
midrangeareas[i].goaltime = goaltime;
Log_Write( "%d midrange area %d", nummidrangeareas, i );
nummidrangeareas++;
} //end for
//
for ( i = 1; i < ( *aasworld ).numareas; i++ )
{
if ( !midrangeareas[i].valid ) {
continue;
}
//get the areas in one cluster
numclusterareas = 0;
AAS_AltRoutingFloodCluster_r( i );
//now we've got a cluster with areas through which an alternative route could go
//get the 'center' of the cluster
VectorClear( mid );
for ( j = 0; j < numclusterareas; j++ )
{
VectorAdd( mid, ( *aasworld ).areas[clusterareas[j]].center, mid );
} //end for
VectorScale( mid, 1.0 / numclusterareas, mid );
//get the area closest to the center of the cluster
bestdist = 999999;
bestareanum = 0;
for ( j = 0; j < numclusterareas; j++ )
{
VectorSubtract( mid, ( *aasworld ).areas[clusterareas[j]].center, dir );
dist = VectorLength( dir );
if ( dist < bestdist ) {
bestdist = dist;
bestareanum = clusterareas[j];
} //end if
} //end for
// make sure the route to the destination isn't in the same direction as the route to the source
if ( !AAS_AreaRouteToGoalArea( bestareanum, ( *aasworld ).areawaypoints[bestareanum], goalareanum, travelflags, &time, &reachnum ) ) {
continue;
}
a1 = ( *aasworld ).reachability[reachnum].areanum;
if ( !AAS_AreaRouteToGoalArea( bestareanum, ( *aasworld ).areawaypoints[bestareanum], startareanum, travelflags, &time, &reachnum ) ) {
continue;
}
a2 = ( *aasworld ).reachability[reachnum].areanum;
if ( a1 == a2 ) {
continue;
}
//now we've got an area for an alternative route
//FIXME: add alternative goal origin
VectorCopy( ( *aasworld ).areawaypoints[bestareanum], altroutegoals[numaltroutegoals].origin );
altroutegoals[numaltroutegoals].areanum = bestareanum;
altroutegoals[numaltroutegoals].starttraveltime = midrangeareas[bestareanum].starttime;
altroutegoals[numaltroutegoals].goaltraveltime = midrangeareas[bestareanum].goaltime;
altroutegoals[numaltroutegoals].extratraveltime =
( midrangeareas[bestareanum].starttime + midrangeareas[bestareanum].goaltime ) -
goaltraveltime;
numaltroutegoals++;
//
/*#ifdef DEBUG
botimport.Print(PRT_MESSAGE, "alternative route goal area %d, numclusterareas = %d\n", bestareanum, numclusterareas);
if (color)
{
AAS_DrawPermanentCross((*aasworld).areas[bestareanum].center, 10, color);
} //end if
//AAS_ShowArea(bestarea, qtrue);
#endif*/
//don't return more than the maximum alternative route goals
if ( numaltroutegoals >= maxaltroutegoals ) {
break;
}
} //end for
//botimport.Print(PRT_MESSAGE, "%d alternative route goals\n", numaltroutegoals);
#ifdef DEBUG
// botimport.Print(PRT_MESSAGE, "alternative route goals in %d msec\n", Sys_MilliSeconds() - startmillisecs);
#endif
return numaltroutegoals;
#endif
} //end of the function AAS_AlternativeRouteGoals
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_InitAlternativeRouting( void ) {
#ifdef ENABLE_ALTROUTING
if ( midrangeareas ) {
FreeMemory( midrangeareas );
}
midrangeareas = (midrangearea_t *) GetMemory( ( *aasworld ).numareas * sizeof( midrangearea_t ) );
if ( clusterareas ) {
FreeMemory( clusterareas );
}
clusterareas = (int *) GetMemory( ( *aasworld ).numareas * sizeof( int ) );
#endif
} //end of the function AAS_InitAlternativeRouting
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_ShutdownAlternativeRouting( void ) {
#ifdef ENABLE_ALTROUTING
if ( midrangeareas ) {
FreeMemory( midrangeareas );
}
midrangeareas = NULL;
if ( clusterareas ) {
FreeMemory( clusterareas );
}
clusterareas = NULL;
numclusterareas = 0;
#endif
}

View File

@@ -0,0 +1,46 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_routealt.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
void AAS_InitAlternativeRouting( void );
void AAS_ShutdownAlternativeRouting( void );
#endif //AASINTERN
int AAS_AlternativeRouteGoals( vec3_t start, vec3_t goal, int travelflags,
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
int color );

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,171 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: be_aas_routetable.h
// Function: Area Awareness System, Route-table defines
// Programmer: Ridah
// Tab Size: 3
//===========================================================================
#ifndef RT_DEFINED
#define RT_DEFINED
#define RTBID ( ( 'B' << 24 ) + ( 'T' << 16 ) + ( 'R' << 8 ) + 'X' )
#define RTBVERSION 17
#define RTB_BADTRAVELFLAGS ( TFL_JUMPPAD | TFL_ROCKETJUMP | TFL_BFGJUMP | TFL_GRAPPLEHOOK | TFL_DOUBLEJUMP | TFL_RAMPJUMP | TFL_STRAFEJUMP | TFL_LAVA ) //----(SA) modified since slime is no longer deadly
//#define RTB_BADTRAVELFLAGS (TFL_JUMPPAD|TFL_ROCKETJUMP|TFL_BFGJUMP|TFL_GRAPPLEHOOK|TFL_DOUBLEJUMP|TFL_RAMPJUMP|TFL_STRAFEJUMP|TFL_SLIME|TFL_LAVA)
#define MAX_VISIBLE_AREAS 1024 // going over this limit will result in excessive memory usage, try and keep RANGE low enough so this limit won't be reached
#define MAX_LOCALTRAVELTIME 60 // use this to tweak memory usage (reduces parent count, increases local count (and cpu usage) - find a balance)
#define MAX_PARENTS 8192
extern int disable_routetable;
//....................................................................
// Permanent structures (in order of highest to lowest count)
typedef struct
{
unsigned short int reachable_index; // reachability index (from this area's first reachability link in the world) to head for to get to the destination
unsigned short int travel_time; // travel time (!)
} aas_rt_route_t;
typedef struct
{
unsigned short int parent; // parent we belong to
unsigned short int childIndex; // our index in the parent's list of children
// unsigned short int numRouteIndexes;
// int startRouteIndexes;
} aas_rt_parent_link_t;
typedef struct
{
unsigned short int areanum;
// int numLocalRoutes;
// int startLocalRoutes;
// int numParentRoutes;
// int startParentRoutes;
int numParentLinks;
int startParentLinks;
} aas_rt_child_t;
typedef struct
{
unsigned short int areanum; // out area number in the global list
int numParentChildren;
int startParentChildren;
int numVisibleParents;
int startVisibleParents; // list of other parents that we can see (used for fast hide/retreat checks)
// int startParentTravelTimes;
} aas_rt_parent_t;
// this is what each aasworld attaches itself to
typedef struct
{
unsigned short int *areaChildIndexes; // each aas area that is part of the Route-Table has a pointer here to their position in the list of children
int numChildren;
aas_rt_child_t *children;
int numParents;
aas_rt_parent_t *parents;
int numParentChildren;
unsigned short int *parentChildren;
int numVisibleParents;
unsigned short int *visibleParents;
// int numLocalRoutes;
// aas_rt_route_t *localRoutes; // the list of routes to all other local areas
// int numParentRoutes;
// unsigned char *parentRoutes; // reachability to each other parent, as an offset from our first reachability
int numParentLinks;
aas_rt_parent_link_t *parentLinks; // links from each child to the parent's it belongs to
// int numParentTravelTimes;
// unsigned short int *parentTravelTimes; // travel times between all parent areas
// int numRouteIndexes;
// unsigned short int *routeIndexes; // each parentLink has a list within here, which
// contains the local indexes of each child that
// belongs to the parent, within the source child's
// localroutes
} aas_rt_t;
//....................................................................
// Temp structures used only during route-table contruction
typedef struct
{
unsigned short int numvisible; // number of areas that are visible and within range
unsigned short int
visible[MAX_VISIBLE_AREAS]; // list of area indexes of visible and within range areas
} aas_area_buildlocalinfo_t;
typedef struct aas_parent_link_s
{
unsigned short int parent; // parent we belong to
unsigned short int childindex; // our index in the parent's list of children
unsigned short int *routeindexes; // for this parent link, list the children that fall under that parent, and their associated indexes in our localroutes table
struct aas_parent_link_s *next;
} aas_parent_link_t;
typedef struct
{
unsigned short int areanum;
unsigned short int numlocal;
aas_parent_link_t *parentlink; // linked list of parents that we belong to
aas_rt_route_t *localroutes; // the list of routes to all other local areas
aas_rt_route_t *parentroutes; // the list of routes to all other parent areas
} aas_area_childlocaldata_t;
typedef struct
{
unsigned short int areanum; // out area number in the global list
unsigned short int numchildren;
unsigned short int *children;
unsigned short int numVisibleParents;
unsigned short int *visibleParents; // list of other parents that we can see (used for fast hide/retreat checks)
} aas_area_parent_t;
#endif // RT_DEFINED
//....................................................................
void AAS_RT_BuildRouteTable( void );
void AAS_RT_ShowRoute( vec3_t srcpos, int srcnum, int destnum );
aas_rt_route_t *AAS_RT_GetRoute( int srcnum, vec3_t origin, int destnum );
void AAS_RT_ShutdownRouteTable( void );
qboolean AAS_RT_GetHidePos( vec3_t srcpos, int srcnum, int srcarea, vec3_t destpos, int destnum, int destarea, vec3_t returnPos );
int AAS_RT_GetReachabilityIndex( int areanum, int reachIndex );

1482
src/botlib/be_aas_sample.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,72 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_aas_sample.h
*
* desc: AAS
*
*
*****************************************************************************/
#ifdef AASINTERN
void AAS_InitAASLinkHeap( void );
void AAS_InitAASLinkedEntities( void );
void AAS_FreeAASLinkHeap( void );
void AAS_FreeAASLinkedEntities( void );
aas_face_t *AAS_AreaGroundFace( int areanum, vec3_t point );
aas_face_t *AAS_TraceEndFace( aas_trace_t *trace );
aas_plane_t *AAS_PlaneFromNum( int planenum );
aas_link_t *AAS_AASLinkEntity( vec3_t absmins, vec3_t absmaxs, int entnum );
aas_link_t *AAS_LinkEntityClientBBox( vec3_t absmins, vec3_t absmaxs, int entnum, int presencetype );
qboolean AAS_PointInsideFace( int facenum, vec3_t point, float epsilon );
qboolean AAS_InsideFace( aas_face_t *face, vec3_t pnormal, vec3_t point, float epsilon );
void AAS_UnlinkFromAreas( aas_link_t *areas );
#endif //AASINTERN
//returns the mins and maxs of the bounding box for the given presence type
void AAS_PresenceTypeBoundingBox( int presencetype, vec3_t mins, vec3_t maxs );
//returns the cluster the area is in (negative portal number if the area is a portal)
int AAS_AreaCluster( int areanum );
//returns the presence type(s) of the area
int AAS_AreaPresenceType( int areanum );
//returns the presence type(s) at the given point
int AAS_PointPresenceType( vec3_t point );
//returns the result of the trace of a client bbox
aas_trace_t AAS_TraceClientBBox( vec3_t start, vec3_t end, int presencetype, int passent );
//stores the areas the trace went through and returns the number of passed areas
int AAS_TraceAreas( vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas );
//returns the area the point is in
int AAS_PointAreaNum( vec3_t point );
//returns the plane the given face is in
void AAS_FacePlane( int facenum, vec3_t normal, float *dist );
int AAS_BBoxAreas( vec3_t absmins, vec3_t absmaxs, int *areas, int maxareas );
void AAS_AreaCenter( int areanum, vec3_t center );
qboolean AAS_AreaWaypoint( int areanum, vec3_t center );

767
src/botlib/be_ai_char.c Normal file
View File

@@ -0,0 +1,767 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_ai_char.c
*
* desc: bot characters
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_log.h"
#include "l_memory.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_libvar.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "../game/be_ai_char.h"
#define MAX_CHARACTERISTICS 80
#define CT_INTEGER 1
#define CT_FLOAT 2
#define CT_STRING 3
#define DEFAULT_CHARACTER "bots/default_c.c"
//characteristic value
union cvalue
{
int integer;
float _float;
char *string;
};
//a characteristic
typedef struct bot_characteristic_s
{
char type; //characteristic type
union cvalue value; //characteristic value
} bot_characteristic_t;
//a bot character
typedef struct bot_character_s
{
char filename[MAX_QPATH];
int skill;
bot_characteristic_t c[1]; //variable sized
} bot_character_t;
bot_character_t *botcharacters[MAX_CLIENTS + 1];
//========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//========================================================================
bot_character_t *BotCharacterFromHandle( int handle ) {
if ( handle <= 0 || handle > MAX_CLIENTS ) {
botimport.Print( PRT_FATAL, "character handle %d out of range\n", handle );
return NULL;
} //end if
if ( !botcharacters[handle] ) {
botimport.Print( PRT_FATAL, "invalid character %d\n", handle );
return NULL;
} //end if
return botcharacters[handle];
} //end of the function BotCharacterFromHandle
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotDumpCharacter( bot_character_t *ch ) {
int i;
Log_Write( "%s", ch->filename );
Log_Write( "skill %d\n", ch->skill );
Log_Write( "{\n" );
for ( i = 0; i < MAX_CHARACTERISTICS; i++ )
{
switch ( ch->c[i].type )
{
case CT_INTEGER: Log_Write( " %4d %d\n", i, ch->c[i].value.integer ); break;
case CT_FLOAT: Log_Write( " %4d %f\n", i, ch->c[i].value._float ); break;
case CT_STRING: Log_Write( " %4d %s\n", i, ch->c[i].value.string ); break;
} //end case
} //end for
Log_Write( "}\n" );
} //end of the function BotDumpCharacter
//========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//========================================================================
void BotFreeCharacterStrings( bot_character_t *ch ) {
int i;
for ( i = 0; i < MAX_CHARACTERISTICS; i++ )
{
if ( ch->c[i].type == CT_STRING ) {
FreeMemory( ch->c[i].value.string );
} //end if
} //end for
} //end of the function BotFreeCharacterStrings
//========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//========================================================================
void BotFreeCharacter2( int handle ) {
if ( handle <= 0 || handle > MAX_CLIENTS ) {
botimport.Print( PRT_FATAL, "character handle %d out of range\n", handle );
return;
} //end if
if ( !botcharacters[handle] ) {
botimport.Print( PRT_FATAL, "invalid character %d\n", handle );
return;
} //end if
BotFreeCharacterStrings( botcharacters[handle] );
FreeMemory( botcharacters[handle] );
botcharacters[handle] = NULL;
} //end of the function BotFreeCharacter2
//========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//========================================================================
void BotFreeCharacter( int handle ) {
if ( !LibVarGetValue( "bot_reloadcharacters" ) ) {
return;
}
BotFreeCharacter2( handle );
} //end of the function BotFreeCharacter
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotDefaultCharacteristics( bot_character_t *ch, bot_character_t *defaultch ) {
int i;
for ( i = 0; i < MAX_CHARACTERISTICS; i++ )
{
if ( ch->c[i].type ) {
continue;
}
//
if ( defaultch->c[i].type == CT_FLOAT ) {
ch->c[i].type = CT_FLOAT;
ch->c[i].value._float = defaultch->c[i].value._float;
} //end if
else if ( defaultch->c[i].type == CT_INTEGER ) {
ch->c[i].type = CT_INTEGER;
ch->c[i].value.integer = defaultch->c[i].value.integer;
} //end else if
else if ( defaultch->c[i].type == CT_STRING ) {
ch->c[i].type = CT_STRING;
ch->c[i].value.string = (char *) GetMemory( strlen( defaultch->c[i].value.string ) + 1 );
strcpy( ch->c[i].value.string, defaultch->c[i].value.string );
} //end else if
} //end for
} //end of the function BotDefaultCharacteristics
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
bot_character_t *BotLoadCharacterFromFile( char *charfile, int skill ) {
int indent, index, foundcharacter;
bot_character_t *ch;
source_t *source;
token_t token;
foundcharacter = qfalse;
//a bot character is parsed in two phases
PS_SetBaseFolder( "botfiles" );
source = LoadSourceFile( charfile );
PS_SetBaseFolder( "" );
if ( !source ) {
botimport.Print( PRT_ERROR, "counldn't load %s\n", charfile );
return NULL;
} //end if
ch = (bot_character_t *) GetClearedMemory( sizeof( bot_character_t ) +
MAX_CHARACTERISTICS * sizeof( bot_characteristic_t ) );
strcpy( ch->filename, charfile );
while ( PC_ReadToken( source, &token ) )
{
if ( !strcmp( token.string, "skill" ) ) {
if ( !PC_ExpectTokenType( source, TT_NUMBER, 0, &token ) ) {
FreeSource( source );
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end if
if ( !PC_ExpectTokenString( source, "{" ) ) {
FreeSource( source );
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end if
//if it's the correct skill
if ( skill < 0 || token.intvalue == skill ) {
foundcharacter = qtrue;
ch->skill = token.intvalue;
while ( PC_ExpectAnyToken( source, &token ) )
{
if ( !strcmp( token.string, "}" ) ) {
break;
}
if ( token.type != TT_NUMBER || !( token.subtype & TT_INTEGER ) ) {
SourceError( source, "expected integer index, found %s\n", token.string );
FreeSource( source );
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end if
index = token.intvalue;
if ( index < 0 || index > MAX_CHARACTERISTICS ) {
SourceError( source, "characteristic index out of range [0, %d]\n", MAX_CHARACTERISTICS );
FreeSource( source );
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end if
if ( ch->c[index].type ) {
SourceError( source, "characteristic %d already initialized\n", index );
FreeSource( source );
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end if
if ( !PC_ExpectAnyToken( source, &token ) ) {
FreeSource( source );
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end if
if ( token.type == TT_NUMBER ) {
if ( token.subtype & TT_FLOAT ) {
ch->c[index].value._float = token.floatvalue;
ch->c[index].type = CT_FLOAT;
} //end if
else
{
ch->c[index].value.integer = token.intvalue;
ch->c[index].type = CT_INTEGER;
} //end else
} //end if
else if ( token.type == TT_STRING ) {
StripDoubleQuotes( token.string );
ch->c[index].value.string = GetMemory( strlen( token.string ) + 1 );
strcpy( ch->c[index].value.string, token.string );
ch->c[index].type = CT_STRING;
} //end else if
else
{
SourceError( source, "expected integer, float or string, found %s\n", token.string );
FreeSource( source );
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end else
} //end if
break;
} //end if
else
{
indent = 1;
while ( indent )
{
if ( !PC_ExpectAnyToken( source, &token ) ) {
FreeSource( source );
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end if
if ( !strcmp( token.string, "{" ) ) {
indent++;
} else if ( !strcmp( token.string, "}" ) ) {
indent--;
}
} //end while
} //end else
} //end if
else
{
SourceError( source, "unknown definition %s\n", token.string );
FreeSource( source );
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end else
} //end while
FreeSource( source );
//
if ( !foundcharacter ) {
BotFreeCharacterStrings( ch );
FreeMemory( ch );
return NULL;
} //end if
return ch;
} //end of the function BotLoadCharacterFromFile
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotFindCachedCharacter( char *charfile, int skill ) {
int handle;
for ( handle = 1; handle <= MAX_CLIENTS; handle++ )
{
if ( !botcharacters[handle] ) {
continue;
}
if ( strcmp( botcharacters[handle]->filename, charfile ) == 0 &&
( skill < 0 || botcharacters[handle]->skill == skill ) ) {
return handle;
} //end if
} //end for
return 0;
} //end of the function BotFindCachedCharacter
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotLoadCachedCharacter( char *charfile, int skill, int reload ) {
int handle, cachedhandle;
bot_character_t *ch = NULL;
#ifdef DEBUG
int starttime;
starttime = Sys_MilliSeconds();
#endif //DEBUG
//find a free spot for a character
for ( handle = 1; handle <= MAX_CLIENTS; handle++ )
{
if ( !botcharacters[handle] ) {
break;
}
} //end for
if ( handle > MAX_CLIENTS ) {
return 0;
}
//try to load a cached character with the given skill
if ( !reload ) {
cachedhandle = BotFindCachedCharacter( charfile, skill );
if ( cachedhandle ) {
//botimport.Print(PRT_MESSAGE, "loaded cached skill %d from %s\n", skill, charfile);
return cachedhandle;
} //end if
} //end else
//try to load the character with the given skill
ch = BotLoadCharacterFromFile( charfile, skill );
if ( ch ) {
botcharacters[handle] = ch;
//
//botimport.Print(PRT_MESSAGE, "loaded skill %d from %s\n", skill, charfile);
#ifdef DEBUG
if ( bot_developer ) {
botimport.Print( PRT_MESSAGE, "skill %d loaded in %d msec from %s\n", skill, Sys_MilliSeconds() - starttime, charfile );
} //end if
#endif //DEBUG
return handle;
} //end if
//
botimport.Print( PRT_WARNING, "couldn't find skill %d in %s\n", skill, charfile );
//
if ( !reload ) {
//try to load a cached default character with the given skill
cachedhandle = BotFindCachedCharacter( "bots/default_c.c", skill );
if ( cachedhandle ) {
botimport.Print( PRT_MESSAGE, "loaded cached default skill %d from %s\n", skill, charfile );
return cachedhandle;
} //end if
} //end if
//try to load the default character with the given skill
ch = BotLoadCharacterFromFile( DEFAULT_CHARACTER, skill );
if ( ch ) {
botcharacters[handle] = ch;
//botimport.Print(PRT_MESSAGE, "loaded default skill %d from %s\n", skill, charfile);
return handle;
} //end if
//
if ( !reload ) {
//try to load a cached character with any skill
cachedhandle = BotFindCachedCharacter( charfile, -1 );
if ( cachedhandle ) {
//botimport.Print(PRT_MESSAGE, "loaded cached skill %d from %s\n", botcharacters[cachedhandle]->skill, charfile);
return cachedhandle;
} //end if
} //end if
//try to load a character with any skill
ch = BotLoadCharacterFromFile( charfile, -1 );
if ( ch ) {
botcharacters[handle] = ch;
//botimport.Print(PRT_MESSAGE, "loaded skill %d from %s\n", ch->skill, charfile);
return handle;
} //end if
//
if ( !reload ) {
//try to load a cached character with any skill
cachedhandle = BotFindCachedCharacter( DEFAULT_CHARACTER, -1 );
if ( cachedhandle ) {
botimport.Print( PRT_MESSAGE, "loaded cached default skill %d from %s\n", botcharacters[cachedhandle]->skill, charfile );
return cachedhandle;
} //end if
} //end if
//try to load a character with any skill
ch = BotLoadCharacterFromFile( DEFAULT_CHARACTER, -1 );
if ( ch ) {
botcharacters[handle] = ch;
botimport.Print( PRT_MESSAGE, "loaded default skill %d from %s\n", ch->skill, charfile );
return handle;
} //end if
//
botimport.Print( PRT_WARNING, "couldn't load any skill from %s\n", charfile );
//couldn't load any character
return 0;
} //end of the function BotLoadCachedCharacter
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotLoadCharacterSkill( char *charfile, int skill ) {
int ch, defaultch;
defaultch = BotLoadCachedCharacter( DEFAULT_CHARACTER, skill, qfalse );
ch = BotLoadCachedCharacter( charfile, skill, LibVarGetValue( "bot_reloadcharacters" ) );
if ( defaultch && ch ) {
BotDefaultCharacteristics( botcharacters[ch], botcharacters[defaultch] );
} //end if
return ch;
} //end of the function BotLoadCharacterSkill
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotInterpolateCharacters( int handle1, int handle2, int desiredskill ) {
bot_character_t *ch1, *ch2, *out;
int i, handle;
float scale;
ch1 = BotCharacterFromHandle( handle1 );
ch2 = BotCharacterFromHandle( handle2 );
if ( !ch1 || !ch2 ) {
return 0;
}
//find a free spot for a character
for ( handle = 1; handle <= MAX_CLIENTS; handle++ )
{
if ( !botcharacters[handle] ) {
break;
}
} //end for
if ( handle > MAX_CLIENTS ) {
return 0;
}
out = (bot_character_t *) GetClearedMemory( sizeof( bot_character_t ) +
MAX_CHARACTERISTICS * sizeof( bot_characteristic_t ) );
out->skill = desiredskill;
strcpy( out->filename, ch1->filename );
botcharacters[handle] = out;
scale = (float) ( desiredskill - 1 ) / ( ch2->skill - ch1->skill );
for ( i = 0; i < MAX_CHARACTERISTICS; i++ )
{
//
if ( ch1->c[i].type == CT_FLOAT && ch2->c[i].type == CT_FLOAT ) {
out->c[i].type = CT_FLOAT;
out->c[i].value._float = ch1->c[i].value._float +
( ch2->c[i].value._float - ch1->c[i].value._float ) * scale;
} //end if
else if ( ch1->c[i].type == CT_INTEGER ) {
out->c[i].type = CT_INTEGER;
out->c[i].value.integer = ch1->c[i].value.integer;
} //end else if
else if ( ch1->c[i].type == CT_STRING ) {
out->c[i].type = CT_STRING;
out->c[i].value.string = (char *) GetMemory( strlen( ch1->c[i].value.string ) + 1 );
strcpy( out->c[i].value.string, ch1->c[i].value.string );
} //end else if
} //end for
return handle;
} //end of the function BotInterpolateCharacters
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotLoadCharacter( char *charfile, int skill ) {
int skill1, skill4, handle;
//make sure the skill is in the valid range
if ( skill < 1 ) {
skill = 1;
} else if ( skill > 5 ) {
skill = 5;
}
//skill 1, 4 and 5 should be available in the character files
if ( skill == 1 || skill == 4 || skill == 5 ) {
return BotLoadCharacterSkill( charfile, skill );
} //end if
//check if there's a cached skill 2 or 3
handle = BotFindCachedCharacter( charfile, skill );
if ( handle ) {
//botimport.Print(PRT_MESSAGE, "loaded cached skill %d from %s\n", skill, charfile);
return handle;
} //end if
//load skill 1 and 4
skill1 = BotLoadCharacterSkill( charfile, 1 );
if ( !skill1 ) {
return 0;
}
skill4 = BotLoadCharacterSkill( charfile, 4 );
if ( !skill4 ) {
return skill1;
}
//interpolate between 1 and 4 to create skill 2 or 3
handle = BotInterpolateCharacters( skill1, skill4, skill );
if ( !handle ) {
return 0;
}
//write the character to the log file
BotDumpCharacter( botcharacters[handle] );
//
return handle;
} //end of the function BotLoadCharacter
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int CheckCharacteristicIndex( int character, int index ) {
bot_character_t *ch;
ch = BotCharacterFromHandle( character );
if ( !ch ) {
return qfalse;
}
if ( index < 0 || index >= MAX_CHARACTERISTICS ) {
botimport.Print( PRT_ERROR, "characteristic %d does not exist\n", index );
return qfalse;
} //end if
if ( !ch->c[index].type ) {
botimport.Print( PRT_ERROR, "characteristic %d is not initialized\n", index );
return qfalse;
} //end if
return qtrue;
} //end of the function CheckCharacteristicIndex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float Characteristic_Float( int character, int index ) {
bot_character_t *ch;
ch = BotCharacterFromHandle( character );
if ( !ch ) {
return 0;
}
//check if the index is in range
if ( !CheckCharacteristicIndex( character, index ) ) {
return 0;
}
//an integer will be converted to a float
if ( ch->c[index].type == CT_INTEGER ) {
return (float) ch->c[index].value.integer;
} //end if
//floats are just returned
else if ( ch->c[index].type == CT_FLOAT ) {
return ch->c[index].value._float;
} //end else if
//cannot convert a string pointer to a float
else
{
botimport.Print( PRT_ERROR, "characteristic %d is not a float\n", index );
return 0;
} //end else if
// return 0;
} //end of the function Characteristic_Float
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float Characteristic_BFloat( int character, int index, float min, float max ) {
float value;
bot_character_t *ch;
ch = BotCharacterFromHandle( character );
if ( !ch ) {
return 0;
}
if ( min > max ) {
botimport.Print( PRT_ERROR, "cannot bound characteristic %d between %f and %f\n", index, min, max );
return 0;
} //end if
value = Characteristic_Float( character, index );
if ( value < min ) {
return min;
}
if ( value > max ) {
return max;
}
return value;
} //end of the function Characteristic_BFloat
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Characteristic_Integer( int character, int index ) {
bot_character_t *ch;
ch = BotCharacterFromHandle( character );
if ( !ch ) {
return 0;
}
//check if the index is in range
if ( !CheckCharacteristicIndex( character, index ) ) {
return 0;
}
//an integer will just be returned
if ( ch->c[index].type == CT_INTEGER ) {
return ch->c[index].value.integer;
} //end if
//floats are casted to integers
else if ( ch->c[index].type == CT_FLOAT ) {
return (int) ch->c[index].value._float;
} //end else if
else
{
botimport.Print( PRT_ERROR, "characteristic %d is not a integer\n", index );
return 0;
} //end else if
// return 0;
} //end of the function Characteristic_Integer
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Characteristic_BInteger( int character, int index, int min, int max ) {
int value;
bot_character_t *ch;
ch = BotCharacterFromHandle( character );
if ( !ch ) {
return 0;
}
if ( min > max ) {
botimport.Print( PRT_ERROR, "cannot bound characteristic %d between %d and %d\n", index, min, max );
return 0;
} //end if
value = Characteristic_Integer( character, index );
if ( value < min ) {
return min;
}
if ( value > max ) {
return max;
}
return value;
} //end of the function Characteristic_BInteger
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Characteristic_String( int character, int index, char *buf, int size ) {
bot_character_t *ch;
ch = BotCharacterFromHandle( character );
if ( !ch ) {
return;
}
//check if the index is in range
if ( !CheckCharacteristicIndex( character, index ) ) {
return;
}
//an integer will be converted to a float
if ( ch->c[index].type == CT_STRING ) {
strncpy( buf, ch->c[index].value.string, size - 1 );
buf[size - 1] = '\0';
return;
} //end if
else
{
botimport.Print( PRT_ERROR, "characteristic %d is not a string\n", index );
return;
} //end else if
return;
} //end of the function Characteristic_String
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotShutdownCharacters( void ) {
int handle;
for ( handle = 1; handle <= MAX_CLIENTS; handle++ )
{
if ( botcharacters[handle] ) {
BotFreeCharacter2( handle );
} //end if
} //end for
} //end of the function BotShutdownCharacters

2890
src/botlib/be_ai_chat.c Normal file

File diff suppressed because it is too large Load Diff

151
src/botlib/be_ai_gen.c Normal file
View File

@@ -0,0 +1,151 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_ai_gen.c
*
* desc: genetic selection
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "../game/be_ai_gen.h"
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int GeneticSelection( int numranks, float *rankings ) {
float sum, select;
int i, index;
sum = 0;
for ( i = 0; i < numranks; i++ )
{
if ( rankings[i] < 0 ) {
continue;
}
sum += rankings[i];
} //end for
if ( sum > 0 ) {
//select a bot where the ones with the higest rankings have
//the highest chance of being selected
select = random() * sum;
for ( i = 0; i < numranks; i++ )
{
if ( rankings[i] < 0 ) {
continue;
}
sum -= rankings[i];
if ( sum <= 0 ) {
return i;
}
} //end for
} //end if
//select a bot randomly
index = random() * numranks;
for ( i = 0; i < numranks; i++ )
{
if ( rankings[index] >= 0 ) {
return index;
}
index = ( index + 1 ) % numranks;
} //end for
return 0;
} //end of the function GeneticSelection
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int GeneticParentsAndChildSelection( int numranks, float *ranks, int *parent1, int *parent2, int *child ) {
float rankings[256], max;
int i;
if ( numranks > 256 ) {
botimport.Print( PRT_WARNING, "GeneticParentsAndChildSelection: too many bots\n" );
*parent1 = *parent2 = *child = 0;
return qfalse;
} //end if
for ( max = 0, i = 0; i < numranks; i++ )
{
if ( ranks[i] < 0 ) {
continue;
}
max++;
} //end for
if ( max < 3 ) {
botimport.Print( PRT_WARNING, "GeneticParentsAndChildSelection: too few valid bots\n" );
*parent1 = *parent2 = *child = 0;
return qfalse;
} //end if
memcpy( rankings, ranks, sizeof( float ) * numranks );
//select first parent
*parent1 = GeneticSelection( numranks, rankings );
rankings[*parent1] = -1;
//select second parent
*parent2 = GeneticSelection( numranks, rankings );
rankings[*parent2] = -1;
//reverse the rankings
max = 0;
for ( i = 0; i < numranks; i++ )
{
if ( rankings[i] < 0 ) {
continue;
}
if ( rankings[i] > max ) {
max = rankings[i];
}
} //end for
for ( i = 0; i < numranks; i++ )
{
if ( rankings[i] < 0 ) {
continue;
}
rankings[i] = max - rankings[i];
} //end for
//select child
*child = GeneticSelection( numranks, rankings );
return qtrue;
} //end of the function GeneticParentsAndChildSelection

1634
src/botlib/be_ai_goal.c Normal file

File diff suppressed because it is too large Load Diff

3962
src/botlib/be_ai_move.c Normal file

File diff suppressed because it is too large Load Diff

555
src/botlib/be_ai_weap.c Normal file
View File

@@ -0,0 +1,555 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_ai_weap.c
*
* desc: weapon AI
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_libvar.h"
#include "l_log.h"
#include "l_memory.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_ai_weight.h" //fuzzy weights
#include "../game/be_ai_weap.h"
//#define DEBUG_AI_WEAP
//structure field offsets
#define WEAPON_OFS( x ) (int)&( ( (weaponinfo_t *)0 )->x )
#define PROJECTILE_OFS( x ) (int)&( ( (projectileinfo_t *)0 )->x )
//weapon definition
fielddef_t weaponinfo_fields[] =
{
{"number", WEAPON_OFS( number ), FT_INT}, //weapon number
{"name", WEAPON_OFS( name ), FT_STRING}, //name of the weapon
{"level", WEAPON_OFS( level ), FT_INT},
{"model", WEAPON_OFS( model ), FT_STRING}, //model of the weapon
{"weaponindex", WEAPON_OFS( weaponindex ), FT_INT}, //index of weapon in inventory
{"flags", WEAPON_OFS( flags ), FT_INT}, //special flags
{"projectile", WEAPON_OFS( projectile ), FT_STRING}, //projectile used by the weapon
{"numprojectiles", WEAPON_OFS( numprojectiles ), FT_INT}, //number of projectiles
{"hspread", WEAPON_OFS( hspread ), FT_FLOAT}, //horizontal spread of projectiles (degrees from middle)
{"vspread", WEAPON_OFS( vspread ), FT_FLOAT}, //vertical spread of projectiles (degrees from middle)
{"speed", WEAPON_OFS( speed ), FT_FLOAT}, //speed of the projectile (0 = instant hit)
{"acceleration", WEAPON_OFS( acceleration ), FT_FLOAT}, //"acceleration" * time (in seconds) + "speed" = projectile speed
{"recoil", WEAPON_OFS( recoil ), FT_FLOAT | FT_ARRAY, 3}, //amount of recoil the player gets from the weapon
{"offset", WEAPON_OFS( offset ), FT_FLOAT | FT_ARRAY, 3}, //projectile start offset relative to eye and view angles
{"angleoffset", WEAPON_OFS( angleoffset ), FT_FLOAT | FT_ARRAY, 3}, //offset of the shoot angles relative to the view angles
{"extrazvelocity", WEAPON_OFS( extrazvelocity ), FT_FLOAT}, //extra z velocity the projectile gets
{"ammoamount", WEAPON_OFS( ammoamount ), FT_INT}, //ammo amount used per shot
{"ammoindex", WEAPON_OFS( ammoindex ), FT_INT}, //index of ammo in inventory
{"activate", WEAPON_OFS( activate ), FT_FLOAT}, //time it takes to select the weapon
{"reload", WEAPON_OFS( reload ), FT_FLOAT}, //time it takes to reload the weapon
{"spinup", WEAPON_OFS( spinup ), FT_FLOAT}, //time it takes before first shot
{"spindown", WEAPON_OFS( spindown ), FT_FLOAT}, //time it takes before weapon stops firing
{NULL, 0, 0, 0}
};
//projectile definition
fielddef_t projectileinfo_fields[] =
{
{"name", PROJECTILE_OFS( name ), FT_STRING}, //name of the projectile
{"model", WEAPON_OFS( model ), FT_STRING}, //model of the projectile
{"flags", PROJECTILE_OFS( flags ), FT_INT}, //special flags
{"gravity", PROJECTILE_OFS( gravity ), FT_FLOAT}, //amount of gravity applied to the projectile [0,1]
{"damage", PROJECTILE_OFS( damage ), FT_INT}, //damage of the projectile
{"radius", PROJECTILE_OFS( radius ), FT_FLOAT}, //radius of damage
{"visdamage", PROJECTILE_OFS( visdamage ), FT_INT}, //damage of the projectile to visible entities
{"damagetype", PROJECTILE_OFS( damagetype ), FT_INT}, //type of damage (combination of the DAMAGETYPE_? flags)
{"healthinc", PROJECTILE_OFS( healthinc ), FT_INT}, //health increase the owner gets
{"push", PROJECTILE_OFS( push ), FT_FLOAT}, //amount a player is pushed away from the projectile impact
{"detonation", PROJECTILE_OFS( detonation ), FT_FLOAT}, //time before projectile explodes after fire pressed
{"bounce", PROJECTILE_OFS( bounce ), FT_FLOAT}, //amount the projectile bounces
{"bouncefric", PROJECTILE_OFS( bouncefric ), FT_FLOAT}, //amount the bounce decreases per bounce
{"bouncestop", PROJECTILE_OFS( bouncestop ), FT_FLOAT}, //minimum bounce value before bouncing stops
//recurive projectile definition??
{NULL, 0, 0, 0}
};
structdef_t weaponinfo_struct =
{
sizeof( weaponinfo_t ), weaponinfo_fields
};
structdef_t projectileinfo_struct =
{
sizeof( projectileinfo_t ), projectileinfo_fields
};
//weapon configuration: set of weapons with projectiles
typedef struct weaponconfig_s
{
int numweapons;
int numprojectiles;
projectileinfo_t *projectileinfo;
weaponinfo_t *weaponinfo;
} weaponconfig_t;
//the bot weapon state
typedef struct bot_weaponstate_s
{
struct weightconfig_s *weaponweightconfig; //weapon weight configuration
int *weaponweightindex; //weapon weight index
} bot_weaponstate_t;
bot_weaponstate_t *botweaponstates[MAX_CLIENTS + 1];
weaponconfig_t *weaponconfig;
//========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//========================================================================
extern qboolean g_singleplayer;
int BotValidWeaponNumber( int weaponnum ) {
// Thanks Arnout! TDF
// Gordon: 0 is valid in mp now too, for mr. pow
if ( ( g_singleplayer && weaponnum < 0 ) || ( !g_singleplayer && weaponnum < 0 ) || weaponnum > weaponconfig->numweapons ) {
botimport.Print( PRT_ERROR, "weapon number out of range\n" );
return qfalse;
} //end if
return qtrue;
} //end of the function BotValidWeaponNumber
//========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//========================================================================
bot_weaponstate_t *BotWeaponStateFromHandle( int handle ) {
if ( handle <= 0 || handle > MAX_CLIENTS ) {
botimport.Print( PRT_FATAL, "move state handle %d out of range\n", handle );
return NULL;
} //end if
if ( !botweaponstates[handle] ) {
botimport.Print( PRT_FATAL, "invalid move state %d\n", handle );
return NULL;
} //end if
return botweaponstates[handle];
} //end of the function BotWeaponStateFromHandle
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef DEBUG_AI_WEAP
void DumpWeaponConfig( weaponconfig_t *wc ) {
FILE *fp;
int i;
fp = Log_FileStruct();
if ( !fp ) {
return;
}
for ( i = 0; i < wc->numprojectiles; i++ )
{
WriteStructure( fp, &projectileinfo_struct, (char *) &wc->projectileinfo[i] );
Log_Flush();
} //end for
for ( i = 0; i < wc->numweapons; i++ )
{
WriteStructure( fp, &weaponinfo_struct, (char *) &wc->weaponinfo[i] );
Log_Flush();
} //end for
} //end of the function DumpWeaponConfig
#endif //DEBUG_AI_WEAP
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
weaponconfig_t *LoadWeaponConfig( char *filename ) {
int max_weaponinfo, max_projectileinfo;
token_t token;
char path[MAX_PATH];
int i, j;
source_t *source;
weaponconfig_t *wc;
weaponinfo_t weaponinfo;
max_weaponinfo = (int) LibVarValue( "max_weaponinfo", "64" );
if ( max_weaponinfo < 0 ) {
botimport.Print( PRT_ERROR, "max_weaponinfo = %d\n", max_weaponinfo );
max_weaponinfo = 64;
LibVarSet( "max_weaponinfo", "64" );
} //end if
max_projectileinfo = (int) LibVarValue( "max_projectileinfo", "64" );
if ( max_projectileinfo < 0 ) {
botimport.Print( PRT_ERROR, "max_projectileinfo = %d\n", max_projectileinfo );
max_projectileinfo = 64;
LibVarSet( "max_projectileinfo", "64" );
} //end if
strncpy( path, filename, MAX_PATH );
source = LoadSourceFile( path );
if ( !source ) {
botimport.Print( PRT_ERROR, "counldn't load %s\n", path );
return NULL;
} //end if
//initialize weapon config
wc = (weaponconfig_t *) GetClearedHunkMemory( sizeof( weaponconfig_t ) +
max_weaponinfo * sizeof( weaponinfo_t ) +
max_projectileinfo * sizeof( projectileinfo_t ) );
wc->weaponinfo = ( weaponinfo_t * )( (char *) wc + sizeof( weaponconfig_t ) );
wc->projectileinfo = ( projectileinfo_t * )( (char *) wc->weaponinfo +
max_weaponinfo * sizeof( weaponinfo_t ) );
wc->numweapons = max_weaponinfo;
wc->numprojectiles = 0;
//parse the source file
while ( PC_ReadToken( source, &token ) )
{
if ( !strcmp( token.string, "weaponinfo" ) ) {
memset( &weaponinfo, 0, sizeof( weaponinfo_t ) );
if ( !ReadStructure( source, &weaponinfo_struct, (char *) &weaponinfo ) ) {
FreeMemory( wc );
FreeSource( source );
return NULL;
} //end if
if ( weaponinfo.number < 0 || weaponinfo.number >= max_weaponinfo ) {
botimport.Print( PRT_ERROR, "weapon info number %d out of range in %s\n", weaponinfo.number, path );
FreeMemory( wc );
FreeSource( source );
return NULL;
} //end if
memcpy( &wc->weaponinfo[weaponinfo.number], &weaponinfo, sizeof( weaponinfo_t ) );
wc->weaponinfo[weaponinfo.number].valid = qtrue;
} //end if
else if ( !strcmp( token.string, "projectileinfo" ) ) {
if ( wc->numprojectiles >= max_projectileinfo ) {
botimport.Print( PRT_ERROR, "more than %d projectiles defined in %s\n", max_projectileinfo, path );
FreeMemory( wc );
FreeSource( source );
return NULL;
} //end if
memset( &wc->projectileinfo[wc->numprojectiles], 0, sizeof( projectileinfo_t ) );
if ( !ReadStructure( source, &projectileinfo_struct, (char *) &wc->projectileinfo[wc->numprojectiles] ) ) {
FreeMemory( wc );
FreeSource( source );
return NULL;
} //end if
wc->numprojectiles++;
} //end if
else
{
botimport.Print( PRT_ERROR, "unknown definition %s in %s\n", token.string, path );
FreeMemory( wc );
FreeSource( source );
return NULL;
} //end else
} //end while
FreeSource( source );
//fix up weapons
for ( i = 0; i < wc->numweapons; i++ )
{
if ( !wc->weaponinfo[i].valid ) {
continue;
}
if ( !wc->weaponinfo[i].name[0] ) {
botimport.Print( PRT_ERROR, "weapon %d has no name in %s\n", i, path );
FreeMemory( wc );
return NULL;
} //end if
if ( !wc->weaponinfo[i].projectile[0] ) {
botimport.Print( PRT_ERROR, "weapon %s has no projectile in %s\n", wc->weaponinfo[i].name, path );
FreeMemory( wc );
return NULL;
} //end if
//find the projectile info and copy it to the weapon info
for ( j = 0; j < wc->numprojectiles; j++ )
{
if ( !strcmp( wc->projectileinfo[j].name, wc->weaponinfo[i].projectile ) ) {
memcpy( &wc->weaponinfo[i].proj, &wc->projectileinfo[j], sizeof( projectileinfo_t ) );
break;
} //end if
} //end for
if ( j == wc->numprojectiles ) {
botimport.Print( PRT_ERROR, "weapon %s uses undefined projectile in %s\n", wc->weaponinfo[i].name, path );
FreeMemory( wc );
return NULL;
} //end if
} //end for
if ( !wc->numweapons ) {
botimport.Print( PRT_WARNING, "no weapon info loaded\n" );
}
botimport.Print( PRT_MESSAGE, "loaded %s\n", path );
return wc;
} //end of the function LoadWeaponConfig
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int *WeaponWeightIndex( weightconfig_t *wwc, weaponconfig_t *wc ) {
int *index, i;
//initialize item weight index
index = (int *) GetClearedMemory( sizeof( int ) * wc->numweapons );
for ( i = 0; i < wc->numweapons; i++ )
{
index[i] = FindFuzzyWeight( wwc, wc->weaponinfo[i].name );
} //end for
return index;
} //end of the function WeaponWeightIndex
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotFreeWeaponWeights( int weaponstate ) {
bot_weaponstate_t *ws;
ws = BotWeaponStateFromHandle( weaponstate );
if ( !ws ) {
return;
}
if ( ws->weaponweightconfig ) {
FreeWeightConfig( ws->weaponweightconfig );
}
if ( ws->weaponweightindex ) {
FreeMemory( ws->weaponweightindex );
}
} //end of the function BotFreeWeaponWeights
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotLoadWeaponWeights( int weaponstate, char *filename ) {
bot_weaponstate_t *ws;
ws = BotWeaponStateFromHandle( weaponstate );
if ( !ws ) {
return BLERR_CANNOTLOADWEAPONWEIGHTS;
}
BotFreeWeaponWeights( weaponstate );
//
PS_SetBaseFolder( "botfiles" );
ws->weaponweightconfig = ReadWeightConfig( filename );
PS_SetBaseFolder( "" );
if ( !ws->weaponweightconfig ) {
botimport.Print( PRT_FATAL, "couldn't load weapon config %s\n", filename );
return BLERR_CANNOTLOADWEAPONWEIGHTS;
} //end if
if ( !weaponconfig ) {
return BLERR_CANNOTLOADWEAPONCONFIG;
}
ws->weaponweightindex = WeaponWeightIndex( ws->weaponweightconfig, weaponconfig );
return BLERR_NOERROR;
} //end of the function BotLoadWeaponWeights
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotGetWeaponInfo( int weaponstate, int weapon, weaponinfo_t *weaponinfo ) {
bot_weaponstate_t *ws;
if ( !BotValidWeaponNumber( weapon ) ) {
return;
}
ws = BotWeaponStateFromHandle( weaponstate );
if ( !ws ) {
return;
}
if ( !weaponconfig ) {
return;
}
memcpy( weaponinfo, &weaponconfig->weaponinfo[weapon], sizeof( weaponinfo_t ) );
} //end of the function BotGetWeaponInfo
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotChooseBestFightWeapon( int weaponstate, int *inventory ) {
int i, index, bestweapon;
float weight, bestweight;
weaponconfig_t *wc;
bot_weaponstate_t *ws;
ws = BotWeaponStateFromHandle( weaponstate );
if ( !ws ) {
return 0;
}
wc = weaponconfig;
if ( !weaponconfig ) {
return 0;
}
//if the bot has no weapon weight configuration
if ( !ws->weaponweightconfig ) {
return 0;
}
bestweight = 0;
bestweapon = 0;
for ( i = 0; i < wc->numweapons; i++ )
{
if ( !wc->weaponinfo[i].valid ) {
continue;
}
index = ws->weaponweightindex[i];
if ( index < 0 ) {
continue;
}
weight = FuzzyWeight( inventory, ws->weaponweightconfig, index );
if ( weight > bestweight ) {
bestweight = weight;
bestweapon = i;
} //end if
} //end for
return bestweapon;
} //end of the function BotChooseBestFightWeapon
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotResetWeaponState( int weaponstate ) {
struct weightconfig_s *weaponweightconfig;
int *weaponweightindex;
bot_weaponstate_t *ws;
ws = BotWeaponStateFromHandle( weaponstate );
if ( !ws ) {
return;
}
weaponweightconfig = ws->weaponweightconfig;
weaponweightindex = ws->weaponweightindex;
//memset(ws, 0, sizeof(bot_weaponstate_t));
ws->weaponweightconfig = weaponweightconfig;
ws->weaponweightindex = weaponweightindex;
} //end of the function BotResetWeaponState
//========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//========================================================================
int BotAllocWeaponState( void ) {
int i;
for ( i = 1; i <= MAX_CLIENTS; i++ )
{
if ( !botweaponstates[i] ) {
botweaponstates[i] = GetClearedMemory( sizeof( bot_weaponstate_t ) );
return i;
} //end if
} //end for
return 0;
} //end of the function BotAllocWeaponState
//========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//========================================================================
void BotFreeWeaponState( int handle ) {
if ( handle <= 0 || handle > MAX_CLIENTS ) {
botimport.Print( PRT_FATAL, "move state handle %d out of range\n", handle );
return;
} //end if
if ( !botweaponstates[handle] ) {
botimport.Print( PRT_FATAL, "invalid move state %d\n", handle );
return;
} //end if
BotFreeWeaponWeights( handle );
FreeMemory( botweaponstates[handle] );
botweaponstates[handle] = NULL;
} //end of the function BotFreeWeaponState
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int BotSetupWeaponAI( void ) {
char *file;
PS_SetBaseFolder( "botfiles" );
file = LibVarString( "weaponconfig", "weapons.c" );
weaponconfig = LoadWeaponConfig( file );
PS_SetBaseFolder( "" );
if ( !weaponconfig ) {
botimport.Print( PRT_FATAL, "couldn't load the weapon config\n" );
return BLERR_CANNOTLOADWEAPONCONFIG;
} //end if
#ifdef DEBUG_AI_WEAP
DumpWeaponConfig( weaponconfig );
#endif //DEBUG_AI_WEAP
//
return BLERR_NOERROR;
} //end of the function BotSetupWeaponAI
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotShutdownWeaponAI( void ) {
int i;
if ( weaponconfig ) {
FreeMemory( weaponconfig );
}
weaponconfig = NULL;
for ( i = 1; i <= MAX_CLIENTS; i++ )
{
if ( botweaponstates[i] ) {
BotFreeWeaponState( i );
} //end if
} //end for
} //end of the function BotShutdownWeaponAI

972
src/botlib/be_ai_weight.c Normal file
View File

@@ -0,0 +1,972 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_ai_weight.c
*
* desc: fuzzy logic
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_utils.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_libvar.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_interface.h"
#include "be_ai_weight.h"
#define MAX_INVENTORYVALUE 999999
#define EVALUATERECURSIVELY
#define MAX_WEIGHT_FILES 128
weightconfig_t *weightFileList[MAX_WEIGHT_FILES];
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int ReadValue( source_t *source, float *value ) {
token_t token;
if ( !PC_ExpectAnyToken( source, &token ) ) {
return qfalse;
}
if ( !strcmp( token.string, "-" ) ) {
SourceWarning( source, "negative value set to zero\n" );
if ( !PC_ExpectTokenType( source, TT_NUMBER, 0, &token ) ) {
return qfalse;
}
} //end if
if ( token.type != TT_NUMBER ) {
SourceError( source, "invalid return value %s\n", token.string );
return qfalse;
} //end if
*value = token.floatvalue;
return qtrue;
} //end of the function ReadValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int ReadFuzzyWeight( source_t *source, fuzzyseperator_t *fs ) {
if ( PC_CheckTokenString( source, "balance" ) ) {
fs->type = WT_BALANCE;
if ( !PC_ExpectTokenString( source, "(" ) ) {
return qfalse;
}
if ( !ReadValue( source, &fs->weight ) ) {
return qfalse;
}
if ( !PC_ExpectTokenString( source, "," ) ) {
return qfalse;
}
if ( !ReadValue( source, &fs->minweight ) ) {
return qfalse;
}
if ( !PC_ExpectTokenString( source, "," ) ) {
return qfalse;
}
if ( !ReadValue( source, &fs->maxweight ) ) {
return qfalse;
}
if ( !PC_ExpectTokenString( source, ")" ) ) {
return qfalse;
}
} //end if
else
{
fs->type = 0;
if ( !ReadValue( source, &fs->weight ) ) {
return qfalse;
}
fs->minweight = fs->weight;
fs->maxweight = fs->weight;
} //end if
if ( !PC_ExpectTokenString( source, ";" ) ) {
return qfalse;
}
return qtrue;
} //end of the function ReadFuzzyWeight
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeFuzzySeperators_r( fuzzyseperator_t *fs ) {
if ( !fs ) {
return;
}
if ( fs->child ) {
FreeFuzzySeperators_r( fs->child );
}
if ( fs->next ) {
FreeFuzzySeperators_r( fs->next );
}
FreeMemory( fs );
} //end of the function FreeFuzzySeperators
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeWeightConfig2( weightconfig_t *config ) {
int i;
for ( i = 0; i < config->numweights; i++ )
{
FreeFuzzySeperators_r( config->weights[i].firstseperator );
if ( config->weights[i].name ) {
FreeMemory( config->weights[i].name );
}
} //end for
FreeMemory( config );
} //end of the function FreeWeightConfig2
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeWeightConfig( weightconfig_t *config ) {
if ( !LibVarGetValue( "bot_reloadcharacters" ) ) {
return;
}
FreeWeightConfig2( config );
} //end of the function FreeWeightConfig
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
fuzzyseperator_t *ReadFuzzySeperators_r( source_t *source ) {
int newindent, index, def, founddefault;
token_t token;
fuzzyseperator_t *fs, *lastfs, *firstfs;
founddefault = qfalse;
firstfs = NULL;
lastfs = NULL;
if ( !PC_ExpectTokenString( source, "(" ) ) {
return NULL;
}
if ( !PC_ExpectTokenType( source, TT_NUMBER, TT_INTEGER, &token ) ) {
return NULL;
}
index = token.intvalue;
if ( !PC_ExpectTokenString( source, ")" ) ) {
return NULL;
}
if ( !PC_ExpectTokenString( source, "{" ) ) {
return NULL;
}
if ( !PC_ExpectAnyToken( source, &token ) ) {
return NULL;
}
do
{
def = !strcmp( token.string, "default" );
if ( def || !strcmp( token.string, "case" ) ) {
fs = (fuzzyseperator_t *) GetClearedMemory( sizeof( fuzzyseperator_t ) );
fs->index = index;
if ( lastfs ) {
lastfs->next = fs;
} else { firstfs = fs;}
lastfs = fs;
if ( def ) {
if ( founddefault ) {
SourceError( source, "switch already has a default\n" );
FreeFuzzySeperators_r( firstfs );
return NULL;
} //end if
fs->value = MAX_INVENTORYVALUE;
founddefault = qtrue;
} //end if
else
{
if ( !PC_ExpectTokenType( source, TT_NUMBER, TT_INTEGER, &token ) ) {
FreeFuzzySeperators_r( firstfs );
return NULL;
} //end if
fs->value = token.intvalue;
} //end else
if ( !PC_ExpectTokenString( source, ":" ) || !PC_ExpectAnyToken( source, &token ) ) {
FreeFuzzySeperators_r( firstfs );
return NULL;
} //end if
newindent = qfalse;
if ( !strcmp( token.string, "{" ) ) {
newindent = qtrue;
if ( !PC_ExpectAnyToken( source, &token ) ) {
FreeFuzzySeperators_r( firstfs );
return NULL;
} //end if
} //end if
if ( !strcmp( token.string, "return" ) ) {
if ( !ReadFuzzyWeight( source, fs ) ) {
FreeFuzzySeperators_r( firstfs );
return NULL;
} //end if
} //end if
else if ( !strcmp( token.string, "switch" ) ) {
fs->child = ReadFuzzySeperators_r( source );
if ( !fs->child ) {
FreeFuzzySeperators_r( firstfs );
return NULL;
} //end if
} //end else if
else
{
SourceError( source, "invalid name %s\n", token.string );
return NULL;
} //end else
if ( newindent ) {
if ( !PC_ExpectTokenString( source, "}" ) ) {
FreeFuzzySeperators_r( firstfs );
return NULL;
} //end if
} //end if
} //end if
else
{
FreeFuzzySeperators_r( firstfs );
SourceError( source, "invalid name %s\n", token.string );
return NULL;
} //end else
if ( !PC_ExpectAnyToken( source, &token ) ) {
FreeFuzzySeperators_r( firstfs );
return NULL;
} //end if
} while ( strcmp( token.string, "}" ) );
//
if ( !founddefault ) {
SourceWarning( source, "switch without default\n" );
fs = (fuzzyseperator_t *) GetClearedMemory( sizeof( fuzzyseperator_t ) );
fs->index = index;
fs->value = MAX_INVENTORYVALUE;
fs->weight = 0;
fs->next = NULL;
fs->child = NULL;
if ( lastfs ) {
lastfs->next = fs;
} else { firstfs = fs;}
lastfs = fs;
} //end if
//
return firstfs;
} //end of the function ReadFuzzySeperators_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
weightconfig_t *ReadWeightConfig( char *filename ) {
int newindent, avail = 0, n;
token_t token;
source_t *source;
fuzzyseperator_t *fs;
weightconfig_t *config = NULL;
#ifdef DEBUG
int starttime;
starttime = Sys_MilliSeconds();
#endif //DEBUG
if ( !LibVarGetValue( "bot_reloadcharacters" ) ) {
avail = -1;
for ( n = 0; n < MAX_WEIGHT_FILES; n++ )
{
config = weightFileList[n];
if ( !config ) {
if ( avail == -1 ) {
avail = n;
} //end if
continue;
} //end if
if ( strcmp( filename, config->filename ) == 0 ) {
//botimport.Print( PRT_MESSAGE, "retained %s\n", filename );
return config;
} //end if
} //end for
if ( avail == -1 ) {
botimport.Print( PRT_ERROR, "weightFileList was full trying to load %s\n", filename );
return NULL;
} //end if
} //end if
source = LoadSourceFile( filename );
if ( !source ) {
botimport.Print( PRT_ERROR, "counldn't load %s\n", filename );
return NULL;
} //end if
//
config = (weightconfig_t *) GetClearedMemory( sizeof( weightconfig_t ) );
config->numweights = 0;
Q_strncpyz( config->filename, filename, sizeof( config->filename ) );
//parse the item config file
while ( PC_ReadToken( source, &token ) )
{
if ( !strcmp( token.string, "weight" ) ) {
if ( config->numweights >= MAX_WEIGHTS ) {
SourceWarning( source, "too many fuzzy weights\n" );
break;
} //end if
if ( !PC_ExpectTokenType( source, TT_STRING, 0, &token ) ) {
FreeWeightConfig( config );
FreeSource( source );
return NULL;
} //end if
StripDoubleQuotes( token.string );
config->weights[config->numweights].name = (char *) GetClearedMemory( strlen( token.string ) + 1 );
strcpy( config->weights[config->numweights].name, token.string );
if ( !PC_ExpectAnyToken( source, &token ) ) {
FreeWeightConfig( config );
FreeSource( source );
return NULL;
} //end if
newindent = qfalse;
if ( !strcmp( token.string, "{" ) ) {
newindent = qtrue;
if ( !PC_ExpectAnyToken( source, &token ) ) {
FreeWeightConfig( config );
FreeSource( source );
return NULL;
} //end if
} //end if
if ( !strcmp( token.string, "switch" ) ) {
fs = ReadFuzzySeperators_r( source );
if ( !fs ) {
FreeWeightConfig( config );
FreeSource( source );
return NULL;
} //end if
config->weights[config->numweights].firstseperator = fs;
} //end if
else if ( !strcmp( token.string, "return" ) ) {
fs = (fuzzyseperator_t *) GetClearedMemory( sizeof( fuzzyseperator_t ) );
fs->index = 0;
fs->value = MAX_INVENTORYVALUE;
fs->next = NULL;
fs->child = NULL;
if ( !ReadFuzzyWeight( source, fs ) ) {
FreeMemory( fs );
FreeWeightConfig( config );
FreeSource( source );
return NULL;
} //end if
config->weights[config->numweights].firstseperator = fs;
} //end else if
else
{
SourceError( source, "invalid name %s\n", token.string );
FreeWeightConfig( config );
FreeSource( source );
return NULL;
} //end else
if ( newindent ) {
if ( !PC_ExpectTokenString( source, "}" ) ) {
FreeWeightConfig( config );
FreeSource( source );
return NULL;
} //end if
} //end if
config->numweights++;
} //end if
else
{
SourceError( source, "invalid name %s\n", token.string );
FreeWeightConfig( config );
FreeSource( source );
return NULL;
} //end else
} //end while
//free the source at the end of a pass
FreeSource( source );
//if the file was located in a pak file
#ifdef DEBUG
botimport.Print( PRT_MESSAGE, "loaded %s\n", filename );
if ( bot_developer ) {
botimport.Print( PRT_MESSAGE, "weights loaded in %d msec\n", Sys_MilliSeconds() - starttime );
} //end if
#endif //DEBUG
//
if ( !LibVarGetValue( "bot_reloadcharacters" ) ) {
weightFileList[avail] = config;
} //end if
//
return config;
} //end of the function ReadWeightConfig
#if 0
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean WriteFuzzyWeight( FILE *fp, fuzzyseperator_t *fs ) {
if ( fs->type == WT_BALANCE ) {
if ( fprintf( fp, " return balance(" ) < 0 ) {
return qfalse;
}
if ( !WriteFloat( fp, fs->weight ) ) {
return qfalse;
}
if ( fprintf( fp, "," ) < 0 ) {
return qfalse;
}
if ( !WriteFloat( fp, fs->minweight ) ) {
return qfalse;
}
if ( fprintf( fp, "," ) < 0 ) {
return qfalse;
}
if ( !WriteFloat( fp, fs->maxweight ) ) {
return qfalse;
}
if ( fprintf( fp, ");\n" ) < 0 ) {
return qfalse;
}
} //end if
else
{
if ( fprintf( fp, " return " ) < 0 ) {
return qfalse;
}
if ( !WriteFloat( fp, fs->weight ) ) {
return qfalse;
}
if ( fprintf( fp, ";\n" ) < 0 ) {
return qfalse;
}
} //end else
return qtrue;
} //end of the function WriteFuzzyWeight
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean WriteFuzzySeperators_r( FILE *fp, fuzzyseperator_t *fs, int indent ) {
if ( !WriteIndent( fp, indent ) ) {
return qfalse;
}
if ( fprintf( fp, "switch(%d)\n", fs->index ) < 0 ) {
return qfalse;
}
if ( !WriteIndent( fp, indent ) ) {
return qfalse;
}
if ( fprintf( fp, "{\n" ) < 0 ) {
return qfalse;
}
indent++;
do
{
if ( !WriteIndent( fp, indent ) ) {
return qfalse;
}
if ( fs->next ) {
if ( fprintf( fp, "case %d:", fs->value ) < 0 ) {
return qfalse;
}
} //end if
else
{
if ( fprintf( fp, "default:" ) < 0 ) {
return qfalse;
}
} //end else
if ( fs->child ) {
if ( fprintf( fp, "\n" ) < 0 ) {
return qfalse;
}
if ( !WriteIndent( fp, indent ) ) {
return qfalse;
}
if ( fprintf( fp, "{\n" ) < 0 ) {
return qfalse;
}
if ( !WriteFuzzySeperators_r( fp, fs->child, indent + 1 ) ) {
return qfalse;
}
if ( !WriteIndent( fp, indent ) ) {
return qfalse;
}
if ( fs->next ) {
if ( fprintf( fp, "} //end case\n" ) < 0 ) {
return qfalse;
}
} //end if
else
{
if ( fprintf( fp, "} //end default\n" ) < 0 ) {
return qfalse;
}
} //end else
} //end if
else
{
if ( !WriteFuzzyWeight( fp, fs ) ) {
return qfalse;
}
} //end else
fs = fs->next;
} while ( fs );
indent--;
if ( !WriteIndent( fp, indent ) ) {
return qfalse;
}
if ( fprintf( fp, "} //end switch\n" ) < 0 ) {
return qfalse;
}
return qtrue;
} //end of the function WriteItemFuzzyWeights_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean WriteWeightConfig( char *filename, weightconfig_t *config ) {
int i;
FILE *fp;
weight_t *ifw;
fp = fopen( filename, "wb" );
if ( !fp ) {
return qfalse;
}
for ( i = 0; i < config->numweights; i++ )
{
ifw = &config->weights[i];
if ( fprintf( fp, "\nweight \"%s\"\n", ifw->name ) < 0 ) {
return qfalse;
}
if ( fprintf( fp, "{\n" ) < 0 ) {
return qfalse;
}
if ( ifw->firstseperator->index > 0 ) {
if ( !WriteFuzzySeperators_r( fp, ifw->firstseperator, 1 ) ) {
return qfalse;
}
} //end if
else
{
if ( !WriteIndent( fp, 1 ) ) {
return qfalse;
}
if ( !WriteFuzzyWeight( fp, ifw->firstseperator ) ) {
return qfalse;
}
} //end else
if ( fprintf( fp, "} //end weight\n" ) < 0 ) {
return qfalse;
}
} //end for
fclose( fp );
return qtrue;
} //end of the function WriteWeightConfig
#endif
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int FindFuzzyWeight( weightconfig_t *wc, char *name ) {
int i;
for ( i = 0; i < wc->numweights; i++ )
{
if ( !strcmp( wc->weights[i].name, name ) ) {
return i;
} //end if
} //end if
return -1;
} //end of the function FindFuzzyWeight
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float FuzzyWeight_r( int *inventory, fuzzyseperator_t *fs ) {
float scale, w1, w2;
if ( inventory[fs->index] < fs->value ) {
if ( fs->child ) {
return FuzzyWeight_r( inventory, fs->child );
} else { return fs->weight;}
} //end if
else if ( fs->next ) {
if ( inventory[fs->index] < fs->next->value ) {
//first weight
if ( fs->child ) {
w1 = FuzzyWeight_r( inventory, fs->child );
} else { w1 = fs->weight;}
//second weight
if ( fs->next->child ) {
w2 = FuzzyWeight_r( inventory, fs->next->child );
} else { w2 = fs->next->weight;}
//the scale factor
scale = ( inventory[fs->index] - fs->value ) / ( fs->next->value - fs->value );
//scale between the two weights
return scale * w1 + ( 1 - scale ) * w2;
} //end if
return FuzzyWeight_r( inventory, fs->next );
} //end else if
return fs->weight;
} //end of the function FuzzyWeight_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float FuzzyWeightUndecided_r( int *inventory, fuzzyseperator_t *fs ) {
float scale, w1, w2;
if ( inventory[fs->index] < fs->value ) {
if ( fs->child ) {
return FuzzyWeightUndecided_r( inventory, fs->child );
} else { return fs->minweight + random() * ( fs->maxweight - fs->minweight );}
} //end if
else if ( fs->next ) {
if ( inventory[fs->index] < fs->next->value ) {
//first weight
if ( fs->child ) {
w1 = FuzzyWeightUndecided_r( inventory, fs->child );
} else { w1 = fs->minweight + random() * ( fs->maxweight - fs->minweight );}
//second weight
if ( fs->next->child ) {
w2 = FuzzyWeight_r( inventory, fs->next->child );
} else { w2 = fs->next->minweight + random() * ( fs->next->maxweight - fs->next->minweight );}
//the scale factor
scale = ( inventory[fs->index] - fs->value ) / ( fs->next->value - fs->value );
//scale between the two weights
return scale * w1 + ( 1 - scale ) * w2;
} //end if
return FuzzyWeightUndecided_r( inventory, fs->next );
} //end else if
return fs->weight;
} //end of the function FuzzyWeightUndecided_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float FuzzyWeight( int *inventory, weightconfig_t *wc, int weightnum ) {
#ifdef EVALUATERECURSIVELY
return FuzzyWeight_r( inventory, wc->weights[weightnum].firstseperator );
#else
fuzzyseperator_t *s;
s = wc->weights[weightnum].firstseperator;
if ( !s ) {
return 0;
}
while ( 1 )
{
if ( inventory[s->index] < s->value ) {
if ( s->child ) {
s = s->child;
} else { return s->weight;}
} //end if
else
{
if ( s->next ) {
s = s->next;
} else { return s->weight;}
} //end else
} //end if
return 0;
#endif
} //end of the function FuzzyWeight
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float FuzzyWeightUndecided( int *inventory, weightconfig_t *wc, int weightnum ) {
#ifdef EVALUATERECURSIVELY
return FuzzyWeightUndecided_r( inventory, wc->weights[weightnum].firstseperator );
#else
fuzzyseperator_t *s;
s = wc->weights[weightnum].firstseperator;
if ( !s ) {
return 0;
}
while ( 1 )
{
if ( inventory[s->index] < s->value ) {
if ( s->child ) {
s = s->child;
} else { return s->minweight + random() * ( s->maxweight - s->minweight );}
} //end if
else
{
if ( s->next ) {
s = s->next;
} else { return s->minweight + random() * ( s->maxweight - s->minweight );}
} //end else
} //end if
return 0;
#endif
} //end of the function FuzzyWeightUndecided
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EvolveFuzzySeperator_r( fuzzyseperator_t *fs ) {
if ( fs->child ) {
EvolveFuzzySeperator_r( fs->child );
} //end if
else if ( fs->type == WT_BALANCE ) {
//every once in a while an evolution leap occurs, mutation
if ( random() < 0.01 ) {
fs->weight += crandom() * ( fs->maxweight - fs->minweight );
} else { fs->weight += crandom() * ( fs->maxweight - fs->minweight ) * 0.5;}
//modify bounds if necesary because of mutation
if ( fs->weight < fs->minweight ) {
fs->minweight = fs->weight;
} else if ( fs->weight > fs->maxweight ) {
fs->maxweight = fs->weight;
}
} //end else if
if ( fs->next ) {
EvolveFuzzySeperator_r( fs->next );
}
} //end of the function EvolveFuzzySeperator_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EvolveWeightConfig( weightconfig_t *config ) {
int i;
for ( i = 0; i < config->numweights; i++ )
{
EvolveFuzzySeperator_r( config->weights[i].firstseperator );
} //end for
} //end of the function EvolveWeightConfig
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ScaleFuzzySeperator_r( fuzzyseperator_t *fs, float scale ) {
if ( fs->child ) {
ScaleFuzzySeperator_r( fs->child, scale );
} //end if
else if ( fs->type == WT_BALANCE ) {
//
fs->weight = ( fs->maxweight + fs->minweight ) * scale;
//get the weight between bounds
if ( fs->weight < fs->minweight ) {
fs->weight = fs->minweight;
} else if ( fs->weight > fs->maxweight ) {
fs->weight = fs->maxweight;
}
} //end else if
if ( fs->next ) {
ScaleFuzzySeperator_r( fs->next, scale );
}
} //end of the function ScaleFuzzySeperator_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ScaleWeight( weightconfig_t *config, char *name, float scale ) {
int i;
if ( scale < 0 ) {
scale = 0;
} else if ( scale > 1 ) {
scale = 1;
}
for ( i = 0; i < config->numweights; i++ )
{
if ( !strcmp( name, config->weights[i].name ) ) {
ScaleFuzzySeperator_r( config->weights[i].firstseperator, scale );
break;
} //end if
} //end for
} //end of the function ScaleWeight
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ScaleFuzzySeperatorBalanceRange_r( fuzzyseperator_t *fs, float scale ) {
if ( fs->child ) {
ScaleFuzzySeperatorBalanceRange_r( fs->child, scale );
} //end if
else if ( fs->type == WT_BALANCE ) {
float mid = ( fs->minweight + fs->maxweight ) * 0.5;
//get the weight between bounds
fs->maxweight = mid + ( fs->maxweight - mid ) * scale;
fs->minweight = mid + ( fs->minweight - mid ) * scale;
if ( fs->maxweight < fs->minweight ) {
fs->maxweight = fs->minweight;
} //end if
} //end else if
if ( fs->next ) {
ScaleFuzzySeperatorBalanceRange_r( fs->next, scale );
}
} //end of the function ScaleFuzzySeperatorBalanceRange_r
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void ScaleFuzzyBalanceRange( weightconfig_t *config, float scale ) {
int i;
if ( scale < 0 ) {
scale = 0;
} else if ( scale > 100 ) {
scale = 100;
}
for ( i = 0; i < config->numweights; i++ )
{
ScaleFuzzySeperatorBalanceRange_r( config->weights[i].firstseperator, scale );
} //end for
} //end of the function ScaleFuzzyBalanceRange
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int InterbreedFuzzySeperator_r( fuzzyseperator_t *fs1, fuzzyseperator_t *fs2,
fuzzyseperator_t *fsout ) {
if ( fs1->child ) {
if ( !fs2->child || !fsout->child ) {
botimport.Print( PRT_ERROR, "cannot interbreed weight configs, unequal child\n" );
return qfalse;
} //end if
if ( !InterbreedFuzzySeperator_r( fs2->child, fs2->child, fsout->child ) ) {
return qfalse;
} //end if
} //end if
else if ( fs1->type == WT_BALANCE ) {
if ( fs2->type != WT_BALANCE || fsout->type != WT_BALANCE ) {
botimport.Print( PRT_ERROR, "cannot interbreed weight configs, unequal balance\n" );
return qfalse;
} //end if
fsout->weight = ( fs1->weight + fs2->weight ) / 2;
if ( fsout->weight > fsout->maxweight ) {
fsout->maxweight = fsout->weight;
}
if ( fsout->weight > fsout->minweight ) {
fsout->minweight = fsout->weight;
}
} //end else if
if ( fs1->next ) {
if ( !fs2->next || !fsout->next ) {
botimport.Print( PRT_ERROR, "cannot interbreed weight configs, unequal next\n" );
return qfalse;
} //end if
if ( !InterbreedFuzzySeperator_r( fs1->next, fs2->next, fsout->next ) ) {
return qfalse;
} //end if
} //end if
return qtrue;
} //end of the function InterbreedFuzzySeperator_r
//===========================================================================
// config1 and config2 are interbreeded and stored in configout
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void InterbreedWeightConfigs( weightconfig_t *config1, weightconfig_t *config2,
weightconfig_t *configout ) {
int i;
if ( config1->numweights != config2->numweights ||
config1->numweights != configout->numweights ) {
botimport.Print( PRT_ERROR, "cannot interbreed weight configs, unequal numweights\n" );
return;
} //end if
for ( i = 0; i < config1->numweights; i++ )
{
InterbreedFuzzySeperator_r( config1->weights[i].firstseperator,
config2->weights[i].firstseperator,
configout->weights[i].firstseperator );
} //end for
} //end of the function InterbreedWeightConfigs
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void BotShutdownWeights( void ) {
int i;
for ( i = 0; i < MAX_WEIGHT_FILES; i++ )
{
if ( weightFileList[i] ) {
FreeWeightConfig2( weightFileList[i] );
weightFileList[i] = NULL;
} //end if
} //end for
} //end of the function BotShutdownWeights

89
src/botlib/be_ai_weight.h Normal file
View File

@@ -0,0 +1,89 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_ai_weight.h
*
* desc: fuzzy weights
*
*
*****************************************************************************/
#define WT_BALANCE 1
#define MAX_WEIGHTS 128
//fuzzy seperator
typedef struct fuzzyseperator_s
{
int index;
int value;
int type;
float weight;
float minweight;
float maxweight;
struct fuzzyseperator_s *child;
struct fuzzyseperator_s *next;
} fuzzyseperator_t;
//fuzzy weight
typedef struct weight_s
{
char *name;
struct fuzzyseperator_s *firstseperator;
} weight_t;
//weight configuration
typedef struct weightconfig_s
{
int numweights;
weight_t weights[MAX_WEIGHTS];
char filename[MAX_QPATH];
} weightconfig_t;
//reads a weight configuration
weightconfig_t *ReadWeightConfig( char *filename );
//free a weight configuration
void FreeWeightConfig( weightconfig_t *config );
//writes a weight configuration, returns true if successfull
qboolean WriteWeightConfig( char *filename, weightconfig_t *config );
//find the fuzzy weight with the given name
int FindFuzzyWeight( weightconfig_t *wc, char *name );
//returns the fuzzy weight for the given inventory and weight
float FuzzyWeight( int *inventory, weightconfig_t *wc, int weightnum );
float FuzzyWeightUndecided( int *inventory, weightconfig_t *wc, int weightnum );
//scales the weight with the given name
void ScaleWeight( weightconfig_t *config, char *name, float scale );
//scale the balance range
void ScaleBalanceRange( weightconfig_t *config, float scale );
//evolves the weight configuration
void EvolveWeightConfig( weightconfig_t *config );
//interbreed the weight configurations and stores the interbreeded one in configout
void InterbreedWeightConfigs( weightconfig_t *config1, weightconfig_t *config2, weightconfig_t *configout );
//frees cached weight configurations
void BotShutdownWeights( void );

493
src/botlib/be_ea.c Normal file
View File

@@ -0,0 +1,493 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_ea.c
*
* desc: elementary actions
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "../game/botlib.h"
#include "be_interface.h"
#define MAX_USERMOVE 400
#define MAX_COMMANDARGUMENTS 10
#define ACTION_JUMPEDLASTFRAME 128
bot_input_t *botinputs;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Say( int client, char *str ) {
botimport.BotClientCommand( client, va( "say %s", str ) );
} //end of the function EA_Say
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_SayTeam( int client, char *str ) {
botimport.BotClientCommand( client, va( "say_team %s", str ) );
} //end of the function EA_SayTeam
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_UseItem( int client, char *it ) {
botimport.BotClientCommand( client, va( "use %s", it ) );
} //end of the function EA_UseItem
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_DropItem( int client, char *it ) {
botimport.BotClientCommand( client, va( "drop %s", it ) );
} //end of the function EA_DropItem
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_UseInv( int client, char *inv ) {
botimport.BotClientCommand( client, va( "invuse %s", inv ) );
} //end of the function EA_UseInv
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_DropInv( int client, char *inv ) {
botimport.BotClientCommand( client, va( "invdrop %s", inv ) );
} //end of the function EA_DropInv
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Gesture( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_GESTURE;
} //end of the function EA_Gesture
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Command( int client, char *command ) {
botimport.BotClientCommand( client, command );
} //end of the function EA_Command
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_SelectWeapon( int client, int weapon ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->weapon = weapon;
} //end of the function EA_SelectWeapon
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Attack( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_ATTACK;
} //end of the function EA_Attack
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Reload( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_RELOAD;
} //end of the function EA_Attack
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Talk( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_TALK;
} //end of the function EA_Talk
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Use( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_USE;
} //end of the function EA_Use
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Respawn( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_RESPAWN;
} //end of the function EA_Respawn
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Jump( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
if ( bi->actionflags & ACTION_JUMPEDLASTFRAME ) {
bi->actionflags &= ~ACTION_JUMP;
} //end if
else
{
bi->actionflags |= ACTION_JUMP;
} //end if
} //end of the function EA_Jump
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_DelayedJump( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
if ( bi->actionflags & ACTION_JUMPEDLASTFRAME ) {
bi->actionflags &= ~ACTION_DELAYEDJUMP;
} //end if
else
{
bi->actionflags |= ACTION_DELAYEDJUMP;
} //end if
} //end of the function EA_DelayedJump
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Crouch( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_CROUCH;
} //end of the function EA_Crouch
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Walk( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_WALK;
} //end of the function EA_Walk
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_MoveUp( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_MOVEUP;
} //end of the function EA_MoveUp
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_MoveDown( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_MOVEDOWN;
} //end of the function EA_MoveDown
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_MoveForward( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_MOVEFORWARD;
} //end of the function EA_MoveForward
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_MoveBack( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_MOVEBACK;
} //end of the function EA_MoveBack
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_MoveLeft( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_MOVELEFT;
} //end of the function EA_MoveLeft
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_MoveRight( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_MOVERIGHT;
} //end of the function EA_MoveRight
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Move( int client, vec3_t dir, float speed ) {
bot_input_t *bi;
bi = &botinputs[client];
VectorCopy( dir, bi->dir );
//cap speed
if ( speed > MAX_USERMOVE ) {
speed = MAX_USERMOVE;
} else if ( speed < -MAX_USERMOVE ) {
speed = -MAX_USERMOVE;
}
bi->speed = speed;
} //end of the function EA_Move
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_View( int client, vec3_t viewangles ) {
bot_input_t *bi;
bi = &botinputs[client];
VectorCopy( viewangles, bi->viewangles );
} //end of the function EA_View
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Prone( int client ) {
bot_input_t *bi;
bi = &botinputs[client];
bi->actionflags |= ACTION_PRONE;
} //end of the function EA_Prone
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_EndRegular( int client, float thinktime ) {
/*
bot_input_t *bi;
int jumped = qfalse;
bi = &botinputs[client];
bi->actionflags &= ~ACTION_JUMPEDLASTFRAME;
bi->thinktime = thinktime;
botimport.BotInput(client, bi);
bi->thinktime = 0;
VectorClear(bi->dir);
bi->speed = 0;
jumped = bi->actionflags & ACTION_JUMP;
bi->actionflags = 0;
if (jumped) bi->actionflags |= ACTION_JUMPEDLASTFRAME;
*/
} //end of the function EA_EndRegular
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_GetInput( int client, float thinktime, bot_input_t *input ) {
bot_input_t *bi;
// int jumped = qfalse;
bi = &botinputs[client];
// bi->actionflags &= ~ACTION_JUMPEDLASTFRAME;
bi->thinktime = thinktime;
memcpy( input, bi, sizeof( bot_input_t ) );
/*
bi->thinktime = 0;
VectorClear(bi->dir);
bi->speed = 0;
jumped = bi->actionflags & ACTION_JUMP;
bi->actionflags = 0;
if (jumped) bi->actionflags |= ACTION_JUMPEDLASTFRAME;
*/
} //end of the function EA_GetInput
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_ResetInput( int client, bot_input_t *init ) {
bot_input_t *bi;
int jumped = qfalse;
bi = &botinputs[client];
bi->actionflags &= ~ACTION_JUMPEDLASTFRAME;
bi->thinktime = 0;
VectorClear( bi->dir );
bi->speed = 0;
jumped = bi->actionflags & ACTION_JUMP;
bi->actionflags = 0;
if ( jumped ) {
bi->actionflags |= ACTION_JUMPEDLASTFRAME;
}
if ( init ) {
memcpy( bi, init, sizeof( bot_input_t ) );
}
} //end of the function EA_ResetInput
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int EA_Setup( void ) {
//initialize the bot inputs
botinputs = (bot_input_t *) GetClearedHunkMemory(
botlibglobals.maxclients * sizeof( bot_input_t ) );
return BLERR_NOERROR;
} //end of the function EA_Setup
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void EA_Shutdown( void ) {
FreeMemory( botinputs );
botinputs = NULL;
} //end of the function EA_Shutdown

878
src/botlib/be_interface.c Normal file
View File

@@ -0,0 +1,878 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_interface.c
*
* desc: bot library interface
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_log.h"
#include "l_libvar.h"
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "aasfile.h"
#include "../game/botlib.h"
#include "../game/be_aas.h"
#include "be_aas_funcs.h"
#include "be_aas_def.h"
#include "be_interface.h"
#include "../game/be_ea.h"
#include "be_ai_weight.h"
#include "../game/be_ai_goal.h"
#include "../game/be_ai_move.h"
#include "../game/be_ai_weap.h"
#include "../game/be_ai_chat.h"
#include "../game/be_ai_char.h"
#include "../game/be_ai_gen.h"
//library globals in a structure
botlib_globals_t botlibglobals;
botlib_export_t be_botlib_export;
botlib_import_t botimport;
//
int bot_developer;
//qtrue if the library is setup
int botlibsetup = qfalse;
//===========================================================================
//
// several functions used by the exported functions
//
//===========================================================================
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
// Ridah, faster Win32 code
#ifdef _WIN32
#undef MAX_PATH // this is an ugly hack, to temporarily ignore the current definition, since it's also defined in windows.h
#include <windows.h>
#undef MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
int Sys_MilliSeconds( void ) {
// Ridah, faster Win32 code
#ifdef _WIN32
int sys_curtime;
static qboolean initialized = qfalse;
static int sys_timeBase;
if ( !initialized ) {
sys_timeBase = timeGetTime();
initialized = qtrue;
}
sys_curtime = timeGetTime() - sys_timeBase;
return sys_curtime;
#else
return clock() * 1000 / CLOCKS_PER_SEC;
#endif
} //end of the function Sys_MilliSeconds
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean ValidClientNumber( int num, char *str ) {
if ( num < 0 || num > botlibglobals.maxclients ) {
//weird: the disabled stuff results in a crash
botimport.Print( PRT_ERROR, "%s: invalid client number %d, [0, %d]\n",
str, num, botlibglobals.maxclients );
return qfalse;
} //end if
return qtrue;
} //end of the function BotValidateClientNumber
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean ValidEntityNumber( int num, char *str ) {
if ( num < 0 || num > botlibglobals.maxentities ) {
botimport.Print( PRT_ERROR, "%s: invalid entity number %d, [0, %d]\n",
str, num, botlibglobals.maxentities );
return qfalse;
} //end if
return qtrue;
} //end of the function BotValidateClientNumber
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean BotLibSetup( char *str ) {
// return qtrue;
if ( !botlibglobals.botlibsetup ) {
botimport.Print( PRT_ERROR, "%s: bot library used before being setup\n", str );
return qfalse;
} //end if
return qtrue;
} //end of the function BotLibSetup
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
extern define_t *globaldefines;
int Export_BotLibSetup( qboolean singleplayer ) {
int errnum;
bot_developer = LibVarGetValue( "bot_developer" );
//initialize byte swapping (litte endian etc.)
Swap_Init();
Log_Open( "botlib.log" );
//
botimport.Print( PRT_MESSAGE, "------- BotLib Initialization -------\n" );
//
botlibglobals.maxclients = (int) LibVarValue( "maxclients", "128" );
botlibglobals.maxentities = (int) LibVarValue( "maxentities", "1024" );
errnum = AAS_Setup(); //be_aas_main.c
if ( errnum != BLERR_NOERROR ) {
return errnum;
}
errnum = EA_Setup(); //be_ea.c
if ( errnum != BLERR_NOERROR ) {
return errnum;
}
errnum = BotSetupWeaponAI(); //be_ai_weap.c
if ( errnum != BLERR_NOERROR ) {
return errnum;
}
// START Arnout changes, 28-08-2002.
// added single player
errnum = BotSetupGoalAI( singleplayer ); //be_ai_goal.c
// END Arnout changes, 28-08-2002.
if ( errnum != BLERR_NOERROR ) {
return errnum;
}
errnum = BotSetupChatAI(); //be_ai_chat.c
if ( errnum != BLERR_NOERROR ) {
return errnum;
}
errnum = BotSetupMoveAI(); //be_ai_move.c
if ( errnum != BLERR_NOERROR ) {
return errnum;
}
globaldefines = NULL;
botlibsetup = qtrue;
botlibglobals.botlibsetup = qtrue;
return BLERR_NOERROR;
} //end of the function Export_BotLibSetup
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Export_BotLibShutdown( void ) {
static int recursive = 0;
if ( !BotLibSetup( "BotLibShutdown" ) ) {
return BLERR_LIBRARYNOTSETUP;
}
//
if ( recursive ) {
return BLERR_NOERROR;
}
recursive = 1;
// shutdown all AI subsystems
BotShutdownChatAI(); //be_ai_chat.c
BotShutdownMoveAI(); //be_ai_move.c
BotShutdownGoalAI(); //be_ai_goal.c
BotShutdownWeaponAI(); //be_ai_weap.c
BotShutdownWeights(); //be_ai_weight.c
BotShutdownCharacters(); //be_ai_char.c
// shutdown AAS
AAS_Shutdown();
// shutdown bot elemantary actions
EA_Shutdown();
// free all libvars
LibVarDeAllocAll();
// remove all global defines from the pre compiler
PC_RemoveAllGlobalDefines();
// shut down library log file
Log_Shutdown();
//
botlibsetup = qfalse;
botlibglobals.botlibsetup = qfalse;
recursive = 0;
// print any files still open
PC_CheckOpenSourceHandles();
//
#ifdef _DEBUG
Log_AlwaysOpen( "memory.log" );
PrintMemoryLabels();
Log_Shutdown();
#endif
return BLERR_NOERROR;
} //end of the function Export_BotLibShutdown
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Export_BotLibVarSet( char *var_name, char *value ) {
LibVarSet( var_name, value );
return BLERR_NOERROR;
} //end of the function Export_BotLibVarSet
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Export_BotLibVarGet( char *var_name, char *value, int size ) {
char *varvalue;
varvalue = LibVarGetString( var_name );
strncpy( value, varvalue, size - 1 );
value[size - 1] = '\0';
return BLERR_NOERROR;
} //end of the function Export_BotLibVarGet
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Export_BotLibStartFrame( float time ) {
if ( !BotLibSetup( "BotStartFrame" ) ) {
return BLERR_LIBRARYNOTSETUP;
}
return AAS_StartFrame( time );
} //end of the function Export_BotLibStartFrame
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_EnableAllAreas( void );
int Export_BotLibLoadMap( const char *mapname ) {
#ifdef DEBUG
int starttime = Sys_MilliSeconds();
#endif
int errnum;
if ( !BotLibSetup( "BotLoadMap" ) ) {
return BLERR_LIBRARYNOTSETUP;
}
//
// if the mapname is NULL, then this is a restart
if ( !mapname ) {
// START Arnout changes, 29-08-2002.
// don't init the heap if no aas loaded, causes "SV_Bot_HunkAlloc: Alloc with marks already set"
if ( ( *aasworld ).loaded ) {
AAS_InitAASLinkHeap();
AAS_EnableAllAreas();
}
// END Arnout changes, 29-08-2002.
( *aasworld ).numframes = 0;
memset( ( *aasworld ).arealinkedentities, 0, ( *aasworld ).numareas * sizeof( aas_link_t * ) );
memset( ( *aasworld ).entities, 0, ( *aasworld ).maxentities * sizeof( aas_entity_t ) );
return BLERR_NOERROR;
}
//
botimport.Print( PRT_MESSAGE, "------------ Map Loading ------------\n" );
//startup AAS for the current map, model and sound index
errnum = AAS_LoadMap( mapname );
if ( errnum != BLERR_NOERROR ) {
return errnum;
}
//initialize the items in the level
BotInitLevelItems(); //be_ai_goal.h
BotSetBrushModelTypes(); //be_ai_move.h
//
botimport.Print( PRT_MESSAGE, "-------------------------------------\n" );
#ifdef DEBUG
botimport.Print( PRT_MESSAGE, "map loaded in %d msec\n", Sys_MilliSeconds() - starttime );
#endif
//
return BLERR_NOERROR;
} //end of the function Export_BotLibLoadMap
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int Export_BotLibUpdateEntity( int ent, bot_entitystate_t *state ) {
if ( !BotLibSetup( "BotUpdateEntity" ) ) {
return BLERR_LIBRARYNOTSETUP;
}
if ( !ValidEntityNumber( ent, "BotUpdateEntity" ) ) {
return BLERR_INVALIDENTITYNUMBER;
}
return AAS_UpdateEntity( ent, state );
} //end of the function Export_BotLibUpdateEntity
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void AAS_TestMovementPrediction( int entnum, vec3_t origin, vec3_t dir );
void ElevatorBottomCenter( aas_reachability_t *reach, vec3_t bottomcenter );
int BotGetReachabilityToGoal( vec3_t origin, int areanum, int entnum,
int lastgoalareanum, int lastareanum,
int *avoidreach, float *avoidreachtimes, int *avoidreachtries,
bot_goal_t *goal, int travelflags, int movetravelflags );
int AAS_PointLight( vec3_t origin, int *red, int *green, int *blue );
int AAS_TraceAreas( vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas );
int AAS_Reachability_WeaponJump( int area1num, int area2num );
int BotFuzzyPointReachabilityArea( vec3_t origin );
float BotGapDistance( vec3_t origin, vec3_t hordir, int entnum );
int AAS_NearestHideArea( int srcnum, vec3_t origin, int areanum, int enemynum, vec3_t enemyorigin, int enemyareanum, int travelflags, float maxdist, vec3_t distpos );
int AAS_FindAttackSpotWithinRange( int srcnum, int rangenum, int enemynum, float rangedist, int travelflags, float *outpos );
int AAS_ListAreasInRange( vec3_t srcpos, int srcarea, float range, int travelflags, vec3_t *outareas, int maxareas );
int AAS_AvoidDangerArea( vec3_t srcpos, int srcarea, vec3_t dangerpos, int dangerarea, float range, int travelflags );
int AAS_Retreat( int *dangerSpots, int dangerSpotCount, vec3_t srcpos, int srcarea, vec3_t dangerpos, int dangerarea, float range, float dangerRange, int travelflags );
int AAS_AlternativeRouteGoals( vec3_t start, vec3_t goal, int travelflags,
aas_altroutegoal_t *altroutegoals, int maxaltroutegoals,
int color );
void AAS_SetAASBlockingEntity( vec3_t absmin, vec3_t absmax, int blocking );
void AAS_RecordTeamDeathArea( vec3_t srcpos, int srcarea, int team, int teamCount, int travelflags );
int BotExportTest( int parm0, char *parm1, vec3_t parm2, vec3_t parm3 ) {
static int area = -1;
static int line[2];
int newarea, i, highlightarea, bot_testhidepos, hideposarea, bot_debug;
vec3_t forward, origin;
// vec3_t mins = {-16, -16, -24};
// vec3_t maxs = {16, 16, 32};
if ( !aasworld->loaded ) {
return 0;
}
AAS_SetCurrentWorld( 0 );
for ( i = 0; i < 2; i++ ) {
if ( !line[i] ) {
line[i] = botimport.DebugLineCreate();
}
}
// AAS_ClearShownDebugLines();
bot_testhidepos = LibVarGetValue( "bot_testhidepos" );
if ( bot_testhidepos ) {
VectorCopy( parm2, origin );
newarea = BotFuzzyPointReachabilityArea( origin );
if ( parm0 & 1 ) {
botlibglobals.goalareanum = newarea;
VectorCopy( origin, botlibglobals.goalorigin );
botimport.Print( PRT_MESSAGE, "new enemy position %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea );
} //end if
AAS_ClearShownPolygons();
AAS_ClearShownDebugLines();
hideposarea = AAS_NearestHideArea( 0, origin, AAS_PointAreaNum( origin ), 0,
botlibglobals.goalorigin, botlibglobals.goalareanum, TFL_DEFAULT, 99999, NULL );
//area we are currently in
AAS_ShowAreaPolygons( newarea, 1, qtrue );
//enemy position
AAS_ShowAreaPolygons( botlibglobals.goalareanum, 2, qtrue );
//area we should go hide
AAS_ShowAreaPolygons( hideposarea, 4, qtrue );
return 0;
}
highlightarea = LibVarGetValue( "bot_highlightarea" );
if ( highlightarea > 0 ) {
newarea = highlightarea;
} else {
VectorCopy( parm2, origin );
//origin[2] += 0.5;
newarea = BotFuzzyPointReachabilityArea( origin );
} //end else
bot_debug = LibVarGetValue( "bot_debug" );
if ( bot_debug == 9 ) {
aas_clientmove_t move;
vec3_t dest;
qboolean this_success;
if ( parm0 & 1 ) {
botlibglobals.goalareanum = newarea;
VectorCopy( parm2, botlibglobals.goalorigin );
botimport.Print( PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea );
}
VectorCopy( parm2, origin );
VectorCopy( botlibglobals.goalorigin, dest );
// debug direct movement
VectorSubtract( dest, origin, forward );
VectorNormalize( forward );
VectorScale( forward, 300, forward );
this_success = AAS_PredictClientMovement( &move, 0, origin,
-1, qfalse,
forward, dest, -1,
40, 0.05, SE_ENTERAREA | SE_HITGROUNDDAMAGE | SE_HITENT | SE_HITGROUNDAREA | SE_STUCK | SE_GAP, botlibglobals.goalareanum,
qtrue );
if ( this_success ) {
switch ( move.stopevent ) {
case SE_ENTERAREA:
case SE_HITENT:
case SE_HITGROUNDAREA:
break;
default:
this_success = qfalse;
}
}
if ( this_success != botlibglobals.lastsuccess ) {
botimport.Print( PRT_MESSAGE, "DirectMove: %s\n", this_success ? "SUCCESS" : "FAILURE" );
botlibglobals.lastsuccess = this_success;
}
return 0;
}
botimport.Print( PRT_MESSAGE, "\rtravel time to goal (%d) = %d ", botlibglobals.goalareanum, AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT ) );
if ( newarea != area ) {
botimport.Print( PRT_MESSAGE, "origin = %f, %f, %f\n", origin[0], origin[1], origin[2] );
area = newarea;
botimport.Print( PRT_MESSAGE, "new area %d, cluster %d, presence type %d\n", area, AAS_AreaCluster( area ), AAS_PointPresenceType( origin ) );
if ( aasworld->areasettings[area].areaflags & AREA_LIQUID ) {
botimport.Print( PRT_MESSAGE, "liquid area\n" );
} //end if
botimport.Print( PRT_MESSAGE, "area contents: " );
if ( aasworld->areasettings[area].contents & AREACONTENTS_MOVER ) {
botimport.Print( PRT_MESSAGE, "mover " );
} //end if
if ( aasworld->areasettings[area].contents & AREACONTENTS_WATER ) {
botimport.Print( PRT_MESSAGE, "water " );
} //end if
if ( aasworld->areasettings[area].contents & AREACONTENTS_LAVA ) {
botimport.Print( PRT_MESSAGE, "lava " );
} //end if
if ( aasworld->areasettings[area].contents & AREACONTENTS_SLIME ) {
botimport.Print( PRT_MESSAGE, "slag " );
} //end if
if ( aasworld->areasettings[area].contents & AREACONTENTS_JUMPPAD ) {
botimport.Print( PRT_MESSAGE, "jump pad " );
} //end if
if ( aasworld->areasettings[area].contents & AREACONTENTS_CLUSTERPORTAL ) {
botimport.Print( PRT_MESSAGE, "cluster portal " );
} //end if
if ( aasworld->areasettings[area].contents & AREACONTENTS_DONOTENTER ) {
botimport.Print( PRT_MESSAGE, "do not enter " );
} //end if
if ( aasworld->areasettings[area].contents & AREACONTENTS_DONOTENTER_LARGE ) {
botimport.Print( PRT_MESSAGE, "do not enter large " );
} //end if
if ( !aasworld->areasettings[area].contents ) {
botimport.Print( PRT_MESSAGE, "empty " );
} //end if
botimport.Print( PRT_MESSAGE, "\n" );
botimport.Print( PRT_MESSAGE, "area flags: " );
if ( aasworld->areasettings[area].areaflags & AREA_LADDER ) {
botimport.Print( PRT_MESSAGE, "ladder " );
}
if ( aasworld->areasettings[area].areaflags & AREA_GROUNDED ) {
botimport.Print( PRT_MESSAGE, "grounded " );
}
if ( aasworld->areasettings[area].areaflags & AREA_LIQUID ) {
botimport.Print( PRT_MESSAGE, "liquid " );
}
if ( aasworld->areasettings[area].areaflags & AREA_DISABLED ) {
botimport.Print( PRT_MESSAGE, "DISABLED " );
}
if ( aasworld->areasettings[area].areaflags & AREA_AVOID ) {
botimport.Print( PRT_MESSAGE, "AVOID " );
}
botimport.Print( PRT_MESSAGE, "\n" );
botimport.Print( PRT_MESSAGE, "travel time to goal (%d) = %d\n", botlibglobals.goalareanum, AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT | TFL_ROCKETJUMP ) );
}
if ( parm0 & 1 ) {
botlibglobals.goalareanum = newarea;
VectorCopy( parm2, botlibglobals.goalorigin );
botimport.Print( PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n", origin[0], origin[1], origin[2], newarea );
}
AAS_ClearShownPolygons();
AAS_ClearShownDebugLines();
if ( parm0 & 8 ) {
int jk = 0;
if ( parm0 & 16 ) {
for ( ; jk < aasworld->numareas; jk++ ) {
if ( !( aasworld->areasettings[jk].areaflags & AREA_DISABLED ) ) {
AAS_ShowAreaPolygons( jk, 1, parm0 & 4 );
}
}
} else {
for ( ; jk < aasworld->numareas; jk++ ) {
AAS_ShowAreaPolygons( jk, 1, parm0 & 4 );
}
}
} else {
AAS_ShowAreaPolygons( newarea, 1, parm0 & 4 );
}
if ( parm0 & 2 ) {
AAS_ShowReachableAreas( area );
} else {
static int lastgoalareanum, lastareanum;
static int avoidreach[MAX_AVOIDREACH];
static float avoidreachtimes[MAX_AVOIDREACH];
static int avoidreachtries[MAX_AVOIDREACH];
int reachnum;
bot_goal_t goal;
aas_reachability_t reach;
static int lastreach;
goal.areanum = botlibglobals.goalareanum;
VectorCopy( botlibglobals.goalorigin, goal.origin );
reachnum = BotGetReachabilityToGoal( origin, newarea, -1,
lastgoalareanum, lastareanum,
avoidreach, avoidreachtimes, avoidreachtries,
&goal, TFL_DEFAULT | TFL_FUNCBOB, TFL_DEFAULT );
AAS_ReachabilityFromNum( reachnum, &reach );
if ( lastreach != reachnum ) {
botimport.Print( PRT_MESSAGE, "Travel Type: " );
AAS_PrintTravelType( reach.traveltype );
botimport.Print( PRT_MESSAGE, "\n" );
}
lastreach = reachnum;
AAS_ShowReachability( &reach );
} //end else
VectorClear( forward );
return 0;
} //end of the function BotExportTest
/*
============
Init_AAS_Export
============
*/
static void Init_AAS_Export( aas_export_t *aas ) {
//--------------------------------------------
// be_aas_entity.c
//--------------------------------------------
aas->AAS_EntityInfo = AAS_EntityInfo;
//--------------------------------------------
// be_aas_main.c
//--------------------------------------------
aas->AAS_Initialized = AAS_Initialized;
aas->AAS_PresenceTypeBoundingBox = AAS_PresenceTypeBoundingBox;
aas->AAS_Time = AAS_Time;
//--------------------------------------------
// be_aas_sample.c
//--------------------------------------------
aas->AAS_PointAreaNum = AAS_PointAreaNum;
aas->AAS_TraceAreas = AAS_TraceAreas;
aas->AAS_BBoxAreas = AAS_BBoxAreas;
aas->AAS_AreaCenter = AAS_AreaCenter;
aas->AAS_AreaWaypoint = AAS_AreaWaypoint;
//--------------------------------------------
// be_aas_bspq3.c
//--------------------------------------------
aas->AAS_PointContents = AAS_PointContents;
aas->AAS_NextBSPEntity = AAS_NextBSPEntity;
aas->AAS_ValueForBSPEpairKey = AAS_ValueForBSPEpairKey;
aas->AAS_VectorForBSPEpairKey = AAS_VectorForBSPEpairKey;
aas->AAS_FloatForBSPEpairKey = AAS_FloatForBSPEpairKey;
aas->AAS_IntForBSPEpairKey = AAS_IntForBSPEpairKey;
//--------------------------------------------
// be_aas_reach.c
//--------------------------------------------
aas->AAS_AreaReachability = AAS_AreaReachability;
aas->AAS_AreaLadder = AAS_AreaLadder;
//--------------------------------------------
// be_aas_route.c
//--------------------------------------------
aas->AAS_AreaTravelTimeToGoalArea = AAS_AreaTravelTimeToGoalArea;
//--------------------------------------------
// be_aas_move.c
//--------------------------------------------
aas->AAS_Swimming = AAS_Swimming;
aas->AAS_PredictClientMovement = AAS_PredictClientMovement;
// Ridah, route-tables
//--------------------------------------------
// be_aas_routetable.c
//--------------------------------------------
aas->AAS_RT_ShowRoute = AAS_RT_ShowRoute;
aas->AAS_RT_GetHidePos = AAS_RT_GetHidePos;
aas->AAS_FindAttackSpotWithinRange = AAS_FindAttackSpotWithinRange;
aas->AAS_NearestHideArea = AAS_NearestHideArea;
aas->AAS_ListAreasInRange = AAS_ListAreasInRange;
aas->AAS_AvoidDangerArea = AAS_AvoidDangerArea;
aas->AAS_Retreat = AAS_Retreat;
aas->AAS_AlternativeRouteGoals = AAS_AlternativeRouteGoals;
aas->AAS_SetAASBlockingEntity = AAS_SetAASBlockingEntity;
aas->AAS_RecordTeamDeathArea = AAS_RecordTeamDeathArea;
// done.
// Ridah, multiple AAS files
aas->AAS_SetCurrentWorld = AAS_SetCurrentWorld;
// done.
}
/*
============
Init_EA_Export
============
*/
static void Init_EA_Export( ea_export_t *ea ) {
//ClientCommand elementary actions
ea->EA_Say = EA_Say;
ea->EA_SayTeam = EA_SayTeam;
ea->EA_UseItem = EA_UseItem;
ea->EA_DropItem = EA_DropItem;
ea->EA_UseInv = EA_UseInv;
ea->EA_DropInv = EA_DropInv;
ea->EA_Gesture = EA_Gesture;
ea->EA_Command = EA_Command;
ea->EA_SelectWeapon = EA_SelectWeapon;
ea->EA_Talk = EA_Talk;
ea->EA_Attack = EA_Attack;
ea->EA_Reload = EA_Reload;
ea->EA_Use = EA_Use;
ea->EA_Respawn = EA_Respawn;
ea->EA_Jump = EA_Jump;
ea->EA_DelayedJump = EA_DelayedJump;
ea->EA_Crouch = EA_Crouch;
ea->EA_Walk = EA_Walk;
ea->EA_MoveUp = EA_MoveUp;
ea->EA_MoveDown = EA_MoveDown;
ea->EA_MoveForward = EA_MoveForward;
ea->EA_MoveBack = EA_MoveBack;
ea->EA_MoveLeft = EA_MoveLeft;
ea->EA_MoveRight = EA_MoveRight;
ea->EA_Move = EA_Move;
ea->EA_View = EA_View;
ea->EA_GetInput = EA_GetInput;
ea->EA_EndRegular = EA_EndRegular;
ea->EA_ResetInput = EA_ResetInput;
ea->EA_Prone = EA_Prone;
}
/*
============
Init_AI_Export
============
*/
static void Init_AI_Export( ai_export_t *ai ) {
//-----------------------------------
// be_ai_char.h
//-----------------------------------
ai->BotLoadCharacter = BotLoadCharacter;
ai->BotFreeCharacter = BotFreeCharacter;
ai->Characteristic_Float = Characteristic_Float;
ai->Characteristic_BFloat = Characteristic_BFloat;
ai->Characteristic_Integer = Characteristic_Integer;
ai->Characteristic_BInteger = Characteristic_BInteger;
ai->Characteristic_String = Characteristic_String;
//-----------------------------------
// be_ai_chat.h
//-----------------------------------
ai->BotAllocChatState = BotAllocChatState;
ai->BotFreeChatState = BotFreeChatState;
ai->BotQueueConsoleMessage = BotQueueConsoleMessage;
ai->BotRemoveConsoleMessage = BotRemoveConsoleMessage;
ai->BotNextConsoleMessage = BotNextConsoleMessage;
ai->BotNumConsoleMessages = BotNumConsoleMessages;
ai->BotInitialChat = BotInitialChat;
ai->BotNumInitialChats = BotNumInitialChats;
ai->BotReplyChat = BotReplyChat;
ai->BotChatLength = BotChatLength;
ai->BotEnterChat = BotEnterChat;
ai->BotGetChatMessage = BotGetChatMessage;
ai->StringContains = StringContains;
ai->BotFindMatch = BotFindMatch;
ai->BotMatchVariable = BotMatchVariable;
ai->UnifyWhiteSpaces = UnifyWhiteSpaces;
ai->BotReplaceSynonyms = BotReplaceSynonyms;
ai->BotLoadChatFile = BotLoadChatFile;
ai->BotSetChatGender = BotSetChatGender;
ai->BotSetChatName = BotSetChatName;
//-----------------------------------
// be_ai_goal.h
//-----------------------------------
ai->BotResetGoalState = BotResetGoalState;
ai->BotResetAvoidGoals = BotResetAvoidGoals;
ai->BotRemoveFromAvoidGoals = BotRemoveFromAvoidGoals;
ai->BotPushGoal = BotPushGoal;
ai->BotPopGoal = BotPopGoal;
ai->BotEmptyGoalStack = BotEmptyGoalStack;
ai->BotDumpAvoidGoals = BotDumpAvoidGoals;
ai->BotDumpGoalStack = BotDumpGoalStack;
ai->BotGoalName = BotGoalName;
ai->BotGetTopGoal = BotGetTopGoal;
ai->BotGetSecondGoal = BotGetSecondGoal;
ai->BotChooseLTGItem = BotChooseLTGItem;
ai->BotChooseNBGItem = BotChooseNBGItem;
ai->BotTouchingGoal = BotTouchingGoal;
ai->BotItemGoalInVisButNotVisible = BotItemGoalInVisButNotVisible;
ai->BotGetLevelItemGoal = BotGetLevelItemGoal;
ai->BotGetNextCampSpotGoal = BotGetNextCampSpotGoal;
ai->BotGetMapLocationGoal = BotGetMapLocationGoal;
ai->BotAvoidGoalTime = BotAvoidGoalTime;
ai->BotInitLevelItems = BotInitLevelItems;
ai->BotUpdateEntityItems = BotUpdateEntityItems;
ai->BotLoadItemWeights = BotLoadItemWeights;
ai->BotFreeItemWeights = BotFreeItemWeights;
ai->BotInterbreedGoalFuzzyLogic = BotInterbreedGoalFuzzyLogic;
ai->BotSaveGoalFuzzyLogic = BotSaveGoalFuzzyLogic;
ai->BotMutateGoalFuzzyLogic = BotMutateGoalFuzzyLogic;
ai->BotAllocGoalState = BotAllocGoalState;
ai->BotFreeGoalState = BotFreeGoalState;
//-----------------------------------
// be_ai_move.h
//-----------------------------------
ai->BotResetMoveState = BotResetMoveState;
ai->BotMoveToGoal = BotMoveToGoal;
ai->BotMoveInDirection = BotMoveInDirection;
ai->BotResetAvoidReach = BotResetAvoidReach;
ai->BotResetLastAvoidReach = BotResetLastAvoidReach;
ai->BotReachabilityArea = BotReachabilityArea;
ai->BotMovementViewTarget = BotMovementViewTarget;
ai->BotPredictVisiblePosition = BotPredictVisiblePosition;
ai->BotAllocMoveState = BotAllocMoveState;
ai->BotFreeMoveState = BotFreeMoveState;
ai->BotInitMoveState = BotInitMoveState;
// Ridah
ai->BotInitAvoidReach = BotInitAvoidReach;
// done.
//-----------------------------------
// be_ai_weap.h
//-----------------------------------
ai->BotChooseBestFightWeapon = BotChooseBestFightWeapon;
ai->BotGetWeaponInfo = BotGetWeaponInfo;
ai->BotLoadWeaponWeights = BotLoadWeaponWeights;
ai->BotAllocWeaponState = BotAllocWeaponState;
ai->BotFreeWeaponState = BotFreeWeaponState;
ai->BotResetWeaponState = BotResetWeaponState;
//-----------------------------------
// be_ai_gen.h
//-----------------------------------
ai->GeneticParentsAndChildSelection = GeneticParentsAndChildSelection;
}
/*
============
GetBotLibAPI
============
*/
botlib_export_t *GetBotLibAPI( int apiVersion, botlib_import_t *import ) {
botimport = *import;
memset( &be_botlib_export, 0, sizeof( be_botlib_export ) );
if ( apiVersion != BOTLIB_API_VERSION ) {
botimport.Print( PRT_ERROR, "Mismatched BOTLIB_API_VERSION: expected %i, got %i\n", BOTLIB_API_VERSION, apiVersion );
return NULL;
}
Init_AAS_Export( &be_botlib_export.aas );
Init_EA_Export( &be_botlib_export.ea );
Init_AI_Export( &be_botlib_export.ai );
be_botlib_export.BotLibSetup = Export_BotLibSetup;
be_botlib_export.BotLibShutdown = Export_BotLibShutdown;
be_botlib_export.BotLibVarSet = Export_BotLibVarSet;
be_botlib_export.BotLibVarGet = Export_BotLibVarGet;
be_botlib_export.PC_AddGlobalDefine = PC_AddGlobalDefine;
be_botlib_export.PC_RemoveAllGlobalDefines = PC_RemoveAllGlobalDefines;
be_botlib_export.PC_LoadSourceHandle = PC_LoadSourceHandle;
be_botlib_export.PC_FreeSourceHandle = PC_FreeSourceHandle;
be_botlib_export.PC_ReadTokenHandle = PC_ReadTokenHandle;
be_botlib_export.PC_SourceFileAndLine = PC_SourceFileAndLine;
be_botlib_export.PC_UnreadLastTokenHandle = PC_UnreadLastTokenHandle;
be_botlib_export.BotLibStartFrame = Export_BotLibStartFrame;
be_botlib_export.BotLibLoadMap = Export_BotLibLoadMap;
be_botlib_export.BotLibUpdateEntity = Export_BotLibUpdateEntity;
be_botlib_export.Test = BotExportTest;
return &be_botlib_export;
}

94
src/botlib/be_interface.h Normal file
View File

@@ -0,0 +1,94 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: be_interface.h
*
* desc: botlib interface
*
*
*****************************************************************************/
/*
"Do not go where the path leads, rather go where there's no track and leave a trail."
"AAS (Area Awareness System)"
"Part of the Gladiator is BoGuS (Bot Guidance System)"
"ANSI (Advanced Navigational System Interface)"
"to make things work the only thing you really have to do is think things work."
"a madman is just someone living in another reality which isn't shared among many people"
*/
//#define DEBUG //debug code
#define RANDOMIZE //randomize bot behaviour
#if defined( WIN32 ) || defined( _WIN32 )
#define AASZIP //allow reading directly from aasX.zip files
#endif
#define QUAKE2 //bot for Quake2
//#define HALFLIFE //bot for Half-Life
//==========================================================
//
// global variable structures
//
//==========================================================
//FIXME: get rid of this global structure
typedef struct botlib_globals_s
{
int botlibsetup; //true when the bot library has been setup
int maxentities; //maximum number of entities
int maxclients; //maximum number of clients
float time; //the global time
//#ifdef DEBUG
qboolean debug; //true if debug is on
int goalareanum;
vec3_t goalorigin;
int runai;
qboolean lastsuccess;
//#endif
} botlib_globals_t;
//==========================================================
//
// global variables
//
//==========================================================
extern botlib_globals_t botlibglobals;
extern botlib_import_t botimport;
extern int bot_developer; //true if developer is on
//
int Sys_MilliSeconds( void );

444
src/botlib/botlib.vcproj Normal file
View File

@@ -0,0 +1,444 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Name="botlib"
ProjectGUID="{EFA65954-05A8-43C4-B4FE-FAFE8E678AB7}"
TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB,BOTLIB;_CRT_SECURE_NO_WARNINGS"
StringPooling="true"
RuntimeLibrary="0"
BufferSecurityCheck="false"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/botlib.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="4"
SuppressStartupBanner="true"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\Release\botlib.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="4"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32,_DEBUG,_LIB,BOTLIB,DEBUG;_CRT_SECURE_NO_WARNINGS"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/botlib.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="true"
DebugInformationFormat="4"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLibrarianTool"
OutputFile=".\Debug\botlib.lib"
SuppressStartupBanner="true"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
>
<File
RelativePath=".\be_aas_bspq3.c"
>
</File>
<File
RelativePath=".\be_aas_cluster.c"
>
</File>
<File
RelativePath=".\be_aas_debug.c"
>
</File>
<File
RelativePath=".\be_aas_entity.c"
>
</File>
<File
RelativePath=".\be_aas_file.c"
>
</File>
<File
RelativePath=".\be_aas_main.c"
>
</File>
<File
RelativePath=".\be_aas_move.c"
>
</File>
<File
RelativePath=".\be_aas_optimize.c"
>
</File>
<File
RelativePath=".\be_aas_reach.c"
>
</File>
<File
RelativePath=".\be_aas_route.c"
>
</File>
<File
RelativePath=".\be_aas_routealt.c"
>
</File>
<File
RelativePath=".\be_aas_routetable.c"
>
</File>
<File
RelativePath=".\be_aas_sample.c"
>
</File>
<File
RelativePath=".\be_ai_char.c"
>
</File>
<File
RelativePath=".\be_ai_chat.c"
>
</File>
<File
RelativePath=".\be_ai_gen.c"
>
</File>
<File
RelativePath=".\be_ai_goal.c"
>
</File>
<File
RelativePath=".\be_ai_move.c"
>
</File>
<File
RelativePath=".\be_ai_weap.c"
>
</File>
<File
RelativePath=".\be_ai_weight.c"
>
</File>
<File
RelativePath=".\be_ea.c"
>
</File>
<File
RelativePath=".\be_interface.c"
>
</File>
<File
RelativePath=".\l_crc.c"
>
</File>
<File
RelativePath=".\l_libvar.c"
>
</File>
<File
RelativePath=".\l_log.c"
>
</File>
<File
RelativePath=".\l_memory.c"
>
</File>
<File
RelativePath=".\l_precomp.c"
>
</File>
<File
RelativePath=".\l_script.c"
>
</File>
<File
RelativePath=".\l_struct.c"
>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl"
>
<File
RelativePath=".\aasfile.h"
>
</File>
<File
RelativePath="..\game\be_aas.h"
>
</File>
<File
RelativePath=".\be_aas_bsp.h"
>
</File>
<File
RelativePath=".\be_aas_cluster.h"
>
</File>
<File
RelativePath=".\be_aas_debug.h"
>
</File>
<File
RelativePath=".\be_aas_def.h"
>
</File>
<File
RelativePath=".\be_aas_entity.h"
>
</File>
<File
RelativePath=".\be_aas_file.h"
>
</File>
<File
RelativePath=".\be_aas_funcs.h"
>
</File>
<File
RelativePath=".\be_aas_main.h"
>
</File>
<File
RelativePath=".\be_aas_move.h"
>
</File>
<File
RelativePath=".\be_aas_optimize.h"
>
</File>
<File
RelativePath=".\be_aas_reach.h"
>
</File>
<File
RelativePath=".\be_aas_route.h"
>
</File>
<File
RelativePath=".\be_aas_routealt.h"
>
</File>
<File
RelativePath=".\be_aas_routetable.h"
>
</File>
<File
RelativePath=".\be_aas_sample.h"
>
</File>
<File
RelativePath="..\game\be_ai_char.h"
>
</File>
<File
RelativePath="..\game\be_ai_chat.h"
>
</File>
<File
RelativePath="..\game\be_ai_gen.h"
>
</File>
<File
RelativePath="..\game\be_ai_goal.h"
>
</File>
<File
RelativePath="..\game\be_ai_move.h"
>
</File>
<File
RelativePath="..\game\be_ai_weap.h"
>
</File>
<File
RelativePath=".\be_ai_weight.h"
>
</File>
<File
RelativePath="..\game\be_ea.h"
>
</File>
<File
RelativePath=".\be_interface.h"
>
</File>
<File
RelativePath="..\game\botlib.h"
>
</File>
<File
RelativePath=".\l_crc.h"
>
</File>
<File
RelativePath=".\l_libvar.h"
>
</File>
<File
RelativePath=".\l_log.h"
>
</File>
<File
RelativePath=".\l_memory.h"
>
</File>
<File
RelativePath=".\l_precomp.h"
>
</File>
<File
RelativePath=".\l_script.h"
>
</File>
<File
RelativePath=".\l_struct.h"
>
</File>
<File
RelativePath=".\l_utils.h"
>
</File>
<File
RelativePath="..\game\q_shared.h"
>
</File>
<File
RelativePath="..\game\surfaceflags.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

271
src/botlib/botlib_stub.c Normal file
View File

@@ -0,0 +1,271 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*
* $Id: botlib_stub.c,v 1.3 2004/01/31 04:03:49 ikkyo Exp $
*
* rain - this is a stub botlib so that we can compile without changes to
* the rest of the engine. This way, we can drop in the real botlib later
* if we get access to it.
*
* Notes:
* + The l_* files are pilfered from extractfuncs. They work, but
* I believe they're a bit out-of-date versus the real versions..
* + I don't yet return real handles for the PC functions--instead, I
* pass around the real pointer to the source_t struct. This is
* probably a bad thing, and it should be fixed down the road.
*/
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "l_script.h"
#include "l_precomp.h"
void botlib_stub( void );
int PC_LoadSourceHandle( const char * );
int PC_FreeSourceHandle( int );
int PC_ReadTokenHandle( int, pc_token_t * );
int PC_SourceFileAndLine( int, char *, int * );
void PC_UnreadLastTokenHandle( int );
botlib_import_t botimport;
botlib_export_t *GetBotLibAPI( int version, botlib_import_t *imports ) {
static botlib_export_t botlib_export;
botimport = *imports;
botlib_export.aas.AAS_EntityInfo = (void *)botlib_stub;
botlib_export.aas.AAS_Initialized = (void *)botlib_stub;
botlib_export.aas.AAS_PresenceTypeBoundingBox = (void *)botlib_stub;
botlib_export.aas.AAS_Time = (void *)botlib_stub;
botlib_export.aas.AAS_PointAreaNum = (void *)botlib_stub;
botlib_export.aas.AAS_TraceAreas = (void *)botlib_stub;
botlib_export.aas.AAS_BBoxAreas = (void *)botlib_stub;
botlib_export.aas.AAS_AreaCenter = (void *)botlib_stub;
botlib_export.aas.AAS_AreaWaypoint = (void *)botlib_stub;
botlib_export.aas.AAS_PointContents = (void *)botlib_stub;
botlib_export.aas.AAS_NextBSPEntity = (void *)botlib_stub;
botlib_export.aas.AAS_ValueForBSPEpairKey = (void *)botlib_stub;
botlib_export.aas.AAS_VectorForBSPEpairKey = (void *)botlib_stub;
botlib_export.aas.AAS_FloatForBSPEpairKey = (void *)botlib_stub;
botlib_export.aas.AAS_IntForBSPEpairKey = (void *)botlib_stub;
botlib_export.aas.AAS_AreaReachability = (void *)botlib_stub;
botlib_export.aas.AAS_AreaLadder = (void *)botlib_stub;
botlib_export.aas.AAS_AreaTravelTimeToGoalArea = (void *)botlib_stub;
botlib_export.aas.AAS_Swimming = (void *)botlib_stub;
botlib_export.aas.AAS_PredictClientMovement = (void *)botlib_stub;
botlib_export.aas.AAS_RT_ShowRoute = (void *)botlib_stub;
botlib_export.aas.AAS_RT_GetHidePos = (void *)botlib_stub;
botlib_export.aas.AAS_FindAttackSpotWithinRange = (void *)botlib_stub;
botlib_export.aas.AAS_ListAreasInRange = (void *)botlib_stub;
botlib_export.aas.AAS_AvoidDangerArea = (void *)botlib_stub;
botlib_export.aas.AAS_Retreat = (void *)botlib_stub;
botlib_export.aas.AAS_AlternativeRouteGoals = (void *)botlib_stub;
botlib_export.aas.AAS_SetAASBlockingEntity = (void *)botlib_stub;
botlib_export.aas.AAS_NearestHideArea = (void *)botlib_stub;
botlib_export.aas.AAS_RecordTeamDeathArea = (void *)botlib_stub;
botlib_export.aas.AAS_SetCurrentWorld = (void *)botlib_stub;
botlib_export.ea.EA_Say = (void *)botlib_stub;
botlib_export.ea.EA_SayTeam = (void *)botlib_stub;
botlib_export.ea.EA_UseItem = (void *)botlib_stub;
botlib_export.ea.EA_DropItem = (void *)botlib_stub;
botlib_export.ea.EA_UseInv = (void *)botlib_stub;
botlib_export.ea.EA_DropInv = (void *)botlib_stub;
botlib_export.ea.EA_Gesture = (void *)botlib_stub;
botlib_export.ea.EA_Command = (void *)botlib_stub;
botlib_export.ea.EA_SelectWeapon = (void *)botlib_stub;
botlib_export.ea.EA_Talk = (void *)botlib_stub;
botlib_export.ea.EA_Attack = (void *)botlib_stub;
botlib_export.ea.EA_Reload = (void *)botlib_stub;
botlib_export.ea.EA_Use = (void *)botlib_stub;
botlib_export.ea.EA_Respawn = (void *)botlib_stub;
botlib_export.ea.EA_Jump = (void *)botlib_stub;
botlib_export.ea.EA_DelayedJump = (void *)botlib_stub;
botlib_export.ea.EA_Crouch = (void *)botlib_stub;
botlib_export.ea.EA_Walk = (void *)botlib_stub;
botlib_export.ea.EA_MoveUp = (void *)botlib_stub;
botlib_export.ea.EA_MoveDown = (void *)botlib_stub;
botlib_export.ea.EA_MoveForward = (void *)botlib_stub;
botlib_export.ea.EA_MoveBack = (void *)botlib_stub;
botlib_export.ea.EA_MoveLeft = (void *)botlib_stub;
botlib_export.ea.EA_MoveRight = (void *)botlib_stub;
botlib_export.ea.EA_Move = (void *)botlib_stub;
botlib_export.ea.EA_View = (void *)botlib_stub;
botlib_export.ea.EA_Prone = (void *)botlib_stub;
botlib_export.ea.EA_EndRegular = (void *)botlib_stub;
botlib_export.ea.EA_GetInput = (void *)botlib_stub;
botlib_export.ea.EA_ResetInput = (void *)botlib_stub;
botlib_export.ai.BotLoadCharacter = (void *)botlib_stub;
botlib_export.ai.BotFreeCharacter = (void *)botlib_stub;
botlib_export.ai.Characteristic_Float = (void *)botlib_stub;
botlib_export.ai.Characteristic_BFloat = (void *)botlib_stub;
botlib_export.ai.Characteristic_Integer = (void *)botlib_stub;
botlib_export.ai.Characteristic_BInteger = (void *)botlib_stub;
botlib_export.ai.Characteristic_String = (void *)botlib_stub;
botlib_export.ai.BotAllocChatState = (void *)botlib_stub;
botlib_export.ai.BotFreeChatState = (void *)botlib_stub;
botlib_export.ai.BotQueueConsoleMessage = (void *)botlib_stub;
botlib_export.ai.BotRemoveConsoleMessage = (void *)botlib_stub;
botlib_export.ai.BotNextConsoleMessage = (void *)botlib_stub;
botlib_export.ai.BotNumConsoleMessages = (void *)botlib_stub;
botlib_export.ai.BotInitialChat = (void *)botlib_stub;
botlib_export.ai.BotNumInitialChats = (void *)botlib_stub;
botlib_export.ai.BotReplyChat = (void *)botlib_stub;
botlib_export.ai.BotChatLength = (void *)botlib_stub;
botlib_export.ai.BotEnterChat = (void *)botlib_stub;
botlib_export.ai.BotGetChatMessage = (void *)botlib_stub;
botlib_export.ai.StringContains = (void *)botlib_stub;
botlib_export.ai.BotFindMatch = (void *)botlib_stub;
botlib_export.ai.BotMatchVariable = (void *)botlib_stub;
botlib_export.ai.UnifyWhiteSpaces = (void *)botlib_stub;
botlib_export.ai.BotReplaceSynonyms = (void *)botlib_stub;
botlib_export.ai.BotLoadChatFile = (void *)botlib_stub;
botlib_export.ai.BotSetChatGender = (void *)botlib_stub;
botlib_export.ai.BotSetChatName = (void *)botlib_stub;
botlib_export.ai.BotResetGoalState = (void *)botlib_stub;
botlib_export.ai.BotResetAvoidGoals = (void *)botlib_stub;
botlib_export.ai.BotRemoveFromAvoidGoals = (void *)botlib_stub;
botlib_export.ai.BotPushGoal = (void *)botlib_stub;
botlib_export.ai.BotPopGoal = (void *)botlib_stub;
botlib_export.ai.BotEmptyGoalStack = (void *)botlib_stub;
botlib_export.ai.BotDumpAvoidGoals = (void *)botlib_stub;
botlib_export.ai.BotDumpGoalStack = (void *)botlib_stub;
botlib_export.ai.BotGoalName = (void *)botlib_stub;
botlib_export.ai.BotGetTopGoal = (void *)botlib_stub;
botlib_export.ai.BotGetSecondGoal = (void *)botlib_stub;
botlib_export.ai.BotChooseLTGItem = (void *)botlib_stub;
botlib_export.ai.BotChooseNBGItem = (void *)botlib_stub;
botlib_export.ai.BotTouchingGoal = (void *)botlib_stub;
botlib_export.ai.BotItemGoalInVisButNotVisible = (void *)botlib_stub;
botlib_export.ai.BotGetLevelItemGoal = (void *)botlib_stub;
botlib_export.ai.BotGetNextCampSpotGoal = (void *)botlib_stub;
botlib_export.ai.BotGetMapLocationGoal = (void *)botlib_stub;
botlib_export.ai.BotAvoidGoalTime = (void *)botlib_stub;
botlib_export.ai.BotInitLevelItems = (void *)botlib_stub;
botlib_export.ai.BotUpdateEntityItems = (void *)botlib_stub;
botlib_export.ai.BotLoadItemWeights = (void *)botlib_stub;
botlib_export.ai.BotFreeItemWeights = (void *)botlib_stub;
botlib_export.ai.BotInterbreedGoalFuzzyLogic = (void *)botlib_stub;
botlib_export.ai.BotSaveGoalFuzzyLogic = (void *)botlib_stub;
botlib_export.ai.BotMutateGoalFuzzyLogic = (void *)botlib_stub;
botlib_export.ai.BotAllocGoalState = (void *)botlib_stub;
botlib_export.ai.BotFreeGoalState = (void *)botlib_stub;
botlib_export.ai.BotResetMoveState = (void *)botlib_stub;
botlib_export.ai.BotMoveToGoal = (void *)botlib_stub;
botlib_export.ai.BotMoveInDirection = (void *)botlib_stub;
botlib_export.ai.BotResetAvoidReach = (void *)botlib_stub;
botlib_export.ai.BotResetLastAvoidReach = (void *)botlib_stub;
botlib_export.ai.BotReachabilityArea = (void *)botlib_stub;
botlib_export.ai.BotMovementViewTarget = (void *)botlib_stub;
botlib_export.ai.BotPredictVisiblePosition = (void *)botlib_stub;
botlib_export.ai.BotAllocMoveState = (void *)botlib_stub;
botlib_export.ai.BotFreeMoveState = (void *)botlib_stub;
botlib_export.ai.BotInitMoveState = (void *)botlib_stub;
botlib_export.ai.BotInitAvoidReach = (void *)botlib_stub;
botlib_export.ai.BotChooseBestFightWeapon = (void *)botlib_stub;
botlib_export.ai.BotGetWeaponInfo = (void *)botlib_stub;
botlib_export.ai.BotLoadWeaponWeights = (void *)botlib_stub;
botlib_export.ai.BotAllocWeaponState = (void *)botlib_stub;
botlib_export.ai.BotFreeWeaponState = (void *)botlib_stub;
botlib_export.ai.BotResetWeaponState = (void *)botlib_stub;
botlib_export.ai.GeneticParentsAndChildSelection = (void *)botlib_stub;
botlib_export.BotLibSetup = (void *)botlib_stub;
botlib_export.BotLibShutdown = (void *)botlib_stub;
botlib_export.BotLibVarSet = (void *)botlib_stub;
botlib_export.BotLibVarGet = (void *)botlib_stub;
botlib_export.BotLibStartFrame = (void *)botlib_stub;
botlib_export.BotLibLoadMap = (void *)botlib_stub;
botlib_export.BotLibUpdateEntity = (void *)botlib_stub;
botlib_export.Test = (void *)botlib_stub;
botlib_export.PC_AddGlobalDefine = PC_AddGlobalDefine;
botlib_export.PC_RemoveAllGlobalDefines = PC_RemoveAllGlobalDefines;
botlib_export.PC_LoadSourceHandle = PC_LoadSourceHandle;
botlib_export.PC_FreeSourceHandle = PC_FreeSourceHandle;
botlib_export.PC_ReadTokenHandle = PC_ReadTokenHandle;
botlib_export.PC_SourceFileAndLine = PC_SourceFileAndLine;
botlib_export.PC_UnreadLastTokenHandle = PC_UnreadLastTokenHandle;
return &botlib_export;
}
void botlib_stub( void ) {
botimport.Print( PRT_WARNING, "WARNING: botlib stub!\n" );
}
int PC_LoadSourceHandle( const char *filename ) {
// rain - FIXME - LoadSourceFile should take a const filename
return (int)LoadSourceFile( filename );
}
int PC_FreeSourceHandle( int handle ) {
FreeSource( (source_t *)handle );
return 0;
}
int PC_ReadTokenHandle( int handle, pc_token_t *token ) {
token_t t;
int ret;
ret = PC_ReadToken( (source_t *)handle, &t );
token->type = t.type;
token->subtype = t.subtype;
token->intvalue = t.intvalue;
token->floatvalue = t.floatvalue;
Q_strncpyz( token->string, t.string, MAX_TOKENLENGTH );
token->line = t.line;
token->linescrossed = t.linescrossed;
// gamecode doesn't want the quotes on the string
if ( token->type == TT_STRING ) {
StripDoubleQuotes( token->string );
}
return ret;
}
int PC_SourceFileAndLine( int handle, char *filename, int *line ) {
source_t *source = (source_t *)handle;
Q_strncpyz( filename, source->filename, 128 );
// ikkyo - i'm pretty sure token.line is the line of the last token
// parsed, not the line of the token currently being parsed...
*line = source->token.line;
return 0;
}
void PC_UnreadLastTokenHandle( int handle ) {
PC_UnreadLastToken( (source_t *)handle );
}

34
src/botlib/l_common.h Normal file
View File

@@ -0,0 +1,34 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#ifndef _L_COMMON_
#define _L_COMMON_
#error CVS REMOVE ME
#endif

155
src/botlib/l_crc.c Normal file
View File

@@ -0,0 +1,155 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_crc.c
*
* desc: CRC calculation
*
*
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "be_interface.h" //for botimport.Print
// FIXME: byte swap?
// this is a 16 bit, non-reflected CRC using the polynomial 0x1021
// and the initial and final xor values shown below... in other words, the
// CCITT standard CRC used by XMODEM
#define CRC_INIT_VALUE 0xffff
#define CRC_XOR_VALUE 0x0000
unsigned short crctable[257] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0,
0x0000 // code reaches element 256
};
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void CRC_Init( unsigned short *crcvalue ) {
*crcvalue = CRC_INIT_VALUE;
} //end of the function CRC_Init
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void CRC_ProcessByte( unsigned short *crcvalue, byte data ) {
*crcvalue = ( *crcvalue << 8 ) ^ crctable[( *crcvalue >> 8 ) ^ data];
} //end of the function CRC_ProcessByte
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
unsigned short CRC_Value( unsigned short crcvalue ) {
return crcvalue ^ CRC_XOR_VALUE;
} //end of the function CRC_Value
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
unsigned short CRC_ProcessString( unsigned char *data, int length ) {
unsigned short crcvalue;
int i, ind;
CRC_Init( &crcvalue );
for ( i = 0; i < length; i++ )
{
ind = ( crcvalue >> 8 ) ^ data[i];
if ( ind < 0 || ind > 256 ) {
ind = 0;
}
crcvalue = ( crcvalue << 8 ) ^ crctable[ind];
} //end for
return CRC_Value( crcvalue );
} //end of the function CRC_ProcessString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void CRC_ContinueProcessString( unsigned short *crc, char *data, int length ) {
int i;
for ( i = 0; i < length; i++ )
{
*crc = ( *crc << 8 ) ^ crctable[( *crc >> 8 ) ^ data[i]];
} //end for
} //end of the function CRC_ProcessString

44
src/botlib/l_crc.h Normal file
View File

@@ -0,0 +1,44 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: l_crc.h
// Function: for CRC checks
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
// Last update: 1997-12-31
// Tab Size: 3
//===========================================================================
typedef unsigned short crc_t;
void CRC_Init( unsigned short *crcvalue );
void CRC_ProcessByte( unsigned short *crcvalue, byte data );
unsigned short CRC_Value( unsigned short crcvalue );
unsigned short CRC_ProcessString( unsigned char *data, int length );
void CRC_ContinueProcessString( unsigned short *crc, char *data, int length );

282
src/botlib/l_libvar.c Normal file
View File

@@ -0,0 +1,282 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_libvar.c
*
* desc: bot library variables
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "l_memory.h"
#include "l_libvar.h"
//list with library variables
libvar_t *libvarlist;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarStringValue( char *string ) {
int dotfound = 0;
float value = 0;
while ( *string )
{
if ( *string < '0' || *string > '9' ) {
if ( dotfound || *string != '.' ) {
return 0;
} //end if
else
{
dotfound = 10;
string++;
} //end if
} //end if
if ( dotfound ) {
value = value + (float) ( *string - '0' ) / (float) dotfound;
dotfound *= 10;
} //end if
else
{
value = value * 10.0 + (float) ( *string - '0' );
} //end else
string++;
} //end while
return value;
} //end of the function LibVarStringValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVarAlloc( char *var_name ) {
libvar_t *v;
v = (libvar_t *) GetMemory( sizeof( libvar_t ) + strlen( var_name ) + 1 );
memset( v, 0, sizeof( libvar_t ) );
v->name = (char *) v + sizeof( libvar_t );
strcpy( v->name, var_name );
//add the variable in the list
v->next = libvarlist;
libvarlist = v;
return v;
} //end of the function LibVarAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarDeAlloc( libvar_t *v ) {
if ( v->string ) {
FreeMemory( v->string );
}
FreeMemory( v );
} //end of the function LibVarDeAlloc
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarDeAllocAll( void ) {
libvar_t *v;
for ( v = libvarlist; v; v = libvarlist )
{
libvarlist = libvarlist->next;
LibVarDeAlloc( v );
} //end for
libvarlist = NULL;
} //end of the function LibVarDeAllocAll
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVarGet( char *var_name ) {
libvar_t *v;
for ( v = libvarlist; v; v = v->next )
{
if ( !Q_stricmp( v->name, var_name ) ) {
return v;
} //end if
} //end for
return NULL;
} //end of the function LibVarGet
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *LibVarGetString( char *var_name ) {
libvar_t *v;
v = LibVarGet( var_name );
if ( v ) {
return v->string;
} //end if
else
{
return "";
} //end else
} //end of the function LibVarGetString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarGetValue( char *var_name ) {
libvar_t *v;
v = LibVarGet( var_name );
if ( v ) {
return v->value;
} //end if
else
{
return 0;
} //end else
} //end of the function LibVarGetValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
libvar_t *LibVar( char *var_name, char *value ) {
libvar_t *v;
v = LibVarGet( var_name );
if ( v ) {
return v;
}
//create new variable
v = LibVarAlloc( var_name );
//variable string
v->string = (char *) GetMemory( strlen( value ) + 1 );
strcpy( v->string, value );
//the value
v->value = LibVarStringValue( v->string );
//variable is modified
v->modified = qtrue;
//
return v;
} //end of the function LibVar
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char *LibVarString( char *var_name, char *value ) {
libvar_t *v;
v = LibVar( var_name, value );
return v->string;
} //end of the function LibVarString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
float LibVarValue( char *var_name, char *value ) {
libvar_t *v;
v = LibVar( var_name, value );
return v->value;
} //end of the function LibVarValue
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarSet( char *var_name, char *value ) {
libvar_t *v;
v = LibVarGet( var_name );
if ( v ) {
FreeMemory( v->string );
} //end if
else
{
v = LibVarAlloc( var_name );
} //end else
//variable string
v->string = (char *) GetMemory( strlen( value ) + 1 );
strcpy( v->string, value );
//the value
v->value = LibVarStringValue( v->string );
//variable is modified
v->modified = qtrue;
} //end of the function LibVarSet
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean LibVarChanged( char *var_name ) {
libvar_t *v;
v = LibVarGet( var_name );
if ( v ) {
return v->modified;
} //end if
else
{
return qfalse;
} //end else
} //end of the function LibVarChanged
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LibVarSetNotModified( char *var_name ) {
libvar_t *v;
v = LibVarGet( var_name );
if ( v ) {
v->modified = qfalse;
} //end if
} //end of the function LibVarSetNotModified

69
src/botlib/l_libvar.h Normal file
View File

@@ -0,0 +1,69 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_libvar.h
*
* desc: botlib vars
*
*
*****************************************************************************/
//library variable
typedef struct libvar_s
{
char *name;
char *string;
int flags;
qboolean modified; // set each time the cvar is changed
float value;
struct libvar_s *next;
} libvar_t;
//removes all library variables
void LibVarDeAllocAll( void );
//gets the library variable with the given name
libvar_t *LibVarGet( char *var_name );
//gets the string of the library variable with the given name
char *LibVarGetString( char *var_name );
//gets the value of the library variable with the given name
float LibVarGetValue( char *var_name );
//creates the library variable if not existing already and returns it
libvar_t *LibVar( char *var_name, char *value );
//creates the library variable if not existing already and returns the value
float LibVarValue( char *var_name, char *value );
//creates the library variable if not existing already and returns the value string
char *LibVarString( char *var_name, char *value );
//sets the library variable
void LibVarSet( char *var_name, char *value );
//returns true if the library variable has been modified
qboolean LibVarChanged( char *var_name );
//sets the library variable to unmodified
void LibVarSetNotModified( char *var_name );

186
src/botlib/l_log.c Normal file
View File

@@ -0,0 +1,186 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_log.c
*
* desc: log file
*
*
*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "be_interface.h" //for botimport.Print
#include "l_libvar.h"
#define MAX_LOGFILENAMESIZE 1024
typedef struct logfile_s
{
char filename[MAX_LOGFILENAMESIZE];
FILE *fp;
int numwrites;
} logfile_t;
static logfile_t logfile;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_AlwaysOpen( char *filename ) {
if ( !filename || !strlen( filename ) ) {
botimport.Print( PRT_MESSAGE, "openlog <filename>\n" );
return;
} //end if
if ( logfile.fp ) {
botimport.Print( PRT_ERROR, "log file %s is already opened\n", logfile.filename );
return;
} //end if
logfile.fp = fopen( filename, "wb" );
if ( !logfile.fp ) {
botimport.Print( PRT_ERROR, "can't open the log file %s\n", filename );
return;
} //end if
strncpy( logfile.filename, filename, MAX_LOGFILENAMESIZE );
botimport.Print( PRT_MESSAGE, "Opened log %s\n", logfile.filename );
} //end of the function Log_Create
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Open( char *filename ) {
if ( !LibVarValue( "log", "0" ) ) {
return;
}
Log_AlwaysOpen( filename );
}
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Close( void ) {
if ( !logfile.fp ) {
return;
}
if ( fclose( logfile.fp ) ) {
botimport.Print( PRT_ERROR, "can't close log file %s\n", logfile.filename );
return;
} //end if
logfile.fp = NULL;
botimport.Print( PRT_MESSAGE, "Closed log %s\n", logfile.filename );
} //end of the function Log_Close
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Shutdown( void ) {
if ( logfile.fp ) {
Log_Close();
}
} //end of the function Log_Shutdown
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void QDECL Log_Write( char *fmt, ... ) {
va_list ap;
if ( !logfile.fp ) {
return;
}
va_start( ap, fmt );
vfprintf( logfile.fp, fmt, ap );
va_end( ap );
//fprintf(logfile.fp, "\r\n");
fflush( logfile.fp );
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void QDECL Log_WriteTimeStamped( char *fmt, ... ) {
va_list ap;
if ( !logfile.fp ) {
return;
}
fprintf( logfile.fp, "%d %02d:%02d:%02d:%02d ",
logfile.numwrites,
(int) ( botlibglobals.time / 60 / 60 ),
(int) ( botlibglobals.time / 60 ),
(int) ( botlibglobals.time ),
(int) ( (int) ( botlibglobals.time * 100 ) ) -
( (int) botlibglobals.time ) * 100 );
va_start( ap, fmt );
vfprintf( logfile.fp, fmt, ap );
va_end( ap );
fprintf( logfile.fp, "\r\n" );
logfile.numwrites++;
fflush( logfile.fp );
} //end of the function Log_Write
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
FILE *Log_FilePointer( void ) {
return logfile.fp;
} //end of the function Log_FilePointer
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void Log_Flush( void ) {
if ( logfile.fp ) {
fflush( logfile.fp );
}
} //end of the function Log_Flush

54
src/botlib/l_log.h Normal file
View File

@@ -0,0 +1,54 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_log.h
*
* desc: log file
*
*
*****************************************************************************/
//open a log file
void Log_Open( char *filename );
//
void Log_AlwaysOpen( char *filename );
//close the current log file
void Log_Close( void );
//close log file if present
void Log_Shutdown( void );
//write to the current opened log file
void QDECL Log_Write( char *fmt, ... );
//write to the current opened log file with a time stamp
void QDECL Log_WriteTimeStamped( char *fmt, ... );
//returns a pointer to the log file
FILE *Log_FilePointer( void );
//flush log file
void Log_Flush( void );

446
src/botlib/l_memory.c Normal file
View File

@@ -0,0 +1,446 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_memory.c
*
* desc: memory allocation
*
*
*****************************************************************************/
#include "../game/q_shared.h"
#include "../game/botlib.h"
#include "l_log.h"
#include "be_interface.h"
#ifdef _DEBUG
// #define MEMDEBUG
#define MEMORYMANEGER
#endif
#define MEM_ID 0x12345678l
#define HUNK_ID 0x87654321l
int allocatedmemory;
int totalmemorysize;
int numblocks;
#ifdef MEMORYMANEGER
typedef struct memoryblock_s
{
unsigned long int id;
void *ptr;
int size;
#ifdef MEMDEBUG
char *label;
char *file;
int line;
#endif //MEMDEBUG
struct memoryblock_s *prev, *next;
} memoryblock_t;
memoryblock_t *memory;
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void LinkMemoryBlock( memoryblock_t *block ) {
block->prev = NULL;
block->next = memory;
if ( memory ) {
memory->prev = block;
}
memory = block;
} //end of the function LinkMemoryBlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void UnlinkMemoryBlock( memoryblock_t *block ) {
if ( block->prev ) {
block->prev->next = block->next;
} else { memory = block->next;}
if ( block->next ) {
block->next->prev = block->prev;
}
} //end of the function UnlinkMemoryBlock
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
memoryblock_t *block;
ptr = botimport.GetMemory( size + sizeof( memoryblock_t ) );
block = (memoryblock_t *) ptr;
block->id = MEM_ID;
block->ptr = (char *) ptr + sizeof( memoryblock_t );
block->size = size + sizeof( memoryblock_t );
#ifdef MEMDEBUG
block->label = label;
block->file = file;
block->line = line;
#endif //MEMDEBUG
LinkMemoryBlock( block );
allocatedmemory += block->size;
totalmemorysize += block->size + sizeof( memoryblock_t );
numblocks++;
return block->ptr;
} //end of the function GetMemoryDebug
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetClearedMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetMemoryDebug( size, label, file, line );
#else
ptr = GetMemory( size );
#endif //MEMDEBUG
memset( ptr, 0, size );
return ptr;
} //end of the function GetClearedMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetHunkMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
memoryblock_t *block;
ptr = botimport.HunkAlloc( size + sizeof( memoryblock_t ) );
block = (memoryblock_t *) ptr;
block->id = HUNK_ID;
block->ptr = (char *) ptr + sizeof( memoryblock_t );
block->size = size + sizeof( memoryblock_t );
#ifdef MEMDEBUG
block->label = label;
block->file = file;
block->line = line;
#endif //MEMDEBUG
LinkMemoryBlock( block );
allocatedmemory += block->size;
totalmemorysize += block->size + sizeof( memoryblock_t );
numblocks++;
return block->ptr;
} //end of the function GetHunkMemoryDebug
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetClearedHunkMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetHunkMemoryDebug( size, label, file, line );
#else
ptr = GetHunkMemory( size );
#endif //MEMDEBUG
memset( ptr, 0, size );
return ptr;
} //end of the function GetClearedHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
memoryblock_t *BlockFromPointer( void *ptr, char *str ) {
memoryblock_t *block;
if ( !ptr ) {
#ifdef MEMDEBUG
//char *crash = (char *) NULL;
//crash[0] = 1;
botimport.Print( PRT_FATAL, "%s: NULL pointer\n", str );
#endif // MEMDEBUG
return NULL;
} //end if
block = ( memoryblock_t * )( (char *) ptr - sizeof( memoryblock_t ) );
if ( block->id != MEM_ID && block->id != HUNK_ID ) {
botimport.Print( PRT_FATAL, "%s: invalid memory block\n", str );
return NULL;
} //end if
if ( block->ptr != ptr ) {
botimport.Print( PRT_FATAL, "%s: memory block pointer invalid\n", str );
return NULL;
} //end if
return block;
} //end of the function BlockFromPointer
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeMemory( void *ptr ) {
memoryblock_t *block;
block = BlockFromPointer( ptr, "FreeMemory" );
if ( !block ) {
return;
}
UnlinkMemoryBlock( block );
allocatedmemory -= block->size;
totalmemorysize -= block->size + sizeof( memoryblock_t );
numblocks--;
//
if ( block->id == MEM_ID ) {
botimport.FreeMemory( block );
} //end if
} //end of the function FreeMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int MemoryByteSize( void *ptr ) {
memoryblock_t *block;
block = BlockFromPointer( ptr, "MemoryByteSize" );
if ( !block ) {
return 0;
}
return block->size;
} //end of the function MemoryByteSize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintUsedMemorySize( void ) {
botimport.Print( PRT_MESSAGE, "total allocated memory: %d KB\n", allocatedmemory >> 10 );
botimport.Print( PRT_MESSAGE, "total botlib memory: %d KB\n", totalmemorysize >> 10 );
botimport.Print( PRT_MESSAGE, "total memory blocks: %d\n", numblocks );
} //end of the function PrintUsedMemorySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintMemoryLabels( void ) {
memoryblock_t *block;
int i;
PrintUsedMemorySize();
i = 0;
Log_Write( "\r\n" );
for ( block = memory; block; block = block->next )
{
#ifdef MEMDEBUG
if ( block->id == HUNK_ID ) {
Log_Write( "%6d, hunk %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label );
} //end if
else
{
Log_Write( "%6d, %p, %8d: %24s line %6d: %s\r\n", i, block->ptr, block->size, block->file, block->line, block->label );
} //end else
#endif //MEMDEBUG
i++;
} //end for
} //end of the function PrintMemoryLabels
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void DumpMemory( void ) {
memoryblock_t *block;
for ( block = memory; block; block = memory )
{
FreeMemory( block->ptr );
} //end for
totalmemorysize = 0;
allocatedmemory = 0;
} //end of the function DumpMemory
#else
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
unsigned long int *memid;
ptr = botimport.GetMemory( size + sizeof( unsigned long int ) );
if ( !ptr ) {
return NULL;
}
memid = (unsigned long int *) ptr;
*memid = MEM_ID;
return (unsigned long int *) ( (char *) ptr + sizeof( unsigned long int ) );
} //end of the function GetMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetClearedMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetMemoryDebug( size, label, file, line );
#else
ptr = GetMemory( size );
#endif //MEMDEBUG
memset( ptr, 0, size );
return ptr;
} //end of the function GetClearedMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetHunkMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
unsigned long int *memid;
ptr = botimport.HunkAlloc( size + sizeof( unsigned long int ) );
if ( !ptr ) {
return NULL;
}
memid = (unsigned long int *) ptr;
*memid = HUNK_ID;
return (unsigned long int *) ( (char *) ptr + sizeof( unsigned long int ) );
} //end of the function GetHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
#ifdef MEMDEBUG
void *GetClearedHunkMemoryDebug( unsigned long size, char *label, char *file, int line )
#else
void *GetClearedHunkMemory( unsigned long size )
#endif //MEMDEBUG
{
void *ptr;
#ifdef MEMDEBUG
ptr = GetHunkMemoryDebug( size, label, file, line );
#else
ptr = GetHunkMemory( size );
#endif //MEMDEBUG
memset( ptr, 0, size );
return ptr;
} //end of the function GetClearedHunkMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void FreeMemory( void *ptr ) {
unsigned long int *memid;
memid = (unsigned long int *) ( (char *) ptr - sizeof( unsigned long int ) );
if ( *memid == MEM_ID ) {
botimport.FreeMemory( memid );
} //end if
} //end of the function FreeMemory
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintUsedMemorySize( void ) {
} //end of the function PrintUsedMemorySize
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void PrintMemoryLabels( void ) {
} //end of the function PrintMemoryLabels
#endif

82
src/botlib/l_memory.h Normal file
View File

@@ -0,0 +1,82 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_memory.h
*
* desc: memory management
*
*
*****************************************************************************/
#ifdef _DEBUG
// #define MEMDEBUG
#endif
#ifdef MEMDEBUG
#define GetMemory( size ) GetMemoryDebug( size, # size, __FILE__, __LINE__ );
#define GetClearedMemory( size ) GetClearedMemoryDebug( size, # size, __FILE__, __LINE__ );
//allocate a memory block of the given size
void *GetMemoryDebug( unsigned long size, char *label, char *file, int line );
//allocate a memory block of the given size and clear it
void *GetClearedMemoryDebug( unsigned long size, char *label, char *file, int line );
//
#define GetHunkMemory( size ) GetHunkMemoryDebug( size, # size, __FILE__, __LINE__ );
#define GetClearedHunkMemory( size ) GetClearedHunkMemoryDebug( size, # size, __FILE__, __LINE__ );
//allocate a memory block of the given size
void *GetHunkMemoryDebug( unsigned long size, char *label, char *file, int line );
//allocate a memory block of the given size and clear it
void *GetClearedHunkMemoryDebug( unsigned long size, char *label, char *file, int line );
#else
//allocate a memory block of the given size
void *GetMemory( unsigned long size );
//allocate a memory block of the given size and clear it
void *GetClearedMemory( unsigned long size );
//
#ifdef BSPC
#define GetHunkMemory GetMemory
#define GetClearedHunkMemory GetClearedMemory
#else
//allocate a memory block of the given size
void *GetHunkMemory( unsigned long size );
//allocate a memory block of the given size and clear it
void *GetClearedHunkMemory( unsigned long size );
#endif
#endif
//free the given memory block
void FreeMemory( void *ptr );
//prints the total used memory size
void PrintUsedMemorySize( void );
//print all memory blocks with label
void PrintMemoryLabels( void );
//returns the size of the memory block in bytes
int MemoryByteSize( void *ptr );
//free all allocated memory
void DumpMemory( void );

3262
src/botlib/l_precomp.c Normal file

File diff suppressed because it is too large Load Diff

167
src/botlib/l_precomp.h Normal file
View File

@@ -0,0 +1,167 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_precomp.h
*
* desc: pre compiler
*
*
*****************************************************************************/
#ifndef _MAX_PATH
#define MAX_PATH MAX_QPATH
#endif
#ifndef PATH_SEPERATORSTR
#if defined( WIN32 ) | defined( _WIN32 ) | defined( __NT__ ) | defined( __WINDOWS__ ) | defined( __WINDOWS_386__ )
#define PATHSEPERATOR_STR "\\"
#else
#define PATHSEPERATOR_STR "/"
#endif
#endif
#ifndef PATH_SEPERATORCHAR
#if defined( WIN32 ) | defined( _WIN32 ) | defined( __NT__ ) | defined( __WINDOWS__ ) | defined( __WINDOWS_386__ )
#define PATHSEPERATOR_CHAR '\\'
#else
#define PATHSEPERATOR_CHAR '/'
#endif
#endif
#define DEFINE_FIXED 0x0001
#define BUILTIN_LINE 1
#define BUILTIN_FILE 2
#define BUILTIN_DATE 3
#define BUILTIN_TIME 4
#define BUILTIN_STDC 5
#define INDENT_IF 0x0001
#define INDENT_ELSE 0x0002
#define INDENT_ELIF 0x0004
#define INDENT_IFDEF 0x0008
#define INDENT_IFNDEF 0x0010
//macro definitions
typedef struct define_s
{
char *name; //define name
int flags; //define flags
int builtin; // > 0 if builtin define
int numparms; //number of define parameters
token_t *parms; //define parameters
token_t *tokens; //macro tokens (possibly containing parm tokens)
struct define_s *next; //next defined macro in a list
struct define_s *hashnext; //next define in the hash chain
} define_t;
//indents
//used for conditional compilation directives:
//#if, #else, #elif, #ifdef, #ifndef
typedef struct indent_s
{
int type; //indent type
int skip; //true if skipping current indent
script_t *script; //script the indent was in
struct indent_s *next; //next indent on the indent stack
} indent_t;
//source file
typedef struct source_s
{
char filename[_MAX_PATH]; //file name of the script
char includepath[_MAX_PATH]; //path to include files
punctuation_t *punctuations; //punctuations to use
script_t *scriptstack; //stack with scripts of the source
token_t *tokens; //tokens to read first
define_t *defines; //list with macro definitions
define_t **definehash; //hash chain with defines
indent_t *indentstack; //stack with indents
int skip; // > 0 if skipping conditional code
token_t token; //last read token
} source_t;
//read a token from the source
int PC_ReadToken( source_t *source, token_t *token );
//expect a certain token
int PC_ExpectTokenString( source_t *source, char *string );
//expect a certain token type
int PC_ExpectTokenType( source_t *source, int type, int subtype, token_t *token );
//expect a token
int PC_ExpectAnyToken( source_t *source, token_t *token );
//returns true when the token is available
int PC_CheckTokenString( source_t *source, char *string );
//returns true an reads the token when a token with the given type is available
int PC_CheckTokenType( source_t *source, int type, int subtype, token_t *token );
//skip tokens until the given token string is read
int PC_SkipUntilString( source_t *source, char *string );
//unread the last token read from the script
void PC_UnreadLastToken( source_t *source );
//unread the given token
void PC_UnreadToken( source_t *source, token_t *token );
//read a token only if on the same line, lines are concatenated with a slash
int PC_ReadLine( source_t *source, token_t *token );
//returns true if there was a white space in front of the token
int PC_WhiteSpaceBeforeToken( token_t *token );
//add a define to the source
int PC_AddDefine( source_t *source, char *string );
//add a globals define that will be added to all opened sources
int PC_AddGlobalDefine( char *string );
//remove the given global define
int PC_RemoveGlobalDefine( char *name );
//remove all globals defines
void PC_RemoveAllGlobalDefines( void );
//add builtin defines
void PC_AddBuiltinDefines( source_t *source );
//set the source include path
void PC_SetIncludePath( source_t *source, char *path );
//set the punction set
void PC_SetPunctuations( source_t *source, punctuation_t *p );
//set the base folder to load files from
void PC_SetBaseFolder( char *path );
//load a source file
source_t *LoadSourceFile( const char *filename );
//load a source from memory
source_t *LoadSourceMemory( char *ptr, int length, char *name );
//free the given source
void FreeSource( source_t *source );
//print a source error
void QDECL SourceError( source_t *source, char *str, ... );
//print a source warning
void QDECL SourceWarning( source_t *source, char *str, ... );
//
int PC_LoadSourceHandle( const char *filename );
int PC_FreeSourceHandle( int handle );
int PC_ReadTokenHandle( int handle, struct pc_token_s *pc_token );
int PC_SourceFileAndLine( int handle, char *filename, int *line );
void PC_CheckOpenSourceHandles( void );
void PC_UnreadLastTokenHandle( int handle );

1444
src/botlib/l_script.c Normal file

File diff suppressed because it is too large Load Diff

268
src/botlib/l_script.h Normal file
View File

@@ -0,0 +1,268 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_script.h
*
* desc: lexicographical parser
*
*
*****************************************************************************/
// Ridah, can't get it to compile without this
#ifndef QDECL
// for windows fastcall option
#define QDECL
//======================= WIN32 DEFINES =================================
#ifdef WIN32
#undef QDECL
#define QDECL __cdecl
#endif
#endif
// done.
//undef if binary numbers of the form 0b... or 0B... are not allowed
#define BINARYNUMBERS
//undef if not using the token.intvalue and token.floatvalue
#define NUMBERVALUE
//use dollar sign also as punctuation
#define DOLLAR
//maximum token length
#define MAX_TOKEN 1024
//maximum path length
#ifndef _MAX_PATH
// TTimo: used to be MAX_QPATH, which is the game filesystem max len, and not the OS max len
#define _MAX_PATH 1024
#endif
//script flags
#define SCFL_NOERRORS 0x0001
#define SCFL_NOWARNINGS 0x0002
#define SCFL_NOSTRINGWHITESPACES 0x0004
#define SCFL_NOSTRINGESCAPECHARS 0x0008
#define SCFL_PRIMITIVE 0x0010
#define SCFL_NOBINARYNUMBERS 0x0020
#define SCFL_NONUMBERVALUES 0x0040
//token types
#define TT_STRING 1 // string
#define TT_LITERAL 2 // literal
#define TT_NUMBER 3 // number
#define TT_NAME 4 // name
#define TT_PUNCTUATION 5 // punctuation
//string sub type
//---------------
// the length of the string
//literal sub type
//----------------
// the ASCII code of the literal
//number sub type
//---------------
#define TT_DECIMAL 0x0008 // decimal number
#define TT_HEX 0x0100 // hexadecimal number
#define TT_OCTAL 0x0200 // octal number
#ifdef BINARYNUMBERS
#define TT_BINARY 0x0400 // binary number
#endif //BINARYNUMBERS
#define TT_FLOAT 0x0800 // floating point number
#define TT_INTEGER 0x1000 // integer number
#define TT_LONG 0x2000 // long number
#define TT_UNSIGNED 0x4000 // unsigned number
//punctuation sub type
//--------------------
#define P_RSHIFT_ASSIGN 1
#define P_LSHIFT_ASSIGN 2
#define P_PARMS 3
#define P_PRECOMPMERGE 4
#define P_LOGIC_AND 5
#define P_LOGIC_OR 6
#define P_LOGIC_GEQ 7
#define P_LOGIC_LEQ 8
#define P_LOGIC_EQ 9
#define P_LOGIC_UNEQ 10
#define P_MUL_ASSIGN 11
#define P_DIV_ASSIGN 12
#define P_MOD_ASSIGN 13
#define P_ADD_ASSIGN 14
#define P_SUB_ASSIGN 15
#define P_INC 16
#define P_DEC 17
#define P_BIN_AND_ASSIGN 18
#define P_BIN_OR_ASSIGN 19
#define P_BIN_XOR_ASSIGN 20
#define P_RSHIFT 21
#define P_LSHIFT 22
#define P_POINTERREF 23
#define P_CPP1 24
#define P_CPP2 25
#define P_MUL 26
#define P_DIV 27
#define P_MOD 28
#define P_ADD 29
#define P_SUB 30
#define P_ASSIGN 31
#define P_BIN_AND 32
#define P_BIN_OR 33
#define P_BIN_XOR 34
#define P_BIN_NOT 35
#define P_LOGIC_NOT 36
#define P_LOGIC_GREATER 37
#define P_LOGIC_LESS 38
#define P_REF 39
#define P_COMMA 40
#define P_SEMICOLON 41
#define P_COLON 42
#define P_QUESTIONMARK 43
#define P_PARENTHESESOPEN 44
#define P_PARENTHESESCLOSE 45
#define P_BRACEOPEN 46
#define P_BRACECLOSE 47
#define P_SQBRACKETOPEN 48
#define P_SQBRACKETCLOSE 49
#define P_BACKSLASH 50
#define P_PRECOMP 51
#define P_DOLLAR 52
//name sub type
//-------------
// the length of the name
//punctuation
typedef struct punctuation_s
{
char *p; //punctuation character(s)
int n; //punctuation indication
struct punctuation_s *next; //next punctuation
} punctuation_t;
//token
typedef struct token_s
{
char string[MAX_TOKEN]; //available token
int type; //last read token type
int subtype; //last read token sub type
#ifdef NUMBERVALUE
unsigned long int intvalue; //integer value
long double floatvalue; //floating point value
#endif //NUMBERVALUE
char *whitespace_p; //start of white space before token
char *endwhitespace_p; //start of white space before token
int line; //line the token was on
int linescrossed; //lines crossed in white space
struct token_s *next; //next token in chain
} token_t;
//script file
typedef struct script_s
{
char filename[_MAX_PATH]; //file name of the script
char *buffer; //buffer containing the script
char *script_p; //current pointer in the script
char *end_p; //pointer to the end of the script
char *lastscript_p; //script pointer before reading token
char *whitespace_p; //begin of the white space
char *endwhitespace_p; //end of the white space
int length; //length of the script in bytes
int line; //current line in script
int lastline; //line before reading token
int tokenavailable; //set by UnreadLastToken
int flags; //several script flags
punctuation_t *punctuations; //the punctuations used in the script
punctuation_t **punctuationtable;
token_t token; //available token
struct script_s *next; //next script in a chain
} script_t;
//read a token from the script
int PS_ReadToken( script_t *script, token_t *token );
//expect a certain token
int PS_ExpectTokenString( script_t *script, char *string );
//expect a certain token type
int PS_ExpectTokenType( script_t *script, int type, int subtype, token_t *token );
//expect a token
int PS_ExpectAnyToken( script_t *script, token_t *token );
//returns true when the token is available
int PS_CheckTokenString( script_t *script, char *string );
//returns true an reads the token when a token with the given type is available
int PS_CheckTokenType( script_t *script, int type, int subtype, token_t *token );
//skip tokens until the given token string is read
int PS_SkipUntilString( script_t *script, char *string );
//unread the last token read from the script
void PS_UnreadLastToken( script_t *script );
//unread the given token
void PS_UnreadToken( script_t *script, token_t *token );
//returns the next character of the read white space, returns NULL if none
char PS_NextWhiteSpaceChar( script_t *script );
//remove any leading and trailing double quotes from the token
void StripDoubleQuotes( char *string );
//remove any leading and trailing single quotes from the token
void StripSingleQuotes( char *string );
//read a possible signed integer
signed long int ReadSignedInt( script_t *script );
//read a possible signed floating point number
long double ReadSignedFloat( script_t *script );
//set an array with punctuations, NULL restores default C/C++ set
void SetScriptPunctuations( script_t *script, punctuation_t *p );
//set script flags
void SetScriptFlags( script_t *script, int flags );
//get script flags
int GetScriptFlags( script_t *script );
//reset a script
void ResetScript( script_t *script );
//returns true if at the end of the script
int EndOfScript( script_t *script );
//returns a pointer to the punctuation with the given number
char *PunctuationFromNum( script_t *script, int num );
//load a script from the given file at the given offset with the given length
script_t *LoadScriptFile( const char *filename );
//load a script from the given memory with the given length
script_t *LoadScriptMemory( char *ptr, int length, char *name );
//free a script
void FreeScript( script_t *script );
//set the base folder to load files from
void PS_SetBaseFolder( char *path );
//print a script error with filename and line number
void QDECL ScriptError( script_t *script, char *str, ... );
//print a script warning with filename and line number
void QDECL ScriptWarning( script_t *script, char *str, ... );

507
src/botlib/l_struct.c Normal file
View File

@@ -0,0 +1,507 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_struct.c
*
* desc: structure reading / writing
*
*
*****************************************************************************/
#ifdef BOTLIB
#include "../game/q_shared.h"
#include "../game/botlib.h" //for the include of be_interface.h
#include "l_script.h"
#include "l_precomp.h"
#include "l_struct.h"
#include "l_utils.h"
#include "be_interface.h"
#endif //BOTLIB
#ifdef BSPC
//include files for usage in the BSP Converter
#include "../bspc/qbsp.h"
#include "../bspc/l_log.h"
#include "../bspc/l_mem.h"
#include "l_precomp.h"
#include "l_struct.h"
#define qtrue true
#define qfalse false
#endif //BSPC
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
fielddef_t *FindField( fielddef_t *defs, char *name ) {
int i;
for ( i = 0; defs[i].name; i++ )
{
if ( !strcmp( defs[i].name, name ) ) {
return &defs[i];
}
} //end for
return NULL;
} //end of the function FindField
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean ReadNumber( source_t *source, fielddef_t *fd, void *p ) {
token_t token;
int negative = qfalse;
long int intval, intmin = 0, intmax = 0;
double floatval;
if ( !PC_ExpectAnyToken( source, &token ) ) {
return 0;
}
//check for minus sign
if ( token.type == TT_PUNCTUATION ) {
if ( fd->type & FT_UNSIGNED ) {
SourceError( source, "expected unsigned value, found %s", token.string );
return 0;
} //end if
//if not a minus sign
if ( strcmp( token.string, "-" ) ) {
SourceError( source, "unexpected punctuation %s", token.string );
return 0;
} //end if
negative = qtrue;
//read the number
if ( !PC_ExpectAnyToken( source, &token ) ) {
return 0;
}
} //end if
//check if it is a number
if ( token.type != TT_NUMBER ) {
SourceError( source, "expected number, found %s", token.string );
return 0;
} //end if
//check for a float value
if ( token.subtype & TT_FLOAT ) {
if ( ( fd->type & FT_TYPE ) != FT_FLOAT ) {
SourceError( source, "unexpected float" );
return 0;
} //end if
floatval = token.floatvalue;
if ( negative ) {
floatval = -floatval;
}
if ( fd->type & FT_BOUNDED ) {
if ( floatval < fd->floatmin || floatval > fd->floatmax ) {
SourceError( source, "float out of range [%f, %f]", fd->floatmin, fd->floatmax );
return 0;
} //end if
} //end if
*(float *) p = (float) floatval;
return 1;
} //end if
//
intval = token.intvalue;
if ( negative ) {
intval = -intval;
}
//check bounds
if ( ( fd->type & FT_TYPE ) == FT_CHAR ) {
if ( fd->type & FT_UNSIGNED ) {
intmin = 0; intmax = 255;
} else {intmin = -128; intmax = 127;}
} //end if
if ( ( fd->type & FT_TYPE ) == FT_INT ) {
if ( fd->type & FT_UNSIGNED ) {
intmin = 0; intmax = 65535;
} else {intmin = -32768; intmax = 32767;}
} //end else if
if ( ( fd->type & FT_TYPE ) == FT_CHAR || ( fd->type & FT_TYPE ) == FT_INT ) {
if ( fd->type & FT_BOUNDED ) {
intmin = Maximum( intmin, fd->floatmin );
intmax = Minimum( intmax, fd->floatmax );
} //end if
if ( intval < intmin || intval > intmax ) {
SourceError( source, "value %d out of range [%d, %d]", intval, intmin, intmax );
return 0;
} //end if
} //end if
else if ( ( fd->type & FT_TYPE ) == FT_FLOAT ) {
if ( fd->type & FT_BOUNDED ) {
if ( intval < fd->floatmin || intval > fd->floatmax ) {
SourceError( source, "value %d out of range [%f, %f]", intval, fd->floatmin, fd->floatmax );
return 0;
} //end if
} //end if
} //end else if
//store the value
if ( ( fd->type & FT_TYPE ) == FT_CHAR ) {
if ( fd->type & FT_UNSIGNED ) {
*(unsigned char *) p = (unsigned char) intval;
} else { *(char *) p = (char) intval;}
} //end if
else if ( ( fd->type & FT_TYPE ) == FT_INT ) {
if ( fd->type & FT_UNSIGNED ) {
*(unsigned int *) p = (unsigned int) intval;
} else { *(int *) p = (int) intval;}
} //end else
else if ( ( fd->type & FT_TYPE ) == FT_FLOAT ) {
*(float *) p = (float) intval;
} //end else
return 1;
} //end of the function ReadNumber
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
qboolean ReadChar( source_t *source, fielddef_t *fd, void *p ) {
token_t token;
if ( !PC_ExpectAnyToken( source, &token ) ) {
return 0;
}
//take literals into account
if ( token.type == TT_LITERAL ) {
StripSingleQuotes( token.string );
*(char *) p = token.string[0];
} //end if
else
{
PC_UnreadLastToken( source );
if ( !ReadNumber( source, fd, p ) ) {
return 0;
}
} //end if
return 1;
} //end of the function ReadChar
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int ReadString( source_t *source, fielddef_t *fd, void *p ) {
token_t token;
if ( !PC_ExpectTokenType( source, TT_STRING, 0, &token ) ) {
return 0;
}
//remove the double quotes
StripDoubleQuotes( token.string );
//copy the string
strncpy( (char *) p, token.string, MAX_STRINGFIELD );
//make sure the string is closed with a zero
( (char *)p )[MAX_STRINGFIELD - 1] = '\0';
//
return 1;
} //end of the function ReadString
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int ReadStructure( source_t *source, structdef_t *def, char *structure ) {
token_t token;
fielddef_t *fd;
void *p;
int num;
if ( !PC_ExpectTokenString( source, "{" ) ) {
return 0;
}
while ( 1 )
{
if ( !PC_ExpectAnyToken( source, &token ) ) {
return qfalse;
}
//if end of structure
if ( !strcmp( token.string, "}" ) ) {
break;
}
//find the field with the name
fd = FindField( def->fields, token.string );
if ( !fd ) {
SourceError( source, "unknown structure field %s", token.string );
return qfalse;
} //end if
if ( fd->type & FT_ARRAY ) {
num = fd->maxarray;
if ( !PC_ExpectTokenString( source, "{" ) ) {
return qfalse;
}
} //end if
else
{
num = 1;
} //end else
p = ( void * )( structure + fd->offset );
while ( num-- > 0 )
{
if ( fd->type & FT_ARRAY ) {
if ( PC_CheckTokenString( source, "}" ) ) {
break;
}
} //end if
switch ( fd->type & FT_TYPE )
{
case FT_CHAR:
{
if ( !ReadChar( source, fd, p ) ) {
return qfalse;
}
p = (char *) p + sizeof( char );
break;
} //end case
case FT_INT:
{
if ( !ReadNumber( source, fd, p ) ) {
return qfalse;
}
p = (char *) p + sizeof( int );
break;
} //end case
case FT_FLOAT:
{
if ( !ReadNumber( source, fd, p ) ) {
return qfalse;
}
p = (char *) p + sizeof( float );
break;
} //end case
case FT_STRING:
{
if ( !ReadString( source, fd, p ) ) {
return qfalse;
}
p = (char *) p + MAX_STRINGFIELD;
break;
} //end case
case FT_STRUCT:
{
if ( !fd->substruct ) {
SourceError( source, "BUG: no sub structure defined" );
return qfalse;
} //end if
ReadStructure( source, fd->substruct, (char *) p );
p = (char *) p + fd->substruct->size;
break;
} //end case
} //end switch
if ( fd->type & FT_ARRAY ) {
if ( !PC_ExpectAnyToken( source, &token ) ) {
return qfalse;
}
if ( !strcmp( token.string, "}" ) ) {
break;
}
if ( strcmp( token.string, "," ) ) {
SourceError( source, "expected a comma, found %s", token.string );
return qfalse;
} //end if
} //end if
} //end while
} //end while
return qtrue;
} //end of the function ReadStructure
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteIndent( FILE *fp, int indent ) {
while ( indent-- > 0 )
{
if ( fprintf( fp, "\t" ) < 0 ) {
return qfalse;
}
} //end while
return qtrue;
} //end of the function WriteIndent
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteFloat( FILE *fp, float value ) {
char buf[128];
int l;
sprintf( buf, "%f", value );
l = strlen( buf );
//strip any trailing zeros
while ( l-- > 1 )
{
if ( buf[l] != '0' && buf[l] != '.' ) {
break;
}
if ( buf[l] == '.' ) {
buf[l] = 0;
break;
} //end if
buf[l] = 0;
} //end while
//write the float to file
if ( fprintf( fp, "%s", buf ) < 0 ) {
return 0;
}
return 1;
} //end of the function WriteFloat
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteStructWithIndent( FILE *fp, structdef_t *def, char *structure, int indent ) {
int i, num;
void *p;
fielddef_t *fd;
if ( !WriteIndent( fp, indent ) ) {
return qfalse;
}
if ( fprintf( fp, "{\r\n" ) < 0 ) {
return qfalse;
}
indent++;
for ( i = 0; def->fields[i].name; i++ )
{
fd = &def->fields[i];
if ( !WriteIndent( fp, indent ) ) {
return qfalse;
}
if ( fprintf( fp, "%s\t", fd->name ) < 0 ) {
return qfalse;
}
p = ( void * )( structure + fd->offset );
if ( fd->type & FT_ARRAY ) {
num = fd->maxarray;
if ( fprintf( fp, "{" ) < 0 ) {
return qfalse;
}
} //end if
else
{
num = 1;
} //end else
while ( num-- > 0 )
{
switch ( fd->type & FT_TYPE )
{
case FT_CHAR:
{
if ( fprintf( fp, "%d", *(char *) p ) < 0 ) {
return qfalse;
}
p = (char *) p + sizeof( char );
break;
} //end case
case FT_INT:
{
if ( fprintf( fp, "%d", *(int *) p ) < 0 ) {
return qfalse;
}
p = (char *) p + sizeof( int );
break;
} //end case
case FT_FLOAT:
{
if ( !WriteFloat( fp, *(float *)p ) ) {
return qfalse;
}
p = (char *) p + sizeof( float );
break;
} //end case
case FT_STRING:
{
if ( fprintf( fp, "\"%s\"", (char *) p ) < 0 ) {
return qfalse;
}
p = (char *) p + MAX_STRINGFIELD;
break;
} //end case
case FT_STRUCT:
{
if ( !WriteStructWithIndent( fp, fd->substruct, structure, indent ) ) {
return qfalse;
}
p = (char *) p + fd->substruct->size;
break;
} //end case
} //end switch
if ( fd->type & FT_ARRAY ) {
if ( num > 0 ) {
if ( fprintf( fp, "," ) < 0 ) {
return qfalse;
}
} //end if
else
{
if ( fprintf( fp, "}" ) < 0 ) {
return qfalse;
}
} //end else
} //end if
} //end while
if ( fprintf( fp, "\r\n" ) < 0 ) {
return qfalse;
}
} //end for
indent--;
if ( !WriteIndent( fp, indent ) ) {
return qfalse;
}
if ( fprintf( fp, "}\r\n" ) < 0 ) {
return qfalse;
}
return qtrue;
} //end of the function WriteStructWithIndent
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int WriteStructure( FILE *fp, structdef_t *def, char *structure ) {
return WriteStructWithIndent( fp, def, structure, 0 );
} //end of the function WriteStructure

81
src/botlib/l_struct.h Normal file
View File

@@ -0,0 +1,81 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_struct.h
*
* desc: structure reading/writing
*
*
*****************************************************************************/
#define MAX_STRINGFIELD 80
//field types
#define FT_CHAR 1 // char
#define FT_INT 2 // int
#define FT_FLOAT 3 // float
#define FT_STRING 4 // char [MAX_STRINGFIELD]
#define FT_STRUCT 6 // struct (sub structure)
//type only mask
#define FT_TYPE 0x00FF // only type, clear subtype
//sub types
#define FT_ARRAY 0x0100 // array of type
#define FT_BOUNDED 0x0200 // bounded value
#define FT_UNSIGNED 0x0400
//structure field definition
typedef struct fielddef_s
{
char *name; //name of the field
int offset; //offset in the structure
int type; //type of the field
//type specific fields
int maxarray; //maximum array size
float floatmin, floatmax; //float min and max
struct structdef_s *substruct; //sub structure
} fielddef_t;
//structure definition
typedef struct structdef_s
{
int size;
fielddef_t *fields;
} structdef_t;
//read a structure from a script
int ReadStructure( source_t *source, structdef_t *def, char *structure );
//write a structure to a file
int WriteStructure( FILE *fp, structdef_t *def, char *structure );
//writes indents
int WriteIndent( FILE *fp, int indent );
//writes a float without traling zeros
int WriteFloat( FILE *fp, float value );

43
src/botlib/l_utils.h Normal file
View File

@@ -0,0 +1,43 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
/*****************************************************************************
* name: l_util.h
*
* desc: utils
*
*
*****************************************************************************/
#define Vector2Angles( v,a ) vectoangles( v,a )
#ifndef MAX_PATH // LBO 1/25/05
#define MAX_PATH MAX_QPATH
#endif
#define Maximum( x,y ) ( x > y ? x : y )
#define Minimum( x,y ) ( x < y ? x : y )

91
src/bspc/_files.c Normal file
View File

@@ -0,0 +1,91 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: _files.c
// Function:
// Programmer: Mr Elusive
// Last update: 1999-12-02
// Tab Size: 4
//===========================================================================
/*
aas_areamerging.c //AAS area merging
aas_cfg.c //AAS configuration for different games
aas_create.c //AAS creating
aas_edgemelting.c //AAS edge melting
aas_facemerging.c //AAS face merging
aas_file.c //AAS file writing
aas_gsubdiv.c //AAS gravitational and ladder subdivision
aas_map.c //AAS map brush creation
aas_prunenodes.c //AAS node pruning
aas_store.c //AAS file storing
map.c //map file loading and writing
map_hl.c //Half-Life map loading
map_q1.c //Quake1 map loading
map_q2.c //Quake2 map loading
map_q3.c //Quake3 map loading
map_sin.c //Sin map loading
tree.c //BSP tree management + node pruning (*)
brushbsp.c //brush bsp creation (*)
portals.c //BSP portal creation and leaf filling (*)
csg.c //Constructive Solid Geometry brush chopping (*)
leakfile.c //leak file writing (*)
textures.c //Quake2 BSP textures (*)
l_bsp_ent.c //BSP entity parsing
l_bsp_hl.c //Half-Life BSP loading and writing
l_bsp_q1.c //Quake1 BSP loading and writing
l_bsp_q2.c //Quake2 BSP loading and writing
l_bsp_q3.c //Quake2 BSP loading and writing
l_bsp_sin.c //Sin BSP loading and writing
l_cmd.c //cmd library
l_log.c //log file library
l_math.c //math library
l_mem.c //memory management library
l_poly.c //polygon (winding) library
l_script.c //script file parsing library
l_threads.c //multi-threading library
l_utils.c //utility library
l_qfiles.c //loading of quake files
gldraw.c //GL drawing (*)
glfile.c //GL file writing (*)
nodraw.c //no draw module (*)
bspc.c //BSPC Win32 console version
winbspc.c //WinBSPC Win32 GUI version
win32_terminal.c //Win32 terminal output
win32_qfiles.c //Win32 game file management (also .pak .sin)
win32_font.c //Win32 fonts
win32_folder.c //Win32 folder dialogs
*/

447
src/bspc/aas_areamerging.c Normal file
View File

@@ -0,0 +1,447 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: aas_areamerging.c
// Function: Merging of Areas
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
// Last update: 1997-12-04
// Tab Size: 3
//===========================================================================
#include "qbsp.h"
#include "../botlib/aasfile.h"
#include "aas_create.h"
#include "aas_store.h"
#define CONVEX_EPSILON 0.3
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
tmp_node_t *AAS_RefreshMergedTree_r( tmp_node_t *tmpnode ) {
tmp_area_t *tmparea;
//if this is a solid leaf
if ( !tmpnode ) {
return NULL;
}
//if this is an area leaf
if ( tmpnode->tmparea ) {
tmparea = tmpnode->tmparea;
while ( tmparea->mergedarea ) tmparea = tmparea->mergedarea;
tmpnode->tmparea = tmparea;
return tmpnode;
} //end if
//do the children recursively
tmpnode->children[0] = AAS_RefreshMergedTree_r( tmpnode->children[0] );
tmpnode->children[1] = AAS_RefreshMergedTree_r( tmpnode->children[1] );
return tmpnode;
} //end of the function AAS_RefreshMergedTree_r
//===========================================================================
// returns true if the two given faces would create a non-convex area at
// the given sides, otherwise false is returned
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int NonConvex( tmp_face_t *face1, tmp_face_t *face2, int side1, int side2 ) {
int i;
winding_t *w1, *w2;
plane_t *plane1, *plane2;
w1 = face1->winding;
w2 = face2->winding;
plane1 = &mapplanes[face1->planenum ^ side1];
plane2 = &mapplanes[face2->planenum ^ side2];
//check if one of the points of face1 is at the back of the plane of face2
for ( i = 0; i < w1->numpoints; i++ )
{
if ( DotProduct( plane2->normal, w1->p[i] ) - plane2->dist < -CONVEX_EPSILON ) {
return true;
}
} //end for
//check if one of the points of face2 is at the back of the plane of face1
for ( i = 0; i < w2->numpoints; i++ )
{
if ( DotProduct( plane1->normal, w2->p[i] ) - plane1->dist < -CONVEX_EPSILON ) {
return true;
}
} //end for
return false;
} //end of the function NonConvex
//===========================================================================
// try to merge the areas at both sides of the given face
//
// Parameter: seperatingface : face that seperates two areas
// Returns: -
// Changes Globals: -
//===========================================================================
int AAS_TryMergeFaceAreas( tmp_face_t *seperatingface ) {
int side1, side2, area1faceflags, area2faceflags;
tmp_area_t *tmparea1, *tmparea2, *newarea;
tmp_face_t *face1, *face2, *nextface1, *nextface2;
tmparea1 = seperatingface->frontarea;
tmparea2 = seperatingface->backarea;
//areas must have the same presence type
if ( tmparea1->presencetype != tmparea2->presencetype ) {
return false;
}
//areas must have the same area contents
if ( tmparea1->contents != tmparea2->contents ) {
return false;
}
//areas must have the same bsp model inside (or both none)
if ( tmparea1->modelnum != tmparea2->modelnum ) {
return false;
}
area1faceflags = 0;
area2faceflags = 0;
for ( face1 = tmparea1->tmpfaces; face1; face1 = face1->next[side1] )
{
side1 = ( face1->frontarea != tmparea1 );
//debug: check if the area belongs to the area
if ( face1->frontarea != tmparea1 &&
face1->backarea != tmparea1 ) {
Error( "face does not belong to area1" );
}
//just continue if the face is seperating the two areas
//NOTE: a result of this is that ground and gap areas can
// be merged if the seperating face is the gap
if ( ( face1->frontarea == tmparea1 &&
face1->backarea == tmparea2 ) ||
( face1->frontarea == tmparea2 &&
face1->backarea == tmparea1 ) ) {
continue;
}
//get area1 face flags
area1faceflags |= face1->faceflags;
if ( AAS_GapFace( face1, side1 ) ) {
area1faceflags |= FACE_GAP;
}
//
for ( face2 = tmparea2->tmpfaces; face2; face2 = face2->next[side2] )
{
side2 = ( face2->frontarea != tmparea2 );
//debug: check if the area belongs to the area
if ( face2->frontarea != tmparea2 &&
face2->backarea != tmparea2 ) {
Error( "face does not belong to area2" );
}
//just continue if the face is seperating the two areas
//NOTE: a result of this is that ground and gap areas can
// be merged if the seperating face is the gap
if ( ( face2->frontarea == tmparea1 &&
face2->backarea == tmparea2 ) ||
( face2->frontarea == tmparea2 &&
face2->backarea == tmparea1 ) ) {
continue;
}
//get area2 face flags
area2faceflags |= face2->faceflags;
if ( AAS_GapFace( face2, side2 ) ) {
area2faceflags |= FACE_GAP;
}
//if the two faces would create a non-convex area
if ( NonConvex( face1, face2, side1, side2 ) ) {
return false;
}
} //end for
} //end for
//if one area has gap faces (that aren't seperating the two areas)
//and the other has ground faces (that aren't seperating the two areas),
//the areas can't be merged
if ( ( ( area1faceflags & FACE_GROUND ) && ( area2faceflags & FACE_GAP ) ) ||
( ( area2faceflags & FACE_GROUND ) && ( area1faceflags & FACE_GAP ) ) ) {
// Log_Print(" can't merge: ground/gap\n");
return false;
} //end if
// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum, numfaces);
// return false;
//
//AAS_CheckArea(tmparea1);
//AAS_CheckArea(tmparea2);
//create the new area
newarea = AAS_AllocTmpArea();
newarea->presencetype = tmparea1->presencetype;
newarea->contents = tmparea1->contents;
newarea->modelnum = tmparea1->modelnum;
newarea->tmpfaces = NULL;
//add all the faces (except the seperating ones) from the first area
//to the new area
for ( face1 = tmparea1->tmpfaces; face1; face1 = nextface1 )
{
side1 = ( face1->frontarea != tmparea1 );
nextface1 = face1->next[side1];
//don't add seperating faces
if ( ( face1->frontarea == tmparea1 &&
face1->backarea == tmparea2 ) ||
( face1->frontarea == tmparea2 &&
face1->backarea == tmparea1 ) ) {
continue;
} //end if
//
AAS_RemoveFaceFromArea( face1, tmparea1 );
AAS_AddFaceSideToArea( face1, side1, newarea );
} //end for
//add all the faces (except the seperating ones) from the second area
//to the new area
for ( face2 = tmparea2->tmpfaces; face2; face2 = nextface2 )
{
side2 = ( face2->frontarea != tmparea2 );
nextface2 = face2->next[side2];
//don't add seperating faces
if ( ( face2->frontarea == tmparea1 &&
face2->backarea == tmparea2 ) ||
( face2->frontarea == tmparea2 &&
face2->backarea == tmparea1 ) ) {
continue;
} //end if
//
AAS_RemoveFaceFromArea( face2, tmparea2 );
AAS_AddFaceSideToArea( face2, side2, newarea );
} //end for
//free all shared faces
for ( face1 = tmparea1->tmpfaces; face1; face1 = nextface1 )
{
side1 = ( face1->frontarea != tmparea1 );
nextface1 = face1->next[side1];
//
AAS_RemoveFaceFromArea( face1, face1->frontarea );
AAS_RemoveFaceFromArea( face1, face1->backarea );
AAS_FreeTmpFace( face1 );
} //end for
//
tmparea1->mergedarea = newarea;
tmparea1->invalid = true;
tmparea2->mergedarea = newarea;
tmparea2->invalid = true;
//
AAS_CheckArea( newarea );
AAS_FlipAreaFaces( newarea );
// Log_Print("merged area %d & %d to %d with %d faces\n", tmparea1->areanum, tmparea2->areanum, newarea->areanum);
return true;
} //end of the function AAS_TryMergeFaceAreas
//===========================================================================
// try to merge areas
// merged areas are added to the end of the convex area list so merging
// will be tried for those areas as well
//
// Parameter: -
// Returns: -
// Changes Globals: tmpaasworld
//===========================================================================
/*
void AAS_MergeAreas(void)
{
int side, nummerges;
tmp_area_t *tmparea, *othertmparea;
tmp_face_t *face;
nummerges = 0;
Log_Write("AAS_MergeAreas\r\n");
qprintf("%6d areas merged", 1);
//first merge grounded areas only
//NOTE: this is useless because the area settings aren't available yet
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
// Log_Print("checking area %d\n", i);
//if the area is invalid
if (tmparea->invalid)
{
// Log_Print(" area invalid\n");
continue;
} //end if
//
// if (!(tmparea->settings->areaflags & AREA_GROUNDED)) continue;
//
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
//if the face has both a front and back area
if (face->frontarea && face->backarea)
{
//
if (face->frontarea == tmparea) othertmparea = face->backarea;
else othertmparea = face->frontarea;
// if (!(othertmparea->settings->areaflags & AREA_GROUNDED)) continue;
// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
if (AAS_TryMergeFaceAreas(face))
{
qprintf("\r%6d", ++nummerges);
break;
} //end if
} //end if
} //end for
} //end for
//merge all areas
for (tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next)
{
// Log_Print("checking area %d\n", i);
//if the area is invalid
if (tmparea->invalid)
{
// Log_Print(" area invalid\n");
continue;
} //end if
//
for (face = tmparea->tmpfaces; face; face = face->next[side])
{
side = (face->frontarea != tmparea);
//if the face has both a front and back area
if (face->frontarea && face->backarea)
{
// Log_Print(" checking area %d with %d\n", face->frontarea, face->backarea);
if (AAS_TryMergeFaceAreas(face))
{
qprintf("\r%6d", ++nummerges);
break;
} //end if
} //end if
} //end for
} //end for
Log_Print("\r%6d areas merged\n", nummerges);
//refresh the merged tree
AAS_RefreshMergedTree_r(tmpaasworld.nodes);
} //end of the function AAS_MergeAreas*/
int AAS_GroundArea( tmp_area_t *tmparea ) {
tmp_face_t *face;
int side;
for ( face = tmparea->tmpfaces; face; face = face->next[side] )
{
side = ( face->frontarea != tmparea );
if ( face->faceflags & FACE_GROUND ) {
return true;
}
} //end for
return false;
} //end of the function AAS_GroundArea
int AAS_LadderArea( tmp_area_t *tmparea ) {
tmp_face_t *face;
int side;
for ( face = tmparea->tmpfaces; face; face = face->next[side] )
{
side = ( face->frontarea != tmparea );
if ( face->faceflags & FACE_LADDER ) {
return true;
}
} //end for
return false;
} //end of the function AAS_GroundArea
void AAS_MergeAreas( void ) {
int side, nummerges, merges, groundfirst;
tmp_area_t *tmparea, *othertmparea;
tmp_face_t *face;
nummerges = 0;
Log_Write( "AAS_MergeAreas\r\n" );
qprintf( "%6d areas merged", 1 );
//
groundfirst = true;
//for (i = 0; i < 4 || merges; i++)
while ( 1 )
{
//if (i < 2) groundfirst = true;
//else groundfirst = false;
//
merges = 0;
//first merge grounded areas only
for ( tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next )
{
//if the area is invalid
if ( tmparea->invalid ) {
continue;
} //end if
//
if ( groundfirst ) {
if ( !AAS_GroundArea( tmparea ) ) {
continue;
}
} //end if
//
for ( face = tmparea->tmpfaces; face; face = face->next[side] )
{
side = ( face->frontarea != tmparea );
//if the face has both a front and back area
if ( face->frontarea && face->backarea ) {
//
if ( face->frontarea == tmparea ) {
othertmparea = face->backarea;
} else { othertmparea = face->frontarea;}
//
if ( groundfirst ) {
if ( !AAS_GroundArea( othertmparea ) ) {
continue;
}
} //end if
// if the critical types are different, dont merge
if ( ( AAS_GroundArea( tmparea ) != AAS_GroundArea( othertmparea ) )
|| ( AAS_LadderArea( tmparea ) != AAS_LadderArea( othertmparea ) )
|| ( ( tmparea->contents & AREACONTENTS_MOVER ) != ( othertmparea->contents & AREACONTENTS_MOVER ) )
|| ( ( tmparea->contents & AREACONTENTS_WATER ) != ( othertmparea->contents & AREACONTENTS_WATER ) ) ) {
continue;
}
if ( AAS_TryMergeFaceAreas( face ) ) {
qprintf( "\r%6d", ++nummerges );
merges++;
break;
} //end if
} //end if
} //end for
} //end for
if ( !merges ) {
if ( groundfirst ) {
groundfirst = false;
} else { break;}
} //end if
} //end for
qprintf( "\n" );
Log_Write( "%6d areas merged\r\n", nummerges );
//refresh the merged tree
AAS_RefreshMergedTree_r( tmpaasworld.nodes );
} //end of the function AAS_MergeAreas

View File

@@ -0,0 +1,40 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: aas_areamerging.h
// Function: Merging of Areas
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
// Last update: 1997-12-04
// Tab Size: 3
//===========================================================================
void AAS_MergeAreas( void );

310
src/bspc/aas_cfg.c Normal file
View File

@@ -0,0 +1,310 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: cfg.c
// Function:
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
// Last update: 1997-12-04
// Tab Size: 3
//===========================================================================
#include "qbsp.h"
#include "float.h"
#include "..\botlib\aasfile.h"
#include "aas_store.h"
#include "aas_cfg.h"
#include "../botlib/l_precomp.h"
#include "../botlib/l_struct.h"
#include "../botlib/l_libvar.h"
///////////////////////////////////
extern void LibVarSet( char *var_name, char *value );
///////////////////////////////////
//structure field offsets
#define BBOX_OFS( x ) (int)&( ( (aas_bbox_t *)0 )->x )
#define CFG_OFS( x ) (int)&( ( (cfg_t *)0 )->x )
//bounding box definition
fielddef_t bbox_fields[] =
{
{"presencetype", BBOX_OFS( presencetype ), FT_INT},
{"flags", BBOX_OFS( flags ), FT_INT},
{"mins", BBOX_OFS( mins ), FT_FLOAT | FT_ARRAY, 3},
{"maxs", BBOX_OFS( maxs ), FT_FLOAT | FT_ARRAY, 3},
{NULL, 0, 0, 0}
};
fielddef_t cfg_fields[] =
{
{"phys_gravitydirection", CFG_OFS( phys_gravitydirection ), FT_FLOAT | FT_ARRAY, 3},
{"phys_friction", CFG_OFS( phys_friction ), FT_FLOAT},
{"phys_stopspeed", CFG_OFS( phys_stopspeed ), FT_FLOAT},
{"phys_gravity", CFG_OFS( phys_gravity ), FT_FLOAT},
{"phys_waterfriction", CFG_OFS( phys_waterfriction ), FT_FLOAT},
{"phys_watergravity", CFG_OFS( phys_watergravity ), FT_FLOAT},
{"phys_maxvelocity", CFG_OFS( phys_maxvelocity ), FT_FLOAT},
{"phys_maxwalkvelocity", CFG_OFS( phys_maxwalkvelocity ), FT_FLOAT},
{"phys_maxcrouchvelocity", CFG_OFS( phys_maxcrouchvelocity ), FT_FLOAT},
{"phys_maxswimvelocity", CFG_OFS( phys_maxswimvelocity ), FT_FLOAT},
{"phys_walkaccelerate", CFG_OFS( phys_walkaccelerate ), FT_FLOAT},
{"phys_airaccelerate", CFG_OFS( phys_airaccelerate ), FT_FLOAT},
{"phys_swimaccelerate", CFG_OFS( phys_swimaccelerate ), FT_FLOAT},
{"phys_maxstep", CFG_OFS( phys_maxstep ), FT_FLOAT},
{"phys_maxsteepness", CFG_OFS( phys_maxsteepness ), FT_FLOAT},
{"phys_maxwaterjump", CFG_OFS( phys_maxwaterjump ), FT_FLOAT},
{"phys_maxbarrier", CFG_OFS( phys_maxbarrier ), FT_FLOAT},
{"phys_jumpvel", CFG_OFS( phys_jumpvel ), FT_FLOAT},
{"phys_falldelta5", CFG_OFS( phys_falldelta5 ), FT_FLOAT},
{"phys_falldelta10", CFG_OFS( phys_falldelta10 ), FT_FLOAT},
{"rs_waterjump", CFG_OFS( rs_waterjump ), FT_FLOAT},
{"rs_teleport", CFG_OFS( rs_teleport ), FT_FLOAT},
{"rs_barrierjump", CFG_OFS( rs_barrierjump ), FT_FLOAT},
{"rs_startcrouch", CFG_OFS( rs_startcrouch ), FT_FLOAT},
{"rs_startgrapple", CFG_OFS( rs_startgrapple ), FT_FLOAT},
{"rs_startwalkoffledge", CFG_OFS( rs_startwalkoffledge ), FT_FLOAT},
{"rs_startjump", CFG_OFS( rs_startjump ), FT_FLOAT},
{"rs_rocketjump", CFG_OFS( rs_rocketjump ), FT_FLOAT},
{"rs_bfgjump", CFG_OFS( rs_bfgjump ), FT_FLOAT},
{"rs_jumppad", CFG_OFS( rs_jumppad ), FT_FLOAT},
{"rs_aircontrolledjumppad", CFG_OFS( rs_aircontrolledjumppad ), FT_FLOAT},
{"rs_funcbob", CFG_OFS( rs_funcbob ), FT_FLOAT},
{"rs_startelevator", CFG_OFS( rs_startelevator ), FT_FLOAT},
{"rs_falldamage5", CFG_OFS( rs_falldamage5 ), FT_FLOAT},
{"rs_falldamage10", CFG_OFS( rs_falldamage10 ), FT_FLOAT},
{"rs_maxjumpfallheight", CFG_OFS( rs_maxjumpfallheight ), FT_FLOAT},
{"rs_allowladders", CFG_OFS( rs_allowladders ), FT_INT},
{NULL, 0, 0, 0}
};
structdef_t bbox_struct =
{
sizeof( aas_bbox_t ), bbox_fields
};
structdef_t cfg_struct =
{
sizeof( cfg_t ), cfg_fields
};
//global cfg
cfg_t cfg;
#if 0
//===========================================================================
// the default Q3A configuration
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void DefaultCfg( void ) {
int i;
// default all float values to infinite
for ( i = 0; cfg_fields[i].name; i++ )
{
if ( ( cfg_fields[i].type & FT_TYPE ) == FT_FLOAT ) {
*( float * )( ( (char*)&cfg ) + cfg_fields[i].offset ) = FLT_MAX;
}
} //end for
//
cfg.numbboxes = 2;
//bbox 0
cfg.bboxes[0].presencetype = PRESENCE_NORMAL;
cfg.bboxes[0].flags = 0;
cfg.bboxes[0].mins[0] = -18;
cfg.bboxes[0].mins[1] = -18;
cfg.bboxes[0].mins[2] = -24;
cfg.bboxes[0].maxs[0] = 18;
cfg.bboxes[0].maxs[1] = 18;
cfg.bboxes[0].maxs[2] = 48;
//bbox 1
cfg.bboxes[1].presencetype = PRESENCE_CROUCH;
cfg.bboxes[1].flags = 1;
cfg.bboxes[1].mins[0] = -18;
cfg.bboxes[1].mins[1] = -18;
cfg.bboxes[1].mins[2] = -24;
cfg.bboxes[1].maxs[0] = 18;
cfg.bboxes[1].maxs[1] = 18;
cfg.bboxes[1].maxs[2] = 24;
//
cfg.allpresencetypes = PRESENCE_NORMAL | PRESENCE_CROUCH;
cfg.phys_gravitydirection[0] = 0;
cfg.phys_gravitydirection[1] = 0;
cfg.phys_gravitydirection[2] = -1;
cfg.phys_maxsteepness = 0.7;
// cfg.phys_maxbarrier = -999;//32; // RIDAH: this is calculated at run-time now, from the gravity and jump velocity settings
} //end of the function DefaultCfg
#else
//===========================================================================
// the default Q3A configuration
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void DefaultCfg( void ) {
int i;
// default all float values to infinite
for ( i = 0; cfg_fields[i].name; i++ )
{
if ( ( cfg_fields[i].type & FT_TYPE ) == FT_FLOAT ) {
*( float * )( ( (char*)&cfg ) + cfg_fields[i].offset ) = FLT_MAX;
}
} //end for
//
cfg.numbboxes = 2;
//bbox 0
cfg.bboxes[0].presencetype = PRESENCE_NORMAL;
cfg.bboxes[0].flags = 0;
cfg.bboxes[0].mins[0] = -15;
cfg.bboxes[0].mins[1] = -15;
cfg.bboxes[0].mins[2] = -24;
cfg.bboxes[0].maxs[0] = 15;
cfg.bboxes[0].maxs[1] = 15;
cfg.bboxes[0].maxs[2] = 32;
//bbox 1
cfg.bboxes[1].presencetype = PRESENCE_CROUCH;
cfg.bboxes[1].flags = 1;
cfg.bboxes[1].mins[0] = -15;
cfg.bboxes[1].mins[1] = -15;
cfg.bboxes[1].mins[2] = -24;
cfg.bboxes[1].maxs[0] = 15;
cfg.bboxes[1].maxs[1] = 15;
cfg.bboxes[1].maxs[2] = 16;
//
cfg.allpresencetypes = PRESENCE_NORMAL | PRESENCE_CROUCH;
cfg.phys_gravitydirection[0] = 0;
cfg.phys_gravitydirection[1] = 0;
cfg.phys_gravitydirection[2] = -1;
cfg.phys_maxsteepness = 0.7;
// cfg.phys_maxbarrier = -999;//32; // RIDAH: this is calculated at run-time now, from the gravity and jump velocity settings
} //end of the function DefaultCfg
#endif
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
char * QDECL va( char *format, ... ) {
va_list argptr;
static char string[2][32000]; // in case va is called by nested functions
static int index = 0;
char *buf;
buf = string[index & 1];
index++;
va_start( argptr, format );
vsprintf( buf, format,argptr );
va_end( argptr );
return buf;
} //end of the function va
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
void SetCfgLibVars( void ) {
int i;
float value;
for ( i = 0; cfg_fields[i].name; i++ )
{
if ( ( cfg_fields[i].type & FT_TYPE ) == FT_FLOAT ) {
value = *( float * )( ( (char*)&cfg ) + cfg_fields[i].offset );
if ( value != FLT_MAX ) {
LibVarSet( cfg_fields[i].name, va( "%f", value ) );
} //end if
} //end if
} //end for
} //end of the function SetCfgLibVars
//===========================================================================
//
// Parameter: -
// Returns: -
// Changes Globals: -
//===========================================================================
int LoadCfgFile( char *filename ) {
source_t *source;
token_t token;
int settingsdefined;
source = LoadSourceFile( filename );
if ( !source ) {
Log_Print( "couldn't open cfg file %s\n", filename );
return false;
} //end if
settingsdefined = false;
memset( &cfg, 0, sizeof( cfg_t ) );
while ( PC_ReadToken( source, &token ) )
{
if ( !stricmp( token.string, "bbox" ) ) {
if ( cfg.numbboxes >= AAS_MAX_BBOXES ) {
SourceError( source, "too many bounding box volumes defined" );
} //end if
if ( !ReadStructure( source, &bbox_struct, (char *) &cfg.bboxes[cfg.numbboxes] ) ) {
FreeSource( source );
return false;
} //end if
cfg.allpresencetypes |= cfg.bboxes[cfg.numbboxes].presencetype;
cfg.numbboxes++;
} //end if
else if ( !stricmp( token.string, "settings" ) ) {
if ( settingsdefined ) {
SourceWarning( source, "settings already defined\n" );
} //end if
settingsdefined = true;
if ( !ReadStructure( source, &cfg_struct, (char *) &cfg ) ) {
FreeSource( source );
return false;
} //end if
} //end else if
} //end while
if ( VectorLength( cfg.phys_gravitydirection ) < 0.9 || VectorLength( cfg.phys_gravitydirection ) > 1.1 ) {
SourceError( source, "invalid gravity direction specified" );
} //end if
if ( cfg.numbboxes <= 0 ) {
SourceError( source, "no bounding volumes specified" );
} //end if
FreeSource( source );
SetCfgLibVars();
Log_Print( "using cfg file %s\n", filename );
return true;
} //end of the function LoadCfgFile

89
src/bspc/aas_cfg.h Normal file
View File

@@ -0,0 +1,89 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: cfg.h
// Function:
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
// Last update: 1997-12-04
// Tab Size: 3
//===========================================================================
#define BBOXFL_GROUNDED 1 //bounding box only valid when on ground
#define BBOXFL_NOTGROUNDED 2 //bounding box only valid when NOT on ground
typedef struct cfg_s
{
int numbboxes; //number of bounding boxes
aas_bbox_t bboxes[AAS_MAX_BBOXES]; //all the bounding boxes
int allpresencetypes; //or of all presence types
// aas settings
vec3_t phys_gravitydirection;
float phys_friction;
float phys_stopspeed;
float phys_gravity;
float phys_waterfriction;
float phys_watergravity;
float phys_maxvelocity;
float phys_maxwalkvelocity;
float phys_maxcrouchvelocity;
float phys_maxswimvelocity;
float phys_walkaccelerate;
float phys_airaccelerate;
float phys_swimaccelerate;
float phys_maxstep;
float phys_maxsteepness;
float phys_maxwaterjump;
float phys_maxbarrier;
float phys_jumpvel;
float phys_falldelta5;
float phys_falldelta10;
float rs_waterjump;
float rs_teleport;
float rs_barrierjump;
float rs_startcrouch;
float rs_startgrapple;
float rs_startwalkoffledge;
float rs_startjump;
float rs_rocketjump;
float rs_bfgjump;
float rs_jumppad;
float rs_aircontrolledjumppad;
float rs_funcbob;
float rs_startelevator;
float rs_falldamage5;
float rs_falldamage10;
float rs_maxjumpfallheight;
qboolean rs_allowladders;
} cfg_t;
extern cfg_t cfg;
void DefaultCfg( void );
int LoadCfgFile( char *filename );

1370
src/bspc/aas_create.c Normal file

File diff suppressed because it is too large Load Diff

153
src/bspc/aas_create.h Normal file
View File

@@ -0,0 +1,153 @@
/*
===========================================================================
Wolfenstein: Enemy Territory GPL Source Code
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
This file is part of the Wolfenstein: Enemy Territory GPL Source Code (“Wolf ET Source Code”).
Wolf ET 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 3 of the License, or
(at your option) any later version.
Wolf ET 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 Wolf ET Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Wolf: ET Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Wolf ET Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
//===========================================================================
//
// Name: aas_create.h
// Function:
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
// Last update: 1997-12-04
// Tab Size: 3
//===========================================================================
#define AREA_PORTAL 1
//temporary AAS face
typedef struct tmp_face_s
{
int num; //face number
int planenum; //number of the plane the face is in
winding_t *winding; //winding of the face
struct tmp_area_s *frontarea; //area at the front of the face
struct tmp_area_s *backarea; //area at the back of the face
int faceflags; //flags of this face
int aasfacenum; //the number of the aas face used for this face
//double link list pointers for front and back area
struct tmp_face_s *prev[2], *next[2];
//links in the list with faces
struct tmp_face_s *l_prev, *l_next;
} tmp_face_t;
//temporary AAS area settings
typedef struct tmp_areasettings_s
{
//could also add all kind of statistic fields
int contents; //contents of the area
int modelnum; //bsp model inside this area
int areaflags; //area flags
int presencetype; //how a bot can be present in this area
int numreachableareas; //number of reachable areas from this one
int firstreachablearea; //first reachable area in the reachable area index
// Ridah, steepness
float groundsteepness;
} tmp_areasettings_t;
//temporary AAS area
typedef struct tmp_area_s
{
int areanum; //number of the area
struct tmp_face_s *tmpfaces; //the faces of the area
int presencetype; //presence type of the area
int contents; //area contents
int modelnum; //bsp model inside this area
int invalid; //true if the area is invalid
tmp_areasettings_t *settings; //area settings
struct tmp_area_s *mergedarea; //points to the new area after merging
//when mergedarea != 0 the area has only the
//seperating face of the merged areas
int aasareanum; //number of the aas area created for this tmp area
//links in the list with areas
struct tmp_area_s *l_prev, *l_next;
} tmp_area_t;
//temporary AAS node
typedef struct tmp_node_s
{
int planenum; //node plane number
struct tmp_area_s *tmparea; //points to an area if this node is an area
struct tmp_node_s *children[2]; //child nodes of this node
} tmp_node_t;
#define NODEBUF_SIZE 128
//node buffer
typedef struct tmp_nodebuf_s
{
int numnodes;
struct tmp_nodebuf_s *next;
tmp_node_t nodes[NODEBUF_SIZE];
} tmp_nodebuf_t;
//the whole temorary AAS
typedef struct tmp_aas_s
{
//faces
int numfaces;
int facenum;
tmp_face_t *faces;
//areas
int numareas;
int areanum;
tmp_area_t *areas;
//area settings
int numareasettings;
tmp_areasettings_t *areasettings;
//nodes
int numnodes;
tmp_node_t *nodes;
//node buffer
tmp_nodebuf_t *nodebuffer;
} tmp_aas_t;
extern tmp_aas_t tmpaasworld;
//creates a .AAS file with the given name from an already loaded map
void AAS_Create( char *aasfile );
//adds a face side to an area
void AAS_AddFaceSideToArea( tmp_face_t *tmpface, int side, tmp_area_t *tmparea );
//remvoes a face from an area
void AAS_RemoveFaceFromArea( tmp_face_t *tmpface, tmp_area_t *tmparea );
//allocate a tmp face
tmp_face_t *AAS_AllocTmpFace( void );
//free the tmp face
void AAS_FreeTmpFace( tmp_face_t *tmpface );
//allocate a tmp area
tmp_area_t *AAS_AllocTmpArea( void );
//free a tmp area
void AAS_FreeTmpArea( tmp_area_t *tmparea );
//allocate a tmp node
tmp_node_t *AAS_AllocTmpNode( void );
//free a tmp node
void AAS_FreeTmpNode( tmp_node_t *node );
//checks if an area is ok
void AAS_CheckArea( tmp_area_t *tmparea );
//flips the area faces where needed
void AAS_FlipAreaFaces( tmp_area_t *tmparea );
//returns true if the face is a gap seen from the given side
int AAS_GapFace( tmp_face_t *tmpface, int side );
//returns true if the face is a ground face
int AAS_GroundFace( tmp_face_t *tmpface );

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