as released 2010-08-12
This commit is contained in:
commit
3d8bca1749
|
@ -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 RETURN TO CASTLE WOLFENSTEIN SINGLE PLAYER GPL SOURCE CODE.
|
||||
|
||||
The following additional terms (“Additional Terms”) supplement and modify the GNU General Public License, Version 3 (“GPL”) applicable to the Return to Castle Wolfenstein single player GPL Source Code (“RTCW SP Source Code”). In addition to the terms and conditions of the GPL, the RTCW SP 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 party’s 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.
|
|
@ -0,0 +1,133 @@
|
|||
Return to Castle Wolfenstein single player GPL source release
|
||||
=============================================================
|
||||
|
||||
This file contains the following sections:
|
||||
|
||||
GENERAL NOTES
|
||||
LICENSE
|
||||
|
||||
GENERAL NOTES
|
||||
=============
|
||||
|
||||
Game data and patching:
|
||||
-----------------------
|
||||
|
||||
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.
|
||||
|
||||
You must patch the game to the latest version.
|
||||
|
||||
Note that RTCW is available from the Steam store at
|
||||
http://store.steampowered.com/app/9010/
|
||||
|
||||
Linux note: due to the game CD containing only a Windows version of the game,
|
||||
you must install and update the game using WINE 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++.
|
||||
|
||||
You will need to execute src\extractfuncs\extractfuncs.bat to generate src\game\g_save.c
|
||||
|
||||
You can test your binaries by replacing WolfSP.exe, qagamex86.dll, cgamex86.dll, uix86.dll at the top of the RTCW install
|
||||
|
||||
Compiling on GNU/Linux x86:
|
||||
---------------------------
|
||||
|
||||
Go to the src/unix directory, and run the cons script
|
||||
(cons is a perl based precursor to scons, this is what we were using at the time)
|
||||
|
||||
Run ./cons -h to review build options. Use ./cons -- release to compile in release mode.
|
||||
|
||||
If 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 Return to Castle Wolfenstein single player 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 RTCW SP 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 Return to Castle Wolfenstein single player 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.
|
||||
|
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_VALIDFILEFIELD 15 // text must be valid for use in a dos filename
|
||||
|
||||
#define ITEM_ALIGN_LEFT 0 // left alignment
|
||||
#define ITEM_ALIGN_CENTER 1 // center alignment
|
||||
#define ITEM_ALIGN_RIGHT 2 // right 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_PICKSPAWN 0x11 // NERVE - SMF - wolf mp pick spawn point
|
||||
|
||||
// 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_TEXTASINT 0x00200000
|
||||
#define CG_SHOW_HIGHLIGHTED 0x00100000
|
||||
|
||||
#define CG_SHOW_NOT_V_BINOC 0x00200000 //----(SA) added // hide on binoc huds
|
||||
#define CG_SHOW_NOT_V_SNIPER 0x00400000 //----(SA) added // hide on sniper 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_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
|
||||
|
||||
// font types
|
||||
#define UI_FONT_DEFAULT 0 // auto-chose betwen big/reg/small
|
||||
#define UI_FONT_NORMAL 1
|
||||
#define UI_FONT_BIG 2
|
||||
#define UI_FONT_SMALL 3
|
||||
#define UI_FONT_HANDWRITING 4
|
||||
|
||||
// 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_LOCATION 9
|
||||
#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_PLAYER_LOCATION 33
|
||||
#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_ARMOR 40
|
||||
#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_HOLDABLE 76
|
||||
#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_NEWMESSAGE 82 // 'you got mail!' //----(SA) added
|
||||
|
||||
#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_SKILL 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_GLINFO 249
|
||||
#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_MENUMODEL 257
|
||||
#define UI_SAVEGAME_SHOT 258
|
||||
|
||||
// NERVE - SMF
|
||||
#define UI_LIMBOCHAT 259
|
||||
// -NERVE - SMF
|
||||
|
||||
#define UI_LEVELSHOT 260
|
||||
#define UI_LOADSTATUSBAR 261
|
||||
#define UI_SAVEGAMENAME 262
|
||||
#define UI_SAVEGAMEINFO 263
|
||||
|
||||
#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_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_GARAND 7
|
||||
#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
|
||||
// -NERVE - SMF
|
|
@ -0,0 +1,3 @@
|
|||
# nasty ugly to get build system working from Anjuta
|
||||
all:
|
||||
cd unix && (if [ `hostname` == antares ] ; then (./pcons-2.3.1 -j4) ; else ./cons ; fi)
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_chat.h
|
||||
*
|
||||
* desc: Quake3 bot AI
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//
|
||||
int BotChat_EnterGame( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_ExitGame( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_StartLevel( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_EndLevel( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_HitTalking( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_HitNoDeath( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_HitNoKill( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_Death( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_Kill( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_EnemySuicide( bot_state_t *bs );
|
||||
//
|
||||
int BotChat_Random( bot_state_t *bs );
|
||||
// time the selected chat takes to type in
|
||||
float BotChatTime( bot_state_t *bs );
|
||||
// returns true if the bot can chat at the current position
|
||||
int BotValidChatPosition( bot_state_t *bs );
|
||||
// test the initial bot chats
|
||||
void BotChatTest( bot_state_t *bs );
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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: Quake3 bot AI
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
int BotMatchMessage( bot_state_t *bs, char *message );
|
||||
void BotPrintTeamGoal( bot_state_t *bs );
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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.h
|
||||
*
|
||||
* desc: Quake3 bot AI
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define MAX_NODESWITCHES 50
|
||||
|
||||
void AIEnter_Intermission( bot_state_t *bs );
|
||||
void AIEnter_Observer( bot_state_t *bs );
|
||||
void AIEnter_Respawn( bot_state_t *bs );
|
||||
void AIEnter_Stand( bot_state_t *bs );
|
||||
void AIEnter_Seek_ActivateEntity( bot_state_t *bs );
|
||||
void AIEnter_Seek_NBG( bot_state_t *bs );
|
||||
void AIEnter_Seek_LTG( bot_state_t *bs );
|
||||
void AIEnter_Seek_Camp( bot_state_t *bs );
|
||||
void AIEnter_Battle_Fight( bot_state_t *bs );
|
||||
void AIEnter_Battle_Chase( bot_state_t *bs );
|
||||
void AIEnter_Battle_Retreat( bot_state_t *bs );
|
||||
void AIEnter_Battle_NBG( bot_state_t *bs );
|
||||
int AINode_Intermission( bot_state_t *bs );
|
||||
int AINode_Observer( bot_state_t *bs );
|
||||
int AINode_Respawn( bot_state_t *bs );
|
||||
int AINode_Stand( bot_state_t *bs );
|
||||
int AINode_Seek_ActivateEntity( bot_state_t *bs );
|
||||
int AINode_Seek_NBG( bot_state_t *bs );
|
||||
int AINode_Seek_LTG( bot_state_t *bs );
|
||||
int AINode_Battle_Fight( bot_state_t *bs );
|
||||
int AINode_Battle_Chase( bot_state_t *bs );
|
||||
int AINode_Battle_Retreat( bot_state_t *bs );
|
||||
int AINode_Battle_NBG( bot_state_t *bs );
|
||||
|
||||
void BotResetNodeSwitches( void );
|
||||
void BotDumpNodeSwitches( bot_state_t *bs );
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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: Quake3 bot AI
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//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 );
|
||||
//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 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 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 );
|
||||
//returns true and sets the .enemy field when an enemy is found
|
||||
int BotFindEnemy( bot_state_t *bs, int curenemy );
|
||||
//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 );
|
||||
//the bot will aim at the current enemy
|
||||
void BotAimAtEnemy( bot_state_t *bs );
|
||||
//check if the bot should attack
|
||||
void BotCheckAttack( bot_state_t *bs );
|
||||
//AI when the bot is blocked
|
||||
void BotAIBlocked( bot_state_t *bs, bot_moveresult_t *moveresult, int activate );
|
||||
//returns the CTF team the bot is in
|
||||
int BotCTFTeam( bot_state_t *bs );
|
||||
//returns the flag the bot is carrying (CTFFLAG_?)
|
||||
int BotCTFCarryingFlag( bot_state_t *bs );
|
||||
//set ctf goals (defend base, get enemy flag) during seek
|
||||
void BotCTFSeekGoals( bot_state_t *bs );
|
||||
//set ctf goals (defend base, get enemy flag) during retreat
|
||||
void BotCTFRetreatGoals( bot_state_t *bs );
|
||||
//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 );
|
||||
//returns the number of the client with the given name
|
||||
int ClientFromName( char *name );
|
||||
//
|
||||
int BotPointAreaNum( vec3_t origin );
|
||||
//
|
||||
void BotMapScripts( bot_state_t *bs );
|
||||
|
||||
//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_RED 1
|
||||
#define CTF_TEAM_BLUE 2
|
||||
|
||||
extern int dmflags; //deathmatch flags
|
||||
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;
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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: Quake3 bot AI
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
//#define DEBUG
|
||||
#define CTF
|
||||
|
||||
#define MAX_ITEMS 256
|
||||
//bot flags
|
||||
#define BFL_STRAFERIGHT 1 //strafe to the right
|
||||
#define BFL_ATTACKED 2 //bot has attacked last ai frame
|
||||
#define BFL_ATTACKJUMPED 4 //bot jumped during attack last frame
|
||||
#define BFL_AIMATENEMY 8 //bot aimed at the enemy this frame
|
||||
#define BFL_AVOIDRIGHT 16 //avoid obstacles by going to the right
|
||||
#define BFL_IDEALVIEWSET 32 //bot has ideal view angles set
|
||||
//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
|
||||
|
||||
//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;
|
||||
|
||||
//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
|
||||
float thinktime; //time the bot thinks this frame
|
||||
vec3_t origin; //origin of the bot
|
||||
vec3_t velocity; //velocity of the bot
|
||||
int presencetype; //presence type of the bot
|
||||
vec3_t eye; //eye coordinates of the bot
|
||||
int areanum; //the number of the area the bot is in
|
||||
int inventory[MAX_ITEMS]; //string with items amounts the bot has
|
||||
int tfl; //the travel flags the bot uses
|
||||
int flags; //several flags
|
||||
int respawn_wait; //wait until respawned
|
||||
int lasthealth; //health value previous frame
|
||||
int lastkilledplayer; //last killed player
|
||||
int lastkilledby; //player that last killed this bot
|
||||
int botdeathtype; //the death type of the bot
|
||||
int enemydeathtype; //the death type of the enemy
|
||||
int botsuicide; //true when the bot suicides
|
||||
int enemysuicide; //true when the enemy of the bot suicides
|
||||
int setupcount; //true when the bot has just been setup
|
||||
int entergamechat; //true when the bot used an enter game chat
|
||||
int num_deaths; //number of time this bot died
|
||||
int num_kills; //number of kills of this bot
|
||||
int revenge_enemy; //the revenge enemy
|
||||
int revenge_kills; //number of kills the enemy made
|
||||
int lastframe_health; //health value the last frame
|
||||
int lasthitcount; //number of hits last frame
|
||||
int chatto; //chat to all or team
|
||||
float walker; //walker charactertic
|
||||
float ltime; //local bot time
|
||||
float entergame_time; //time the bot entered the game
|
||||
float ltg_time; //long term goal time
|
||||
float nbg_time; //nearby goal time
|
||||
float respawn_time; //time the bot takes to respawn
|
||||
float respawnchat_time; //time the bot started a chat during respawn
|
||||
float chase_time; //time the bot will chase the enemy
|
||||
float enemyvisible_time; //time the enemy was last visible
|
||||
float check_time; //time to check for nearby items
|
||||
float stand_time; //time the bot is standing still
|
||||
float lastchat_time; //time the bot last selected a chat
|
||||
float standfindenemy_time; //time to find enemy while standing
|
||||
float attackstrafe_time; //time the bot is strafing in one dir
|
||||
float attackcrouch_time; //time the bot will stop crouching
|
||||
float attackchase_time; //time the bot chases during actual attack
|
||||
float attackjump_time; //time the bot jumped during attack
|
||||
float enemysight_time; //time before reacting to enemy
|
||||
float enemydeath_time; //time the enemy died
|
||||
float enemyposition_time; //time the position and velocity of the enemy were stored
|
||||
float activate_time; //time to activate something
|
||||
float activatemessage_time; //time to show activate message
|
||||
float defendaway_time; //time away while defending
|
||||
float defendaway_range; //max travel time away from defend area
|
||||
float rushbaseaway_time; //time away from rushing to the base
|
||||
float ctfroam_time; //time the bot is roaming in ctf
|
||||
float killedenemy_time; //time the bot killed the enemy
|
||||
float arrive_time; //time arrived (at companion)
|
||||
float lastair_time; //last time the bot had air
|
||||
float teleport_time; //last time the bot teleported
|
||||
float camp_time; //last time camped
|
||||
float camp_range; //camp range
|
||||
float weaponchange_time; //time the bot started changing weapons
|
||||
float firethrottlewait_time; //amount of time to wait
|
||||
float firethrottleshoot_time; //amount of time to shoot
|
||||
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
|
||||
//
|
||||
int lead_teammate; //team mate the bot is leading
|
||||
bot_goal_t lead_teamgoal; //team goal while leading
|
||||
float lead_time; //time leading someone
|
||||
float leadvisible_time; //last time the team mate was visible
|
||||
float leadmessage_time; //last time a messaged was sent to the team mate
|
||||
float leadbackup_time; //time backing up towards team mate
|
||||
//
|
||||
char teamleader[32]; //netname of the team leader
|
||||
float askteamleader_time; //time asked for team leader
|
||||
float becometeamleader_time; //time the bot will become the team leader
|
||||
float teamgiveorders_time; //time to give team orders
|
||||
int numteammates; //number of team mates
|
||||
int redflagstatus; //0 = at base, 1 = not at base
|
||||
int blueflagstatus; //0 = at base, 1 = not at base
|
||||
int flagstatuschanged; //flag status changed
|
||||
int forceorders; //true if forced to give orders
|
||||
int flagcarrier; //team mate carrying the enemy flag
|
||||
char subteam[32]; //sub team name
|
||||
float formation_dist; //formation team mate intervening space
|
||||
char formation_teammate[16]; //netname of the team mate the bot uses for relative positioning
|
||||
float formation_angle; //angle relative to the formation team mate
|
||||
vec3_t formation_dir; //the direction the formation is moving in
|
||||
vec3_t formation_origin; //origin the bot uses for relative positioning
|
||||
bot_goal_t formation_goal; //formation goal
|
||||
bot_goal_t activategoal; //goal to activate (buttons etc.)
|
||||
bot_waypoint_t *checkpoints; //check points
|
||||
bot_waypoint_t *patrolpoints; //patrol points
|
||||
bot_waypoint_t *curpatrolpoint; //current patrol point the bot is going for
|
||||
int patrolflags; //patrol flags
|
||||
} bot_state_t;
|
||||
|
||||
//resets the whole bot state
|
||||
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 );
|
||||
|
||||
// Ridah, defines for AI Cast system
|
||||
int AICast_ShutdownClient( int client );
|
||||
void AICast_Init( void );
|
||||
void AICast_StartFrame( int time );
|
||||
// done.
|
||||
|
||||
// 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 );
|
|
@ -0,0 +1,612 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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.c
|
||||
*
|
||||
* desc: Quake3 bot AI
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../game/g_local.h"
|
||||
#include "../game/botlib.h"
|
||||
#include "../game/be_aas.h"
|
||||
#include "../game/be_ea.h"
|
||||
#include "../game/be_ai_char.h"
|
||||
#include "../game/be_ai_chat.h"
|
||||
#include "../game/be_ai_gen.h"
|
||||
#include "../game/be_ai_goal.h"
|
||||
#include "../game/be_ai_move.h"
|
||||
#include "../game/be_ai_weap.h"
|
||||
#include "../botai/botai.h"
|
||||
//
|
||||
#include "ai_main.h"
|
||||
#include "ai_dmq3.h"
|
||||
#include "ai_chat.h"
|
||||
#include "ai_cmd.h"
|
||||
#include "ai_dmnet.h"
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
BotValidTeamLeader
|
||||
==================
|
||||
*/
|
||||
int BotValidTeamLeader( bot_state_t *bs ) {
|
||||
if ( !strlen( bs->teamleader ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( ClientFromName( bs->teamleader ) == -1 ) {
|
||||
return qfalse;
|
||||
}
|
||||
return qtrue;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
BotNumTeamMates
|
||||
==================
|
||||
*/
|
||||
int BotNumTeamMates( bot_state_t *bs ) {
|
||||
int i, numplayers;
|
||||
char buf[MAX_INFO_STRING];
|
||||
static int maxclients;
|
||||
|
||||
if ( !maxclients ) {
|
||||
maxclients = trap_Cvar_VariableIntegerValue( "sv_maxclients" );
|
||||
}
|
||||
|
||||
numplayers = 0;
|
||||
for ( i = 0; i < maxclients && i < MAX_CLIENTS; i++ ) {
|
||||
trap_GetConfigstring( CS_PLAYERS + i, buf, sizeof( buf ) );
|
||||
//if no config string or no name
|
||||
if ( !strlen( buf ) || !strlen( Info_ValueForKey( buf, "n" ) ) ) {
|
||||
continue;
|
||||
}
|
||||
//skip spectators
|
||||
if ( atoi( Info_ValueForKey( buf, "t" ) ) == TEAM_SPECTATOR ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if ( BotSameTeam( bs, i ) ) {
|
||||
numplayers++;
|
||||
}
|
||||
}
|
||||
return numplayers;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
BotClientTravelTimeToGoal
|
||||
==================
|
||||
*/
|
||||
int BotClientTravelTimeToGoal( int client, bot_goal_t *goal ) {
|
||||
playerState_t ps;
|
||||
int areanum;
|
||||
|
||||
BotAI_GetClientState( client, &ps );
|
||||
areanum = BotPointAreaNum( ps.origin );
|
||||
if ( !areanum ) {
|
||||
return 1;
|
||||
}
|
||||
return trap_AAS_AreaTravelTimeToGoalArea( areanum, ps.origin, goal->areanum, TFL_DEFAULT );
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
BotSortTeamMatesByBaseTravelTime
|
||||
==================
|
||||
*/
|
||||
int BotSortTeamMatesByBaseTravelTime( bot_state_t *bs, int *teammates, int maxteammates ) {
|
||||
|
||||
int i, j, k, numteammates, traveltime;
|
||||
char buf[MAX_INFO_STRING];
|
||||
static int maxclients;
|
||||
int traveltimes[MAX_CLIENTS];
|
||||
bot_goal_t *goal;
|
||||
|
||||
if ( BotCTFTeam( bs ) == CTF_TEAM_RED ) {
|
||||
goal = &ctf_redflag;
|
||||
} else { goal = &ctf_blueflag;}
|
||||
|
||||
if ( !maxclients ) {
|
||||
maxclients = trap_Cvar_VariableIntegerValue( "sv_maxclients" );
|
||||
}
|
||||
|
||||
numteammates = 0;
|
||||
for ( i = 0; i < maxclients && i < MAX_CLIENTS; i++ ) {
|
||||
trap_GetConfigstring( CS_PLAYERS + i, buf, sizeof( buf ) );
|
||||
//if no config string or no name
|
||||
if ( !strlen( buf ) || !strlen( Info_ValueForKey( buf, "n" ) ) ) {
|
||||
continue;
|
||||
}
|
||||
//skip spectators
|
||||
if ( atoi( Info_ValueForKey( buf, "t" ) ) == TEAM_SPECTATOR ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
if ( BotSameTeam( bs, i ) ) {
|
||||
//
|
||||
traveltime = BotClientTravelTimeToGoal( i, goal );
|
||||
//
|
||||
for ( j = 0; j < numteammates; j++ ) {
|
||||
if ( traveltime < traveltimes[j] ) {
|
||||
for ( k = numteammates; k > j; k-- ) {
|
||||
traveltimes[k] = traveltimes[k - 1];
|
||||
teammates[k] = teammates[k - 1];
|
||||
}
|
||||
traveltimes[j] = traveltime;
|
||||
teammates[j] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j >= numteammates ) {
|
||||
traveltimes[j] = traveltime;
|
||||
teammates[j] = i;
|
||||
}
|
||||
numteammates++;
|
||||
if ( numteammates >= maxteammates ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return numteammates;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
BotSayTeamOrders
|
||||
==================
|
||||
*/
|
||||
void BotSayTeamOrder( bot_state_t *bs, int toclient ) {
|
||||
char teamchat[MAX_MESSAGE_SIZE];
|
||||
char buf[MAX_MESSAGE_SIZE];
|
||||
char name[MAX_NETNAME];
|
||||
|
||||
//if the bot is talking to itself
|
||||
if ( bs->client == toclient ) {
|
||||
//don't show the message just put it in the console message queue
|
||||
trap_BotGetChatMessage( bs->cs, buf, sizeof( buf ) );
|
||||
ClientName( bs->client, name, sizeof( name ) );
|
||||
Com_sprintf( teamchat, sizeof( teamchat ), "(%s): %s", name, buf );
|
||||
trap_BotQueueConsoleMessage( bs->cs, CMS_CHAT, teamchat );
|
||||
} else {
|
||||
trap_BotEnterChat( bs->cs, bs->client, CHAT_TEAM );
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
BotCTFOrders
|
||||
==================
|
||||
*/
|
||||
void BotCTFOrders_BothFlagsNotAtBase( bot_state_t *bs ) {
|
||||
int numteammates, defenders, attackers, i, other;
|
||||
int teammates[MAX_CLIENTS];
|
||||
char name[MAX_NETNAME], carriername[MAX_NETNAME];
|
||||
|
||||
numteammates = BotSortTeamMatesByBaseTravelTime( bs, teammates, sizeof( teammates ) );
|
||||
//different orders based on the number of team mates
|
||||
switch ( bs->numteammates ) {
|
||||
case 1: break;
|
||||
case 2:
|
||||
{
|
||||
//tell the one not carrying the flag to attack the enemy base
|
||||
if ( teammates[0] != bs->flagcarrier ) {
|
||||
other = teammates[0];
|
||||
} else { other = teammates[1];}
|
||||
ClientName( other, name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, other );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
//tell the one closest to the base not carrying the flag to accompany the flag carrier
|
||||
if ( teammates[0] != bs->flagcarrier ) {
|
||||
other = teammates[0];
|
||||
} else { other = teammates[1];}
|
||||
ClientName( other, name, sizeof( name ) );
|
||||
ClientName( bs->flagcarrier, carriername, sizeof( carriername ) );
|
||||
if ( bs->flagcarrier == bs->client ) {
|
||||
BotAI_BotInitialChat( bs, "cmd_accompanyme", name, NULL );
|
||||
} else {
|
||||
BotAI_BotInitialChat( bs, "cmd_accompany", name, carriername, NULL );
|
||||
}
|
||||
BotSayTeamOrder( bs, other );
|
||||
//tell the one furthest from the the base not carrying the flag to get the enemy flag
|
||||
if ( teammates[2] != bs->flagcarrier ) {
|
||||
other = teammates[2];
|
||||
} else { other = teammates[1];}
|
||||
ClientName( other, name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, other );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
defenders = (int) ( float ) numteammates * 0.4 + 0.5;
|
||||
attackers = (int) ( float ) numteammates * 0.5 + 0.5;
|
||||
ClientName( bs->flagcarrier, carriername, sizeof( carriername ) );
|
||||
for ( i = 0; i < defenders; i++ ) {
|
||||
//
|
||||
if ( teammates[i] == bs->flagcarrier ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
ClientName( teammates[i], name, sizeof( name ) );
|
||||
if ( bs->flagcarrier == bs->client ) {
|
||||
BotAI_BotInitialChat( bs, "cmd_accompanyme", name, NULL );
|
||||
} else {
|
||||
BotAI_BotInitialChat( bs, "cmd_accompany", name, carriername, NULL );
|
||||
}
|
||||
BotSayTeamOrder( bs, teammates[i] );
|
||||
}
|
||||
for ( i = 0; i < attackers; i++ ) {
|
||||
//
|
||||
if ( teammates[numteammates - i - 1] == bs->flagcarrier ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
ClientName( teammates[numteammates - i - 1], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[numteammates - i - 1] );
|
||||
}
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
BotCTFOrders
|
||||
==================
|
||||
*/
|
||||
void BotCTFOrders_FlagNotAtBase( bot_state_t *bs ) {
|
||||
int numteammates, defenders, attackers, i;
|
||||
int teammates[MAX_CLIENTS];
|
||||
char name[MAX_NETNAME];
|
||||
|
||||
numteammates = BotSortTeamMatesByBaseTravelTime( bs, teammates, sizeof( teammates ) );
|
||||
//different orders based on the number of team mates
|
||||
switch ( bs->numteammates ) {
|
||||
case 1: break;
|
||||
case 2:
|
||||
{
|
||||
//the one closest to the base will defend the base
|
||||
ClientName( teammates[0], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[0] );
|
||||
//the other will get the flag
|
||||
ClientName( teammates[1], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[1] );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
//the one closest to the base will defend the base
|
||||
ClientName( teammates[0], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[0] );
|
||||
//the other two get the flag
|
||||
ClientName( teammates[1], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[1] );
|
||||
//
|
||||
ClientName( teammates[2], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[2] );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
defenders = (int) ( float ) numteammates * 0.3 + 0.5;
|
||||
attackers = (int) ( float ) numteammates * 0.5 + 0.5;
|
||||
for ( i = 0; i < defenders; i++ ) {
|
||||
//
|
||||
ClientName( teammates[i], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[i] );
|
||||
}
|
||||
for ( i = 0; i < attackers; i++ ) {
|
||||
//
|
||||
ClientName( teammates[numteammates - i - 1], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[numteammates - i - 1] );
|
||||
}
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
BotCTFOrders
|
||||
==================
|
||||
*/
|
||||
void BotCTFOrders_EnemyFlagNotAtBase( bot_state_t *bs ) {
|
||||
int numteammates, defenders, attackers, i, other;
|
||||
int teammates[MAX_CLIENTS];
|
||||
char name[MAX_NETNAME], carriername[MAX_NETNAME];
|
||||
|
||||
numteammates = BotSortTeamMatesByBaseTravelTime( bs, teammates, sizeof( teammates ) );
|
||||
//different orders based on the number of team mates
|
||||
switch ( numteammates ) {
|
||||
case 1: break;
|
||||
case 2:
|
||||
{
|
||||
//tell the one not carrying the flag to defend the base
|
||||
if ( teammates[0] == bs->flagcarrier ) {
|
||||
other = teammates[1];
|
||||
} else { other = teammates[0];}
|
||||
ClientName( other, name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, other );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
//tell the one closest to the base not carrying the flag to defend the base
|
||||
if ( teammates[0] != bs->flagcarrier ) {
|
||||
other = teammates[0];
|
||||
} else { other = teammates[1];}
|
||||
ClientName( other, name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, other );
|
||||
//tell the one furthest from the base not carrying the flag to accompany the flag carrier
|
||||
if ( teammates[2] != bs->flagcarrier ) {
|
||||
other = teammates[2];
|
||||
} else { other = teammates[1];}
|
||||
ClientName( other, name, sizeof( name ) );
|
||||
ClientName( bs->flagcarrier, carriername, sizeof( carriername ) );
|
||||
if ( bs->flagcarrier == bs->client ) {
|
||||
BotAI_BotInitialChat( bs, "cmd_accompanyme", name, NULL );
|
||||
} else {
|
||||
BotAI_BotInitialChat( bs, "cmd_accompany", name, carriername, NULL );
|
||||
}
|
||||
BotSayTeamOrder( bs, other );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
//40% will defend the base
|
||||
defenders = (int) ( float ) numteammates * 0.4 + 0.5;
|
||||
//50% accompanies the flag carrier
|
||||
attackers = (int) ( float ) numteammates * 0.5 + 0.5;
|
||||
for ( i = 0; i < defenders; i++ ) {
|
||||
//
|
||||
if ( teammates[i] == bs->flagcarrier ) {
|
||||
continue;
|
||||
}
|
||||
ClientName( teammates[i], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[i] );
|
||||
}
|
||||
ClientName( bs->flagcarrier, carriername, sizeof( carriername ) );
|
||||
for ( i = 0; i < attackers; i++ ) {
|
||||
//
|
||||
if ( teammates[numteammates - i - 1] == bs->flagcarrier ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
ClientName( teammates[numteammates - i - 1], name, sizeof( name ) );
|
||||
if ( bs->flagcarrier == bs->client ) {
|
||||
BotAI_BotInitialChat( bs, "cmd_accompanyme", name, NULL );
|
||||
} else {
|
||||
BotAI_BotInitialChat( bs, "cmd_accompany", name, carriername, NULL );
|
||||
}
|
||||
BotSayTeamOrder( bs, teammates[numteammates - i - 1] );
|
||||
}
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
BotCTFOrders
|
||||
==================
|
||||
*/
|
||||
void BotCTFOrders_BothFlagsAtBase( bot_state_t *bs ) {
|
||||
int numteammates, defenders, attackers, i;
|
||||
int teammates[MAX_CLIENTS];
|
||||
char name[MAX_NETNAME];
|
||||
// char buf[MAX_MESSAGE_SIZE];
|
||||
|
||||
numteammates = BotSortTeamMatesByBaseTravelTime( bs, teammates, sizeof( teammates ) );
|
||||
//different orders based on the number of team mates
|
||||
switch ( numteammates ) {
|
||||
case 1: break;
|
||||
case 2:
|
||||
{
|
||||
//the one closest to the base will defend the base
|
||||
ClientName( teammates[0], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[0] );
|
||||
//the other will get the flag
|
||||
ClientName( teammates[1], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[1] );
|
||||
break;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
//the one closest to the base will defend the base
|
||||
ClientName( teammates[0], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[0] );
|
||||
//the second one closest to the base will defend the base
|
||||
ClientName( teammates[1], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[1] );
|
||||
//the other will get the flag
|
||||
ClientName( teammates[2], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[2] );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
defenders = (int) ( float ) numteammates * 0.5 + 0.5;
|
||||
attackers = (int) ( float ) numteammates * 0.3 + 0.5;
|
||||
for ( i = 0; i < defenders; i++ ) {
|
||||
//
|
||||
ClientName( teammates[i], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_defendbase", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[i] );
|
||||
}
|
||||
for ( i = 0; i < attackers; i++ ) {
|
||||
//
|
||||
ClientName( teammates[numteammates - i - 1], name, sizeof( name ) );
|
||||
BotAI_BotInitialChat( bs, "cmd_getflag", name, NULL );
|
||||
BotSayTeamOrder( bs, teammates[numteammates - i - 1] );
|
||||
}
|
||||
//
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
BotTeamOrders
|
||||
==================
|
||||
*/
|
||||
void BotTeamOrders( bot_state_t *bs ) {
|
||||
//no teamplay orders at this time
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==================
|
||||
BotTeamAI
|
||||
==================
|
||||
*/
|
||||
void BotTeamAI( bot_state_t *bs ) {
|
||||
int numteammates, flagstatus;
|
||||
char netname[MAX_NETNAME];
|
||||
|
||||
//
|
||||
if ( gametype != GT_TEAM && gametype != GT_CTF ) {
|
||||
return;
|
||||
}
|
||||
//make sure we've got a valid team leader
|
||||
if ( !BotValidTeamLeader( bs ) ) {
|
||||
//
|
||||
if ( !bs->askteamleader_time && !bs->becometeamleader_time ) {
|
||||
if ( bs->entergame_time + 10 > trap_AAS_Time() ) {
|
||||
bs->askteamleader_time = trap_AAS_Time() + 5 + random() * 10;
|
||||
} else {
|
||||
bs->becometeamleader_time = trap_AAS_Time() + 5 + random() * 10;
|
||||
}
|
||||
}
|
||||
if ( bs->askteamleader_time && bs->askteamleader_time < trap_AAS_Time() ) {
|
||||
//if asked for a team leader and no repsonse
|
||||
BotAI_BotInitialChat( bs, "whoisteamleader", NULL );
|
||||
trap_BotEnterChat( bs->cs, bs->client, CHAT_TEAM );
|
||||
bs->askteamleader_time = 0;
|
||||
bs->becometeamleader_time = trap_AAS_Time() + 15 + random() * 10;
|
||||
}
|
||||
if ( bs->becometeamleader_time && bs->becometeamleader_time < trap_AAS_Time() ) {
|
||||
BotAI_BotInitialChat( bs, "iamteamleader", NULL );
|
||||
trap_BotEnterChat( bs->cs, bs->client, CHAT_TEAM );
|
||||
ClientName( bs->client, netname, sizeof( netname ) );
|
||||
strncpy( bs->teamleader, netname, sizeof( bs->teamleader ) );
|
||||
bs->teamleader[sizeof( bs->teamleader )] = '\0';
|
||||
bs->becometeamleader_time = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
bs->askteamleader_time = 0;
|
||||
bs->becometeamleader_time = 0;
|
||||
|
||||
//return if this bot is NOT the team leader
|
||||
ClientName( bs->client, netname, sizeof( netname ) );
|
||||
if ( Q_stricmp( netname, bs->teamleader ) != 0 ) {
|
||||
return;
|
||||
}
|
||||
//
|
||||
//if the game starts OR a new player comes onto the team OR a player leaves the team
|
||||
//
|
||||
numteammates = BotNumTeamMates( bs );
|
||||
//give orders
|
||||
switch ( gametype ) {
|
||||
case GT_TEAM:
|
||||
{
|
||||
if ( bs->numteammates != numteammates || bs->forceorders ) {
|
||||
bs->teamgiveorders_time = trap_AAS_Time();
|
||||
bs->numteammates = numteammates;
|
||||
bs->forceorders = qfalse;
|
||||
}
|
||||
//if it's time to give orders
|
||||
if ( bs->teamgiveorders_time < trap_AAS_Time() - 5 ) {
|
||||
BotTeamOrders( bs );
|
||||
//
|
||||
bs->teamgiveorders_time = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GT_CTF:
|
||||
{
|
||||
//
|
||||
if ( bs->numteammates != numteammates || bs->flagstatuschanged || bs->forceorders ) {
|
||||
bs->teamgiveorders_time = trap_AAS_Time();
|
||||
bs->numteammates = numteammates;
|
||||
bs->flagstatuschanged = qfalse;
|
||||
bs->forceorders = qfalse;
|
||||
}
|
||||
//if it's time to give orders
|
||||
if ( bs->teamgiveorders_time && bs->teamgiveorders_time < trap_AAS_Time() - 3 ) {
|
||||
//
|
||||
if ( BotCTFTeam( bs ) == CTF_TEAM_RED ) {
|
||||
flagstatus = bs->redflagstatus * 2 + bs->blueflagstatus;
|
||||
} else { flagstatus = bs->blueflagstatus * 2 + bs->redflagstatus;}
|
||||
//
|
||||
switch ( flagstatus ) {
|
||||
case 0: BotCTFOrders_BothFlagsAtBase( bs ); break;
|
||||
case 1: BotCTFOrders_EnemyFlagNotAtBase( bs ); break;
|
||||
case 2: BotCTFOrders_FlagNotAtBase( bs ); break;
|
||||
case 3: BotCTFOrders_BothFlagsNotAtBase( bs ); break;
|
||||
}
|
||||
//
|
||||
bs->teamgiveorders_time = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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: Quake3 bot AI
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
void BotTeamAI( bot_state_t *bs );
|
||||
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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( void );
|
||||
void trap_BotFreeClient( int clientNum );
|
||||
*/
|
|
@ -0,0 +1,150 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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: Mr Elusive (MrElusive@idsoftware.com)
|
||||
// Last update: 1999-09-08
|
||||
// Tab Size: 4 (real tabs)
|
||||
//===========================================================================
|
||||
|
||||
|
||||
//========================================================
|
||||
//========================================================
|
||||
//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_LIGHTNING 12
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_SP5 13 //float [0, 1]
|
||||
#define CHARACTERISTIC_AIM_ACCURACY_RAILGUN 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]
|
||||
//========================================================
|
||||
//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]
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_MAUSER 5
|
||||
#define INVENTORY_MP40 6
|
||||
#define INVENTORY_SP5 7
|
||||
#define INVENTORY_ROCKETLAUNCHER 8
|
||||
#define INVENTORY_GRENADELAUNCHER 9
|
||||
#define INVENTORY_VENOM 10
|
||||
#define INVENTORY_FLAMETHROWER 11
|
||||
#define INVENTORY_CROSS 12
|
||||
|
||||
#define INVENTORY_GAUNTLET 13
|
||||
|
||||
|
||||
// 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_792MM 28
|
||||
#define INVENTORY_SP5AMMO 29
|
||||
#define INVENTORY_ROCKETS 30
|
||||
#define INVENTORY_GRENADES 31
|
||||
#define INVENTORY_127MM 32
|
||||
#define INVENTORY_FUEL 33
|
||||
#define INVENTORY_CHARGES 34
|
||||
|
||||
// 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_MEDKIT 50
|
||||
#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
|
||||
|
||||
//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
|
||||
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
|
@ -0,0 +1,276 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_USEFORROUTING 1024
|
||||
|
||||
//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
|
||||
*/
|
|
@ -0,0 +1,193 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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.h
|
||||
*
|
||||
* desc: Area Awareness System, stuff exported to the AI
|
||||
*
|
||||
* $Archive: /Wolf4/src/botlib/be_aas.h $
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#define MAX_AAS_WORLDS 2 // one for each bounding box type
|
||||
|
||||
#ifndef MAX_STRINGFIELD
|
||||
#define MAX_STRINGFIELD 80
|
||||
#endif
|
||||
|
||||
//travel flags
|
||||
#define TFL_INVALID 0x0000001 //traveling temporary not possible
|
||||
#define TFL_WALK 0x0000002 //walking
|
||||
#define TFL_CROUCH 0x0000004 //crouching
|
||||
#define TFL_BARRIERJUMP 0x0000008 //jumping onto a barrier
|
||||
#define TFL_JUMP 0x0000010 //jumping
|
||||
#define TFL_LADDER 0x0000020 //climbing a ladder
|
||||
#define TFL_WALKOFFLEDGE 0x0000080 //walking of a ledge
|
||||
#define TFL_SWIM 0x0000100 //swimming
|
||||
#define TFL_WATERJUMP 0x0000200 //jumping out of the water
|
||||
#define TFL_TELEPORT 0x0000400 //teleporting
|
||||
#define TFL_ELEVATOR 0x0000800 //elevator
|
||||
#define TFL_ROCKETJUMP 0x0001000 //rocket jumping
|
||||
#define TFL_BFGJUMP 0x0002000 //bfg jumping
|
||||
#define TFL_GRAPPLEHOOK 0x0004000 //grappling hook
|
||||
#define TFL_DOUBLEJUMP 0x0008000 //double jump
|
||||
#define TFL_RAMPJUMP 0x0010000 //ramp jump
|
||||
#define TFL_STRAFEJUMP 0x0020000 //strafe jump
|
||||
#define TFL_JUMPPAD 0x0040000 //jump pad
|
||||
#define TFL_AIR 0x0080000 //travel through air
|
||||
#define TFL_WATER 0x0100000 //travel through water
|
||||
#define TFL_SLIME 0x0200000 //travel through slime
|
||||
#define TFL_LAVA 0x0400000 //travel through lava
|
||||
#define TFL_DONOTENTER 0x0800000 //travel through donotenter area
|
||||
#define TFL_FUNCBOB 0x1000000 //func bobbing
|
||||
#define TFL_DONOTENTER_LARGE 0x2000000 //travel through donotenter area
|
||||
|
||||
//default travel flags
|
||||
|
||||
//----(SA) modified since slime is no longer deadly
|
||||
#define TFL_DEFAULT TFL_WALK | TFL_CROUCH | TFL_BARRIERJUMP | \
|
||||
TFL_JUMP | TFL_LADDER | \
|
||||
TFL_WALKOFFLEDGE | TFL_SWIM | TFL_WATERJUMP | \
|
||||
TFL_TELEPORT | TFL_ELEVATOR | TFL_AIR | \
|
||||
TFL_WATER | TFL_SLIME | \
|
||||
TFL_JUMPPAD | TFL_FUNCBOB
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SOLID_NOT, // no interaction with other objects
|
||||
SOLID_TRIGGER, // only touch when inside, after moving
|
||||
SOLID_BBOX, // touch on edge
|
||||
SOLID_BSP // bsp clip, touch on edge
|
||||
} solid_t;
|
||||
|
||||
//a trace is returned when a box is swept through the AAS world
|
||||
typedef struct aas_trace_s
|
||||
{
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
int ent; // entity blocking the trace
|
||||
int lastarea; // last area the trace was in (zero if none)
|
||||
int area; // area blocking the trace (zero if none)
|
||||
int planenum; // number of the plane that was hit
|
||||
} aas_trace_t;
|
||||
|
||||
/* Defined in botlib.h
|
||||
|
||||
//bsp_trace_t hit surface
|
||||
typedef struct bsp_surface_s
|
||||
{
|
||||
char name[16];
|
||||
int flags;
|
||||
int value;
|
||||
} bsp_surface_t;
|
||||
|
||||
//a trace is returned when a box is swept through the BSP world
|
||||
typedef struct bsp_trace_s
|
||||
{
|
||||
qboolean allsolid; // if true, plane is not valid
|
||||
qboolean startsolid; // if true, the initial point was in a solid area
|
||||
float fraction; // time completed, 1.0 = didn't hit anything
|
||||
vec3_t endpos; // final position
|
||||
cplane_t plane; // surface normal at impact
|
||||
float exp_dist; // expanded plane distance
|
||||
int sidenum; // number of the brush side hit
|
||||
bsp_surface_t surface; // hit surface
|
||||
int contents; // contents on other side of surface hit
|
||||
int ent; // number of entity hit
|
||||
} bsp_trace_t;
|
||||
//
|
||||
*/
|
||||
|
||||
//entity info
|
||||
typedef struct aas_entityinfo_s
|
||||
{
|
||||
int valid; // true if updated this frame
|
||||
int type; // entity type
|
||||
int flags; // entity flags
|
||||
float ltime; // local time
|
||||
float update_time; // time between last and current update
|
||||
int number; // number of the entity
|
||||
vec3_t origin; // origin of the entity
|
||||
vec3_t angles; // angles of the model
|
||||
vec3_t old_origin; // for lerping
|
||||
vec3_t lastvisorigin; // last visible origin
|
||||
vec3_t mins; // bounding box minimums
|
||||
vec3_t maxs; // bounding box maximums
|
||||
int groundent; // ground entity
|
||||
int solid; // solid type
|
||||
int modelindex; // model used
|
||||
int modelindex2; // weapons, CTF flags, etc
|
||||
int frame; // model frame number
|
||||
int event; // impulse events -- muzzle flashes, footsteps, etc
|
||||
int eventParm; // even parameter
|
||||
int powerups; // bit flags
|
||||
int weapon; // determines weapon and flash model, etc
|
||||
int legsAnim; // mask off ANIM_TOGGLEBIT
|
||||
int torsoAnim; // mask off ANIM_TOGGLEBIT
|
||||
// int weapAnim; // mask off ANIM_TOGGLEBIT //----(SA) added
|
||||
//----(SA) didn't want to comment in as I wasn't sure of any implications of changing this structure.
|
||||
} aas_entityinfo_t;
|
||||
|
||||
|
||||
//client movement prediction stop events, stop as soon as:
|
||||
#define SE_NONE 0
|
||||
#define SE_HITGROUND 1 // the ground is hit
|
||||
#define SE_LEAVEGROUND 2 // there's no ground
|
||||
#define SE_ENTERWATER 4 // water is entered
|
||||
#define SE_ENTERSLIME 8 // slime is entered
|
||||
#define SE_ENTERLAVA 16 // lava is entered
|
||||
#define SE_HITGROUNDDAMAGE 32 // the ground is hit with damage
|
||||
#define SE_GAP 64 // there's a gap
|
||||
#define SE_TOUCHJUMPPAD 128 // touching a jump pad area
|
||||
#define SE_TOUCHTELEPORTER 256 // touching teleporter
|
||||
#define SE_ENTERAREA 512 // the given stoparea is entered
|
||||
#define SE_HITGROUNDAREA 1024 // a ground face in the area is hit
|
||||
|
||||
typedef struct aas_clientmove_s
|
||||
{
|
||||
vec3_t endpos; //position at the end of movement prediction
|
||||
vec3_t velocity; //velocity at the end of movement prediction
|
||||
aas_trace_t trace; //last trace
|
||||
int presencetype; //presence type at end of movement prediction
|
||||
int stopevent; //event that made the prediction stop
|
||||
float endcontents; //contents at the end of movement prediction
|
||||
float time; //time predicted ahead
|
||||
int frames; //number of frames predicted ahead
|
||||
} aas_clientmove_t;
|
||||
|
||||
typedef struct aas_altroutegoal_s
|
||||
{
|
||||
vec3_t origin;
|
||||
int areanum;
|
||||
unsigned short starttraveltime;
|
||||
unsigned short goaltraveltime;
|
||||
unsigned short extratraveltime;
|
||||
} aas_altroutegoal_t;
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
|
|
@ -0,0 +1,525 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 2048
|
||||
|
||||
typedef struct rgb_s
|
||||
{
|
||||
int red;
|
||||
int green;
|
||||
int blue;
|
||||
} rgb_t;
|
||||
|
||||
//bsp entity epair
|
||||
typedef struct bsp_epair_s
|
||||
{
|
||||
char *key;
|
||||
char *value;
|
||||
struct bsp_epair_s *next;
|
||||
} bsp_epair_t;
|
||||
|
||||
//bsp data entity
|
||||
typedef struct bsp_entity_s
|
||||
{
|
||||
bsp_epair_t *epairs;
|
||||
} bsp_entity_t;
|
||||
|
||||
//id Sofware BSP data
|
||||
typedef struct bsp_s
|
||||
{
|
||||
//true when bsp file is loaded
|
||||
int loaded;
|
||||
//entity data
|
||||
int entdatasize;
|
||||
char *dentdata;
|
||||
//bsp entities
|
||||
int numentities;
|
||||
bsp_entity_t entities[MAX_BSPENTITIES];
|
||||
//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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
void AAS_SetViewPortalsAsClusterPortals( void );
|
||||
#endif //AASINTERN
|
||||
|
|
@ -0,0 +1,692 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
#define MAX_DEBUGPOLYGONS 128
|
||||
|
||||
int debuglines[MAX_DEBUGLINES];
|
||||
int debuglinevisible[MAX_DEBUGLINES];
|
||||
int numdebuglines;
|
||||
|
||||
static int debugpolygons[MAX_DEBUGPOLYGONS];
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ClearShownPolygons( void ) {
|
||||
int i;
|
||||
//*
|
||||
for ( i = 0; i < MAX_DEBUGPOLYGONS; i++ )
|
||||
{
|
||||
if ( debugpolygons[i] ) {
|
||||
botimport.DebugPolygonDelete( debugpolygons[i] );
|
||||
}
|
||||
debugpolygons[i] = 0;
|
||||
} //end for
|
||||
//*/
|
||||
/*
|
||||
for (i = 0; i < MAX_DEBUGPOLYGONS; i++)
|
||||
{
|
||||
botimport.DebugPolygonDelete(i);
|
||||
debugpolygons[i] = 0;
|
||||
} //end for
|
||||
*/
|
||||
} //end of the function AAS_ClearShownPolygons
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowPolygon( int color, int numpoints, vec3_t *points ) {
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < MAX_DEBUGPOLYGONS; i++ )
|
||||
{
|
||||
if ( !debugpolygons[i] ) {
|
||||
debugpolygons[i] = botimport.DebugPolygonCreate( color, numpoints, points );
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function AAS_ShowPolygon
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ClearShownDebugLines( void ) {
|
||||
int i;
|
||||
|
||||
//make all lines invisible
|
||||
for ( i = 0; i < MAX_DEBUGLINES; i++ )
|
||||
{
|
||||
if ( debuglines[i] ) {
|
||||
//botimport.DebugLineShow(debuglines[i], NULL, NULL, LINECOLOR_NONE);
|
||||
botimport.DebugLineDelete( debuglines[i] );
|
||||
debuglines[i] = 0;
|
||||
debuglinevisible[i] = qfalse;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function AAS_ClearShownDebugLines
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DebugLine( vec3_t start, vec3_t end, int color ) {
|
||||
int line;
|
||||
|
||||
for ( line = 0; line < MAX_DEBUGLINES; line++ )
|
||||
{
|
||||
if ( !debuglines[line] ) {
|
||||
debuglines[line] = botimport.DebugLineCreate();
|
||||
debuglinevisible[line] = qfalse;
|
||||
numdebuglines++;
|
||||
} //end if
|
||||
if ( !debuglinevisible[line] ) {
|
||||
botimport.DebugLineShow( debuglines[line], start, end, color );
|
||||
debuglinevisible[line] = qtrue;
|
||||
return;
|
||||
} //end else
|
||||
} //end for
|
||||
} //end of the function AAS_DebugLine
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PermanentLine( vec3_t start, vec3_t end, int color ) {
|
||||
int line;
|
||||
|
||||
line = botimport.DebugLineCreate();
|
||||
botimport.DebugLineShow( line, start, end, color );
|
||||
} //end of the function AAS_PermenentLine
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DrawPermanentCross( vec3_t origin, float size, int color ) {
|
||||
int i, debugline;
|
||||
vec3_t start, end;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
VectorCopy( origin, start );
|
||||
start[i] += size;
|
||||
VectorCopy( origin, end );
|
||||
end[i] -= size;
|
||||
AAS_DebugLine( start, end, color );
|
||||
debugline = botimport.DebugLineCreate();
|
||||
botimport.DebugLineShow( debugline, start, end, color );
|
||||
} //end for
|
||||
} //end of the function AAS_DrawPermanentCross
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DrawPlaneCross( vec3_t point, vec3_t normal, float dist, int type, int color ) {
|
||||
int n0, n1, n2, j, line, lines[2];
|
||||
vec3_t start1, end1, start2, end2;
|
||||
|
||||
//make a cross in the hit plane at the hit point
|
||||
VectorCopy( point, start1 );
|
||||
VectorCopy( point, end1 );
|
||||
VectorCopy( point, start2 );
|
||||
VectorCopy( point, end2 );
|
||||
|
||||
n0 = type % 3;
|
||||
n1 = ( type + 1 ) % 3;
|
||||
n2 = ( type + 2 ) % 3;
|
||||
start1[n1] -= 6;
|
||||
start1[n2] -= 6;
|
||||
end1[n1] += 6;
|
||||
end1[n2] += 6;
|
||||
start2[n1] += 6;
|
||||
start2[n2] -= 6;
|
||||
end2[n1] -= 6;
|
||||
end2[n2] += 6;
|
||||
|
||||
start1[n0] = ( dist - ( start1[n1] * normal[n1] +
|
||||
start1[n2] * normal[n2] ) ) / normal[n0];
|
||||
end1[n0] = ( dist - ( end1[n1] * normal[n1] +
|
||||
end1[n2] * normal[n2] ) ) / normal[n0];
|
||||
start2[n0] = ( dist - ( start2[n1] * normal[n1] +
|
||||
start2[n2] * normal[n2] ) ) / normal[n0];
|
||||
end2[n0] = ( dist - ( end2[n1] * normal[n1] +
|
||||
end2[n2] * normal[n2] ) ) / normal[n0];
|
||||
|
||||
for ( j = 0, line = 0; j < 2 && line < MAX_DEBUGLINES; line++ )
|
||||
{
|
||||
if ( !debuglines[line] ) {
|
||||
debuglines[line] = botimport.DebugLineCreate();
|
||||
lines[j++] = debuglines[line];
|
||||
debuglinevisible[line] = qtrue;
|
||||
numdebuglines++;
|
||||
} //end if
|
||||
else if ( !debuglinevisible[line] ) {
|
||||
lines[j++] = debuglines[line];
|
||||
debuglinevisible[line] = qtrue;
|
||||
} //end else
|
||||
} //end for
|
||||
botimport.DebugLineShow( lines[0], start1, end1, color );
|
||||
botimport.DebugLineShow( lines[1], start2, end2, color );
|
||||
} //end of the function AAS_DrawPlaneCross
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowBoundingBox( vec3_t origin, vec3_t mins, vec3_t maxs ) {
|
||||
vec3_t bboxcorners[8];
|
||||
int lines[3];
|
||||
int i, j, line;
|
||||
|
||||
//upper corners
|
||||
bboxcorners[0][0] = origin[0] + maxs[0];
|
||||
bboxcorners[0][1] = origin[1] + maxs[1];
|
||||
bboxcorners[0][2] = origin[2] + maxs[2];
|
||||
//
|
||||
bboxcorners[1][0] = origin[0] + mins[0];
|
||||
bboxcorners[1][1] = origin[1] + maxs[1];
|
||||
bboxcorners[1][2] = origin[2] + maxs[2];
|
||||
//
|
||||
bboxcorners[2][0] = origin[0] + mins[0];
|
||||
bboxcorners[2][1] = origin[1] + mins[1];
|
||||
bboxcorners[2][2] = origin[2] + maxs[2];
|
||||
//
|
||||
bboxcorners[3][0] = origin[0] + maxs[0];
|
||||
bboxcorners[3][1] = origin[1] + mins[1];
|
||||
bboxcorners[3][2] = origin[2] + maxs[2];
|
||||
//lower corners
|
||||
memcpy( bboxcorners[4], bboxcorners[0], sizeof( vec3_t ) * 4 );
|
||||
for ( i = 0; i < 4; i++ ) bboxcorners[4 + i][2] = origin[2] + mins[2];
|
||||
//draw bounding box
|
||||
for ( i = 0; i < 4; i++ )
|
||||
{
|
||||
for ( j = 0, line = 0; j < 3 && line < MAX_DEBUGLINES; line++ )
|
||||
{
|
||||
if ( !debuglines[line] ) {
|
||||
debuglines[line] = botimport.DebugLineCreate();
|
||||
lines[j++] = debuglines[line];
|
||||
debuglinevisible[line] = qtrue;
|
||||
numdebuglines++;
|
||||
} //end if
|
||||
else if ( !debuglinevisible[line] ) {
|
||||
lines[j++] = debuglines[line];
|
||||
debuglinevisible[line] = qtrue;
|
||||
} //end else
|
||||
} //end for
|
||||
//top plane
|
||||
botimport.DebugLineShow( lines[0], bboxcorners[i],
|
||||
bboxcorners[( i + 1 ) & 3], LINECOLOR_RED );
|
||||
//bottom plane
|
||||
botimport.DebugLineShow( lines[1], bboxcorners[4 + i],
|
||||
bboxcorners[4 + ( ( i + 1 ) & 3 )], LINECOLOR_RED );
|
||||
//vertical lines
|
||||
botimport.DebugLineShow( lines[2], bboxcorners[i],
|
||||
bboxcorners[4 + i], LINECOLOR_RED );
|
||||
} //end for
|
||||
} //end of the function AAS_ShowBoundingBox
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowFace( int facenum ) {
|
||||
int i, color, edgenum;
|
||||
aas_edge_t *edge;
|
||||
aas_face_t *face;
|
||||
aas_plane_t *plane;
|
||||
vec3_t start, end;
|
||||
|
||||
color = LINECOLOR_YELLOW;
|
||||
//check if face number is in range
|
||||
if ( facenum >= ( *aasworld ).numfaces ) {
|
||||
botimport.Print( PRT_ERROR, "facenum %d out of range\n", facenum );
|
||||
} //end if
|
||||
face = &( *aasworld ).faces[facenum];
|
||||
//walk through the edges of the face
|
||||
for ( i = 0; i < face->numedges; i++ )
|
||||
{
|
||||
//edge number
|
||||
edgenum = abs( ( *aasworld ).edgeindex[face->firstedge + i] );
|
||||
//check if edge number is in range
|
||||
if ( edgenum >= ( *aasworld ).numedges ) {
|
||||
botimport.Print( PRT_ERROR, "edgenum %d out of range\n", edgenum );
|
||||
} //end if
|
||||
edge = &( *aasworld ).edges[edgenum];
|
||||
if ( color == LINECOLOR_RED ) {
|
||||
color = LINECOLOR_GREEN;
|
||||
} else if ( color == LINECOLOR_GREEN ) {
|
||||
color = LINECOLOR_BLUE;
|
||||
} else if ( color == LINECOLOR_BLUE ) {
|
||||
color = LINECOLOR_YELLOW;
|
||||
} else { color = LINECOLOR_RED;}
|
||||
AAS_DebugLine( ( *aasworld ).vertexes[edge->v[0]],
|
||||
( *aasworld ).vertexes[edge->v[1]],
|
||||
color );
|
||||
} //end for
|
||||
plane = &( *aasworld ).planes[face->planenum];
|
||||
edgenum = abs( ( *aasworld ).edgeindex[face->firstedge] );
|
||||
edge = &( *aasworld ).edges[edgenum];
|
||||
VectorCopy( ( *aasworld ).vertexes[edge->v[0]], start );
|
||||
VectorMA( start, 20, plane->normal, end );
|
||||
AAS_DebugLine( start, end, LINECOLOR_RED );
|
||||
} //end of the function AAS_ShowFace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowFacePolygon( int facenum, int color, int flip ) {
|
||||
int i, edgenum, numpoints;
|
||||
vec3_t points[128];
|
||||
aas_edge_t *edge;
|
||||
aas_face_t *face;
|
||||
|
||||
//check if face number is in range
|
||||
if ( facenum >= ( *aasworld ).numfaces ) {
|
||||
botimport.Print( PRT_ERROR, "facenum %d out of range\n", facenum );
|
||||
} //end if
|
||||
face = &( *aasworld ).faces[facenum];
|
||||
//walk through the edges of the face
|
||||
numpoints = 0;
|
||||
if ( flip ) {
|
||||
for ( i = face->numedges - 1; i >= 0; i-- )
|
||||
{
|
||||
//edge number
|
||||
edgenum = ( *aasworld ).edgeindex[face->firstedge + i];
|
||||
edge = &( *aasworld ).edges[abs( edgenum )];
|
||||
VectorCopy( ( *aasworld ).vertexes[edge->v[edgenum < 0]], points[numpoints] );
|
||||
numpoints++;
|
||||
} //end for
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < face->numedges; i++ )
|
||||
{
|
||||
//edge number
|
||||
edgenum = ( *aasworld ).edgeindex[face->firstedge + i];
|
||||
edge = &( *aasworld ).edges[abs( edgenum )];
|
||||
VectorCopy( ( *aasworld ).vertexes[edge->v[edgenum < 0]], points[numpoints] );
|
||||
numpoints++;
|
||||
} //end for
|
||||
} //end else
|
||||
AAS_ShowPolygon( color, numpoints, points );
|
||||
} //end of the function AAS_ShowFacePolygon
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowArea( int areanum, int groundfacesonly ) {
|
||||
int areaedges[MAX_DEBUGLINES];
|
||||
int numareaedges, i, j, n, color = 0, line;
|
||||
int facenum, edgenum;
|
||||
aas_area_t *area;
|
||||
aas_face_t *face;
|
||||
aas_edge_t *edge;
|
||||
|
||||
//
|
||||
numareaedges = 0;
|
||||
//
|
||||
if ( areanum < 0 || areanum >= ( *aasworld ).numareas ) {
|
||||
botimport.Print( PRT_ERROR, "area %d out of range [0, %d]\n",
|
||||
areanum, ( *aasworld ).numareas );
|
||||
return;
|
||||
} //end if
|
||||
//pointer to the convex area
|
||||
area = &( *aasworld ).areas[areanum];
|
||||
//walk through the faces of the area
|
||||
for ( i = 0; i < area->numfaces; i++ )
|
||||
{
|
||||
facenum = abs( ( *aasworld ).faceindex[area->firstface + i] );
|
||||
//check if face number is in range
|
||||
if ( facenum >= ( *aasworld ).numfaces ) {
|
||||
botimport.Print( PRT_ERROR, "facenum %d out of range\n", facenum );
|
||||
} //end if
|
||||
face = &( *aasworld ).faces[facenum];
|
||||
//ground faces only
|
||||
if ( groundfacesonly ) {
|
||||
if ( !( face->faceflags & ( FACE_GROUND | FACE_LADDER ) ) ) {
|
||||
continue;
|
||||
}
|
||||
} //end if
|
||||
//walk through the edges of the face
|
||||
for ( j = 0; j < face->numedges; j++ )
|
||||
{
|
||||
//edge number
|
||||
edgenum = abs( ( *aasworld ).edgeindex[face->firstedge + j] );
|
||||
//check if edge number is in range
|
||||
if ( edgenum >= ( *aasworld ).numedges ) {
|
||||
botimport.Print( PRT_ERROR, "edgenum %d out of range\n", edgenum );
|
||||
} //end if
|
||||
//check if the edge is stored already
|
||||
for ( n = 0; n < numareaedges; n++ )
|
||||
{
|
||||
if ( areaedges[n] == edgenum ) {
|
||||
break;
|
||||
}
|
||||
} //end for
|
||||
if ( n == numareaedges && numareaedges < MAX_DEBUGLINES ) {
|
||||
areaedges[numareaedges++] = edgenum;
|
||||
} //end if
|
||||
} //end for
|
||||
//AAS_ShowFace(facenum);
|
||||
} //end for
|
||||
//draw all the edges
|
||||
for ( n = 0; n < numareaedges; n++ )
|
||||
{
|
||||
for ( line = 0; line < MAX_DEBUGLINES; line++ )
|
||||
{
|
||||
if ( !debuglines[line] ) {
|
||||
debuglines[line] = botimport.DebugLineCreate();
|
||||
debuglinevisible[line] = qfalse;
|
||||
numdebuglines++;
|
||||
} //end if
|
||||
if ( !debuglinevisible[line] ) {
|
||||
break;
|
||||
} //end else
|
||||
} //end for
|
||||
if ( line >= MAX_DEBUGLINES ) {
|
||||
return;
|
||||
}
|
||||
edge = &( *aasworld ).edges[areaedges[n]];
|
||||
if ( color == LINECOLOR_RED ) {
|
||||
color = LINECOLOR_BLUE;
|
||||
} else if ( color == LINECOLOR_BLUE ) {
|
||||
color = LINECOLOR_GREEN;
|
||||
} else if ( color == LINECOLOR_GREEN ) {
|
||||
color = LINECOLOR_YELLOW;
|
||||
} else { color = LINECOLOR_RED;}
|
||||
botimport.DebugLineShow( debuglines[line],
|
||||
( *aasworld ).vertexes[edge->v[0]],
|
||||
( *aasworld ).vertexes[edge->v[1]],
|
||||
color );
|
||||
debuglinevisible[line] = qtrue;
|
||||
} //end for*/
|
||||
} //end of the function AAS_ShowArea
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowAreaPolygons( int areanum, int color, int groundfacesonly ) {
|
||||
int i, facenum;
|
||||
aas_area_t *area;
|
||||
aas_face_t *face;
|
||||
|
||||
//
|
||||
if ( areanum < 0 || areanum >= ( *aasworld ).numareas ) {
|
||||
botimport.Print( PRT_ERROR, "area %d out of range [0, %d]\n",
|
||||
areanum, ( *aasworld ).numareas );
|
||||
return;
|
||||
} //end if
|
||||
//pointer to the convex area
|
||||
area = &( *aasworld ).areas[areanum];
|
||||
//walk through the faces of the area
|
||||
for ( i = 0; i < area->numfaces; i++ )
|
||||
{
|
||||
facenum = abs( ( *aasworld ).faceindex[area->firstface + i] );
|
||||
//check if face number is in range
|
||||
if ( facenum >= ( *aasworld ).numfaces ) {
|
||||
botimport.Print( PRT_ERROR, "facenum %d out of range\n", facenum );
|
||||
} //end if
|
||||
face = &( *aasworld ).faces[facenum];
|
||||
//ground faces only
|
||||
if ( groundfacesonly ) {
|
||||
if ( !( face->faceflags & ( FACE_GROUND | FACE_LADDER ) ) ) {
|
||||
continue;
|
||||
}
|
||||
} //end if
|
||||
AAS_ShowFacePolygon( facenum, color, face->frontarea != areanum );
|
||||
} //end for
|
||||
} //end of the function AAS_ShowAreaPolygons
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DrawCross( vec3_t origin, float size, int color ) {
|
||||
int i;
|
||||
vec3_t start, end;
|
||||
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
VectorCopy( origin, start );
|
||||
start[i] += size;
|
||||
VectorCopy( origin, end );
|
||||
end[i] -= size;
|
||||
AAS_DebugLine( start, end, color );
|
||||
} //end for
|
||||
} //end of the function AAS_DrawCross
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PrintTravelType( int traveltype ) {
|
||||
#ifdef DEBUG
|
||||
char *str;
|
||||
//
|
||||
switch ( traveltype )
|
||||
{
|
||||
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
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
|
|
@ -0,0 +1,295 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 MAX_CLIENTS 128
|
||||
//#define MAX_MODELS 256 // these are sent over the net as 8 bits
|
||||
//#define MAX_SOUNDS 256 // so they cannot be blindly increased
|
||||
//#define MAX_CONFIGSTRINGS 1024
|
||||
#define MAX_CONFIGSTRINGS 2048 //----(SA) upped
|
||||
|
||||
//#define CS_SCORES 32
|
||||
//#define CS_MODELS (CS_SCORES+MAX_CLIENTS)
|
||||
//#define CS_SOUNDS (CS_MODELS+MAX_MODELS)
|
||||
|
||||
#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;
|
||||
//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;
|
||||
} 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
|
|
@ -0,0 +1,499 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
AAS_BSPModelMinsMaxsOrigin( ent->i.modelindex, ent->i.angles, ent->i.mins, ent->i.maxs, NULL );
|
||||
} //end if
|
||||
else if ( ent->i.solid == SOLID_BBOX ) {
|
||||
//if the bounding box size changed
|
||||
if ( !VectorCompare( state->mins, ent->i.mins ) ||
|
||||
!VectorCompare( state->maxs, ent->i.maxs ) ) {
|
||||
VectorCopy( state->mins, ent->i.mins );
|
||||
VectorCopy( state->maxs, ent->i.maxs );
|
||||
relink = qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
//if the origin changed
|
||||
if ( !VectorCompare( state->origin, ent->i.origin ) ) {
|
||||
VectorCopy( state->origin, ent->i.origin );
|
||||
relink = qtrue;
|
||||
} //end if
|
||||
//if the entity should be relinked
|
||||
if ( relink ) {
|
||||
//don't link the world model
|
||||
if ( entnum != ENTITYNUM_WORLD ) {
|
||||
//absolute mins and maxs
|
||||
VectorAdd( ent->i.mins, ent->i.origin, absmins );
|
||||
VectorAdd( ent->i.maxs, ent->i.origin, absmaxs );
|
||||
|
||||
//unlink the entity
|
||||
AAS_UnlinkFromAreas( ent->areas );
|
||||
//relink the entity to the AAS areas (use the larges bbox)
|
||||
ent->areas = AAS_LinkEntityClientBBox( absmins, absmaxs, entnum, PRESENCE_NORMAL );
|
||||
//unlink the entity from the BSP leaves
|
||||
AAS_UnlinkFromBSPLeaves( ent->leaves );
|
||||
//link the entity to the world BSP tree
|
||||
ent->leaves = AAS_BSPLinkEntity( absmins, absmaxs, entnum, 0 );
|
||||
} //end if
|
||||
} //end if
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function AAS_UpdateEntity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_EntityInfo( int entnum, aas_entityinfo_t *info ) {
|
||||
if ( !( *defaultaasworld ).initialized ) {
|
||||
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 ) {
|
||||
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;
|
||||
// int i;
|
||||
|
||||
// RF, not functional (doesnt work with multiple areas)
|
||||
return qfalse;
|
||||
|
||||
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, qboolean blocking ) {
|
||||
int areas[128];
|
||||
int numareas, i, w;
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
//
|
||||
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, 128 );
|
||||
// now set their blocking status
|
||||
for ( i = 0; i < numareas; i++ ) {
|
||||
AAS_EnableRoutingArea( areas[i], !blocking );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
|
@ -0,0 +1,662 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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] = LittleFloat( ( *aasworld ).bboxes[i].mins[j] );
|
||||
( *aasworld ).bboxes[i].maxs[j] = LittleFloat( ( *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 = LittleLong( ( *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;
|
||||
|
||||
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
|
||||
//
|
||||
if ( header.version == AASVERSION ) {
|
||||
AAS_DData( (unsigned char *) &header + 8, sizeof( aas_header_t ) - 8 );
|
||||
} //end if
|
||||
//
|
||||
( *aasworld ).bspchecksum = atoi( LibVarGetString( "sv_mapChecksum" ) );
|
||||
if ( LittleLong( header.bspchecksum ) != ( *aasworld ).bspchecksum ) {
|
||||
AAS_Error( "aas file %s is out of date\n", filename );
|
||||
botimport.FS_FCloseFile( fp );
|
||||
return BLERR_WRONGAASFILEVERSION;
|
||||
} //end if
|
||||
//load the lumps:
|
||||
//bounding boxes
|
||||
offset = LittleLong( header.lumps[AASLUMP_BBOXES].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_BBOXES].filelen );
|
||||
( *aasworld ).bboxes = (aas_bbox_t *) AAS_LoadAASLump( fp, offset, length, &lastoffset );
|
||||
( *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
|
||||
//
|
||||
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
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
|
@ -0,0 +1,486 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
vsprintf( 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.
|
||||
|
||||
} //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 );
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
botimport.Print( PRT_ERROR, "couldn't write %s\n", ( *aasworld ).filename );
|
||||
} //end else
|
||||
} //end if
|
||||
//initialize the routing
|
||||
AAS_InitRouting();
|
||||
//at this point AAS is initialized
|
||||
AAS_SetInitialized();
|
||||
} //end of the function AAS_ContinueInit
|
||||
//===========================================================================
|
||||
// called at the start of every frame
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_StartFrame( float time ) {
|
||||
// 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 );
|
||||
//
|
||||
( *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;
|
||||
} //end of the function AAS_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; // TTimo: init
|
||||
|
||||
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
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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.
|
|
@ -0,0 +1,912 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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.c
|
||||
*
|
||||
* desc: AAS
|
||||
*
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#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"
|
||||
|
||||
//#define BSPC
|
||||
|
||||
extern botlib_import_t botimport;
|
||||
|
||||
aas_settings_t aassettings;
|
||||
|
||||
//#define AAS_MOVE_DEBUG
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_DropToFloor( vec3_t origin, vec3_t mins, vec3_t maxs ) {
|
||||
vec3_t end;
|
||||
bsp_trace_t trace;
|
||||
|
||||
VectorCopy( origin, end );
|
||||
end[2] -= 100;
|
||||
trace = AAS_Trace( origin, mins, maxs, end, 0, CONTENTS_SOLID );
|
||||
if ( trace.startsolid ) {
|
||||
return qfalse;
|
||||
}
|
||||
VectorCopy( trace.endpos, origin );
|
||||
return qtrue;
|
||||
} //end of the function AAS_DropToFloor
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_InitSettings( void ) {
|
||||
aassettings.sv_friction = 6;
|
||||
aassettings.sv_stopspeed = 100;
|
||||
aassettings.sv_gravity = 800;
|
||||
aassettings.sv_waterfriction = 1;
|
||||
aassettings.sv_watergravity = 400;
|
||||
aassettings.sv_maxvelocity = 320;
|
||||
aassettings.sv_maxwalkvelocity = 300;
|
||||
aassettings.sv_maxcrouchvelocity = 100;
|
||||
aassettings.sv_maxswimvelocity = 150;
|
||||
aassettings.sv_walkaccelerate = 10;
|
||||
aassettings.sv_airaccelerate = 1;
|
||||
aassettings.sv_swimaccelerate = 4;
|
||||
aassettings.sv_maxstep = 18;
|
||||
aassettings.sv_maxsteepness = 0.7;
|
||||
aassettings.sv_maxwaterjump = 17;
|
||||
// Ridah, calculate maxbarrier according to jumpvel and gravity
|
||||
aassettings.sv_jumpvel = 270;
|
||||
aassettings.sv_maxbarrier = 49; //-0.8 + (0.5 * aassettings.sv_gravity * (aassettings.sv_jumpvel / aassettings.sv_gravity) * (aassettings.sv_jumpvel / aassettings.sv_gravity));
|
||||
// done.
|
||||
|
||||
} //end of the function AAS_InitSettings
|
||||
//===========================================================================
|
||||
// returns qtrue if the bot is against a ladder
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_AgainstLadder( vec3_t origin, int ms_areanum ) {
|
||||
int areanum, i, facenum, side;
|
||||
vec3_t org;
|
||||
aas_plane_t *plane;
|
||||
aas_face_t *face;
|
||||
aas_area_t *area;
|
||||
|
||||
VectorCopy( origin, org );
|
||||
areanum = AAS_PointAreaNum( org );
|
||||
if ( !areanum ) {
|
||||
org[0] += 1;
|
||||
areanum = AAS_PointAreaNum( org );
|
||||
if ( !areanum ) {
|
||||
org[1] += 1;
|
||||
areanum = AAS_PointAreaNum( org );
|
||||
if ( !areanum ) {
|
||||
org[0] -= 2;
|
||||
areanum = AAS_PointAreaNum( org );
|
||||
if ( !areanum ) {
|
||||
org[1] -= 2;
|
||||
areanum = AAS_PointAreaNum( org );
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
//if in solid... wrrr shouldn't happen
|
||||
//if (!areanum) return qfalse;
|
||||
// RF, it does if they're in a monsterclip brush
|
||||
if ( !areanum ) {
|
||||
areanum = ms_areanum;
|
||||
}
|
||||
//if not in a ladder area
|
||||
if ( !( ( *aasworld ).areasettings[areanum].areaflags & AREA_LADDER ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
//if a crouch only area
|
||||
if ( !( ( *aasworld ).areasettings[areanum].presencetype & PRESENCE_NORMAL ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
//
|
||||
area = &( *aasworld ).areas[areanum];
|
||||
for ( i = 0; i < area->numfaces; i++ )
|
||||
{
|
||||
facenum = ( *aasworld ).faceindex[area->firstface + i];
|
||||
side = facenum < 0;
|
||||
face = &( *aasworld ).faces[abs( facenum )];
|
||||
//if the face isn't a ladder face
|
||||
if ( !( face->faceflags & FACE_LADDER ) ) {
|
||||
continue;
|
||||
}
|
||||
//get the plane the face is in
|
||||
plane = &( *aasworld ).planes[face->planenum ^ side];
|
||||
//if the origin is pretty close to the plane
|
||||
if ( abs( DotProduct( plane->normal, origin ) - plane->dist ) < 3 ) {
|
||||
if ( AAS_PointInsideFace( abs( facenum ), origin, 0.1 ) ) {
|
||||
return qtrue;
|
||||
}
|
||||
} //end if
|
||||
} //end for
|
||||
return qfalse;
|
||||
} //end of the function AAS_AgainstLadder
|
||||
//===========================================================================
|
||||
// returns qtrue if the bot is on the ground
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_OnGround( vec3_t origin, int presencetype, int passent ) {
|
||||
aas_trace_t trace;
|
||||
vec3_t end, up = {0, 0, 1};
|
||||
aas_plane_t *plane;
|
||||
|
||||
VectorCopy( origin, end );
|
||||
end[2] -= 10;
|
||||
|
||||
trace = AAS_TraceClientBBox( origin, end, presencetype, passent );
|
||||
|
||||
//if in solid
|
||||
if ( trace.startsolid ) {
|
||||
return qtrue; //qfalse;
|
||||
}
|
||||
//if nothing hit at all
|
||||
if ( trace.fraction >= 1.0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
//if too far from the hit plane
|
||||
if ( origin[2] - trace.endpos[2] > 10 ) {
|
||||
return qfalse;
|
||||
}
|
||||
//check if the plane isn't too steep
|
||||
plane = AAS_PlaneFromNum( trace.planenum );
|
||||
if ( DotProduct( plane->normal, up ) < aassettings.sv_maxsteepness ) {
|
||||
return qfalse;
|
||||
}
|
||||
//the bot is on the ground
|
||||
return qtrue;
|
||||
} //end of the function AAS_OnGround
|
||||
//===========================================================================
|
||||
// returns qtrue if a bot at the given position is swimming
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_Swimming( vec3_t origin ) {
|
||||
vec3_t testorg;
|
||||
|
||||
VectorCopy( origin, testorg );
|
||||
testorg[2] -= 2;
|
||||
if ( AAS_PointContents( testorg ) & ( CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER ) ) {
|
||||
return qtrue;
|
||||
}
|
||||
return qfalse;
|
||||
} //end of the function AAS_Swimming
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
vec3_t VEC_UP = {0, -1, 0};
|
||||
vec3_t MOVEDIR_UP = {0, 0, 1};
|
||||
vec3_t VEC_DOWN = {0, -2, 0};
|
||||
vec3_t MOVEDIR_DOWN = {0, 0, -1};
|
||||
|
||||
void AAS_SetMovedir( vec3_t angles, vec3_t movedir ) {
|
||||
if ( VectorCompare( angles, VEC_UP ) ) {
|
||||
VectorCopy( MOVEDIR_UP, movedir );
|
||||
} //end if
|
||||
else if ( VectorCompare( angles, VEC_DOWN ) ) {
|
||||
VectorCopy( MOVEDIR_DOWN, movedir );
|
||||
} //end else if
|
||||
else
|
||||
{
|
||||
AngleVectors( angles, movedir, NULL, NULL );
|
||||
} //end else
|
||||
} //end of the function AAS_SetMovedir
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_JumpReachRunStart( aas_reachability_t *reach, vec3_t runstart ) {
|
||||
vec3_t hordir, start, cmdmove;
|
||||
aas_clientmove_t move;
|
||||
|
||||
//
|
||||
hordir[0] = reach->start[0] - reach->end[0];
|
||||
hordir[1] = reach->start[1] - reach->end[1];
|
||||
hordir[2] = 0;
|
||||
VectorNormalize( hordir );
|
||||
//start point
|
||||
VectorCopy( reach->start, start );
|
||||
start[2] += 1;
|
||||
//get command movement
|
||||
VectorScale( hordir, 400, cmdmove );
|
||||
//
|
||||
AAS_PredictClientMovement( &move, -1, start, PRESENCE_NORMAL, qtrue,
|
||||
vec3_origin, cmdmove, 1, 2, 0.1,
|
||||
SE_ENTERWATER | SE_ENTERSLIME | SE_ENTERLAVA |
|
||||
SE_HITGROUNDDAMAGE | SE_GAP, 0, qfalse );
|
||||
VectorCopy( move.endpos, runstart );
|
||||
//don't enter slime or lava and don't fall from too high
|
||||
if ( move.stopevent & ( SE_ENTERLAVA | SE_HITGROUNDDAMAGE ) ) { //----(SA) modified since slime is no longer deadly
|
||||
// if (move.stopevent & (SE_ENTERSLIME|SE_ENTERLAVA|SE_HITGROUNDDAMAGE))
|
||||
VectorCopy( start, runstart );
|
||||
} //end if
|
||||
} //end of the function AAS_JumpReachRunStart
|
||||
//===========================================================================
|
||||
// returns the Z velocity when rocket jumping at the origin
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float AAS_WeaponJumpZVelocity( vec3_t origin, float radiusdamage ) {
|
||||
vec3_t kvel, v, start, end, forward, right, viewangles, dir;
|
||||
float mass, knockback, points;
|
||||
vec3_t rocketoffset = {8, 8, -8};
|
||||
vec3_t botmins = {-16, -16, -24};
|
||||
vec3_t botmaxs = {16, 16, 32};
|
||||
bsp_trace_t bsptrace;
|
||||
|
||||
//look down (90 degrees)
|
||||
viewangles[PITCH] = 90;
|
||||
viewangles[YAW] = 0;
|
||||
viewangles[ROLL] = 0;
|
||||
//get the start point shooting from
|
||||
VectorCopy( origin, start );
|
||||
start[2] += 8; //view offset Z
|
||||
AngleVectors( viewangles, forward, right, NULL );
|
||||
start[0] += forward[0] * rocketoffset[0] + right[0] * rocketoffset[1];
|
||||
start[1] += forward[1] * rocketoffset[0] + right[1] * rocketoffset[1];
|
||||
start[2] += forward[2] * rocketoffset[0] + right[2] * rocketoffset[1] + rocketoffset[2];
|
||||
//end point of the trace
|
||||
VectorMA( start, 500, forward, end );
|
||||
//trace a line to get the impact point
|
||||
bsptrace = AAS_Trace( start, NULL, NULL, end, 1, CONTENTS_SOLID );
|
||||
//calculate the damage the bot will get from the rocket impact
|
||||
VectorAdd( botmins, botmaxs, v );
|
||||
VectorMA( origin, 0.5, v, v );
|
||||
VectorSubtract( bsptrace.endpos, v, v );
|
||||
//
|
||||
points = radiusdamage - 0.5 * VectorLength( v );
|
||||
if ( points < 0 ) {
|
||||
points = 0;
|
||||
}
|
||||
//the owner of the rocket gets half the damage
|
||||
points *= 0.5;
|
||||
//mass of the bot (p_client.c: PutClientInServer)
|
||||
mass = 200;
|
||||
//knockback is the same as the damage points
|
||||
knockback = points;
|
||||
//direction of the damage (from trace.endpos to bot origin)
|
||||
VectorSubtract( origin, bsptrace.endpos, dir );
|
||||
VectorNormalize( dir );
|
||||
//damage velocity
|
||||
VectorScale( dir, 1600.0 * (float)knockback / mass, kvel ); //the rocket jump hack...
|
||||
//rocket impact velocity + jump velocity
|
||||
return kvel[2] + aassettings.sv_jumpvel;
|
||||
} //end of the function AAS_WeaponJumpZVelocity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float AAS_RocketJumpZVelocity( vec3_t origin ) {
|
||||
//rocket radius damage is 120 (p_weapon.c: Weapon_RocketLauncher_Fire)
|
||||
return AAS_WeaponJumpZVelocity( origin, 120 );
|
||||
} //end of the function AAS_RocketJumpZVelocity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float AAS_BFGJumpZVelocity( vec3_t origin ) {
|
||||
//bfg radius damage is 1000 (p_weapon.c: weapon_bfg_fire)
|
||||
return AAS_WeaponJumpZVelocity( origin, 120 );
|
||||
} //end of the function AAS_BFGJumpZVelocity
|
||||
//===========================================================================
|
||||
// applies ground friction to the given velocity
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_Accelerate( vec3_t velocity, float frametime, vec3_t wishdir, float wishspeed, float accel ) {
|
||||
// q2 style
|
||||
int i;
|
||||
float addspeed, accelspeed, currentspeed;
|
||||
|
||||
currentspeed = DotProduct( velocity, wishdir );
|
||||
addspeed = wishspeed - currentspeed;
|
||||
if ( addspeed <= 0 ) {
|
||||
return;
|
||||
}
|
||||
accelspeed = accel * frametime * wishspeed;
|
||||
if ( accelspeed > addspeed ) {
|
||||
accelspeed = addspeed;
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < 3 ; i++ ) {
|
||||
velocity[i] += accelspeed * wishdir[i];
|
||||
}
|
||||
} //end of the function AAS_Accelerate
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_AirControl( vec3_t start, vec3_t end, vec3_t velocity, vec3_t cmdmove ) {
|
||||
vec3_t dir;
|
||||
|
||||
VectorSubtract( end, start, dir );
|
||||
} //end of the function AAS_AirControl
|
||||
//===========================================================================
|
||||
// applies ground friction to the given velocity
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ApplyFriction( vec3_t vel, float friction, float stopspeed,
|
||||
float frametime ) {
|
||||
float speed, control, newspeed;
|
||||
|
||||
//horizontal speed
|
||||
speed = sqrt( vel[0] * vel[0] + vel[1] * vel[1] );
|
||||
if ( speed ) {
|
||||
control = speed < stopspeed ? stopspeed : speed;
|
||||
newspeed = speed - frametime * control * friction;
|
||||
if ( newspeed < 0 ) {
|
||||
newspeed = 0;
|
||||
}
|
||||
newspeed /= speed;
|
||||
vel[0] *= newspeed;
|
||||
vel[1] *= newspeed;
|
||||
} //end if
|
||||
} //end of the function AAS_ApplyFriction
|
||||
//===========================================================================
|
||||
// predicts the movement
|
||||
// assumes regular bounding box sizes
|
||||
// NOTE: out of water jumping is not included
|
||||
// NOTE: grappling hook is not included
|
||||
//
|
||||
// Parameter: origin : origin to start with
|
||||
// presencetype : presence type to start with
|
||||
// velocity : velocity to start with
|
||||
// cmdmove : client command movement
|
||||
// cmdframes : number of frame cmdmove is valid
|
||||
// maxframes : maximum number of predicted frames
|
||||
// frametime : duration of one predicted frame
|
||||
// stopevent : events that stop the prediction
|
||||
// stopareanum : stop as soon as entered this area
|
||||
// Returns: aas_clientmove_t
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
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 ) {
|
||||
float sv_friction, sv_stopspeed, sv_gravity, sv_waterfriction;
|
||||
float sv_watergravity;
|
||||
float sv_walkaccelerate, sv_airaccelerate, sv_swimaccelerate;
|
||||
float sv_maxwalkvelocity, sv_maxcrouchvelocity, sv_maxswimvelocity;
|
||||
float sv_maxstep, sv_maxsteepness, sv_jumpvel, friction;
|
||||
float gravity, delta, maxvel, wishspeed, accelerate;
|
||||
//float velchange, newvel;
|
||||
int n, i, j, pc, step, swimming, ax, crouch, event, jump_frame, areanum;
|
||||
int areas[20], numareas;
|
||||
vec3_t points[20];
|
||||
vec3_t org, end, feet, start, stepend, lastorg, wishdir;
|
||||
vec3_t frame_test_vel, old_frame_test_vel, left_test_vel;
|
||||
vec3_t up = {0, 0, 1};
|
||||
aas_plane_t *plane, *plane2;
|
||||
aas_trace_t trace, steptrace;
|
||||
|
||||
if ( frametime <= 0 ) {
|
||||
frametime = 0.1;
|
||||
}
|
||||
//
|
||||
sv_friction = aassettings.sv_friction;
|
||||
sv_stopspeed = aassettings.sv_stopspeed;
|
||||
sv_gravity = aassettings.sv_gravity;
|
||||
sv_waterfriction = aassettings.sv_waterfriction;
|
||||
sv_watergravity = aassettings.sv_watergravity;
|
||||
sv_maxwalkvelocity = aassettings.sv_maxwalkvelocity; // * frametime;
|
||||
sv_maxcrouchvelocity = aassettings.sv_maxcrouchvelocity; // * frametime;
|
||||
sv_maxswimvelocity = aassettings.sv_maxswimvelocity; // * frametime;
|
||||
sv_walkaccelerate = aassettings.sv_walkaccelerate;
|
||||
sv_airaccelerate = aassettings.sv_airaccelerate;
|
||||
sv_swimaccelerate = aassettings.sv_swimaccelerate;
|
||||
sv_maxstep = aassettings.sv_maxstep;
|
||||
sv_maxsteepness = aassettings.sv_maxsteepness;
|
||||
sv_jumpvel = aassettings.sv_jumpvel * frametime;
|
||||
//
|
||||
memset( move, 0, sizeof( aas_clientmove_t ) );
|
||||
memset( &trace, 0, sizeof( aas_trace_t ) );
|
||||
//start at the current origin
|
||||
VectorCopy( origin, org );
|
||||
org[2] += 0.25;
|
||||
//velocity to test for the first frame
|
||||
VectorScale( velocity, frametime, frame_test_vel );
|
||||
//
|
||||
jump_frame = -1;
|
||||
//predict a maximum of 'maxframes' ahead
|
||||
for ( n = 0; n < maxframes; n++ )
|
||||
{
|
||||
swimming = AAS_Swimming( org );
|
||||
//get gravity depending on swimming or not
|
||||
gravity = swimming ? sv_watergravity : sv_gravity;
|
||||
//apply gravity at the START of the frame
|
||||
frame_test_vel[2] = frame_test_vel[2] - ( gravity * 0.1 * frametime );
|
||||
//if on the ground or swimming
|
||||
if ( onground || swimming ) {
|
||||
friction = swimming ? sv_friction : sv_waterfriction;
|
||||
//apply friction
|
||||
VectorScale( frame_test_vel, 1 / frametime, frame_test_vel );
|
||||
AAS_ApplyFriction( frame_test_vel, friction, sv_stopspeed, frametime );
|
||||
VectorScale( frame_test_vel, frametime, frame_test_vel );
|
||||
} //end if
|
||||
crouch = qfalse;
|
||||
//apply command movement
|
||||
if ( n < cmdframes ) {
|
||||
ax = 0;
|
||||
maxvel = sv_maxwalkvelocity;
|
||||
accelerate = sv_airaccelerate;
|
||||
VectorCopy( cmdmove, wishdir );
|
||||
if ( onground ) {
|
||||
if ( cmdmove[2] < -300 ) {
|
||||
crouch = qtrue;
|
||||
maxvel = sv_maxcrouchvelocity;
|
||||
} //end if
|
||||
//if not swimming and upmove is positive then jump
|
||||
if ( !swimming && cmdmove[2] > 1 ) {
|
||||
//jump velocity minus the gravity for one frame + 5 for safety
|
||||
frame_test_vel[2] = sv_jumpvel - ( gravity * 0.1 * frametime ) + 5;
|
||||
jump_frame = n;
|
||||
//jumping so air accelerate
|
||||
accelerate = sv_airaccelerate;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
accelerate = sv_walkaccelerate;
|
||||
} //end else
|
||||
ax = 2;
|
||||
} //end if
|
||||
if ( swimming ) {
|
||||
maxvel = sv_maxswimvelocity;
|
||||
accelerate = sv_swimaccelerate;
|
||||
ax = 3;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
wishdir[2] = 0;
|
||||
} //end else
|
||||
//
|
||||
wishspeed = VectorNormalize( wishdir );
|
||||
if ( wishspeed > maxvel ) {
|
||||
wishspeed = maxvel;
|
||||
}
|
||||
VectorScale( frame_test_vel, 1 / frametime, frame_test_vel );
|
||||
AAS_Accelerate( frame_test_vel, frametime, wishdir, wishspeed, accelerate );
|
||||
VectorScale( frame_test_vel, frametime, frame_test_vel );
|
||||
/*
|
||||
for (i = 0; i < ax; i++)
|
||||
{
|
||||
velchange = (cmdmove[i] * frametime) - frame_test_vel[i];
|
||||
if (velchange > sv_maxacceleration) velchange = sv_maxacceleration;
|
||||
else if (velchange < -sv_maxacceleration) velchange = -sv_maxacceleration;
|
||||
newvel = frame_test_vel[i] + velchange;
|
||||
//
|
||||
if (frame_test_vel[i] <= maxvel && newvel > maxvel) frame_test_vel[i] = maxvel;
|
||||
else if (frame_test_vel[i] >= -maxvel && newvel < -maxvel) frame_test_vel[i] = -maxvel;
|
||||
else frame_test_vel[i] = newvel;
|
||||
} //end for
|
||||
*/
|
||||
} //end if
|
||||
if ( crouch ) {
|
||||
presencetype = PRESENCE_CROUCH;
|
||||
} //end if
|
||||
else if ( presencetype == PRESENCE_CROUCH ) {
|
||||
if ( AAS_PointPresenceType( org ) & PRESENCE_NORMAL ) {
|
||||
presencetype = PRESENCE_NORMAL;
|
||||
} //end if
|
||||
} //end else
|
||||
//save the current origin
|
||||
VectorCopy( org, lastorg );
|
||||
//move linear during one frame
|
||||
VectorCopy( frame_test_vel, left_test_vel );
|
||||
j = 0;
|
||||
do
|
||||
{
|
||||
VectorAdd( org, left_test_vel, end );
|
||||
//trace a bounding box
|
||||
trace = AAS_TraceClientBBox( org, end, presencetype, entnum );
|
||||
//
|
||||
//#ifdef AAS_MOVE_DEBUG
|
||||
if ( visualize ) {
|
||||
if ( trace.startsolid ) {
|
||||
botimport.Print( PRT_MESSAGE, "PredictMovement: start solid\n" );
|
||||
}
|
||||
AAS_DebugLine( org, trace.endpos, LINECOLOR_RED );
|
||||
} //end if
|
||||
//#endif //AAS_MOVE_DEBUG
|
||||
//
|
||||
if ( stopevent & SE_ENTERAREA ) {
|
||||
numareas = AAS_TraceAreas( org, trace.endpos, areas, points, 20 );
|
||||
for ( i = 0; i < numareas; i++ )
|
||||
{
|
||||
if ( areas[i] == stopareanum ) {
|
||||
VectorCopy( points[i], move->endpos );
|
||||
VectorScale( frame_test_vel, 1 / frametime, move->velocity );
|
||||
move->trace = trace;
|
||||
move->stopevent = SE_ENTERAREA;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = 0;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end if
|
||||
//move the entity to the trace end point
|
||||
VectorCopy( trace.endpos, org );
|
||||
//if there was a collision
|
||||
if ( trace.fraction < 1.0 ) {
|
||||
//get the plane the bounding box collided with
|
||||
plane = AAS_PlaneFromNum( trace.planenum );
|
||||
//
|
||||
if ( stopevent & SE_HITGROUNDAREA ) {
|
||||
if ( DotProduct( plane->normal, up ) > sv_maxsteepness ) {
|
||||
VectorCopy( org, start );
|
||||
start[2] += 0.5;
|
||||
if ( AAS_PointAreaNum( start ) == stopareanum ) {
|
||||
VectorCopy( start, move->endpos );
|
||||
VectorScale( frame_test_vel, 1 / frametime, move->velocity );
|
||||
move->trace = trace;
|
||||
move->stopevent = SE_HITGROUNDAREA;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = 0;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
//assume there's no step
|
||||
step = qfalse;
|
||||
//if it is a vertical plane and the bot didn't jump recently
|
||||
if ( plane->normal[2] == 0 && ( jump_frame < 0 || n - jump_frame > 2 ) ) {
|
||||
//check for a step
|
||||
VectorMA( org, -0.25, plane->normal, start );
|
||||
VectorCopy( start, stepend );
|
||||
start[2] += sv_maxstep;
|
||||
steptrace = AAS_TraceClientBBox( start, stepend, presencetype, entnum );
|
||||
//
|
||||
if ( !steptrace.startsolid ) {
|
||||
plane2 = AAS_PlaneFromNum( steptrace.planenum );
|
||||
if ( DotProduct( plane2->normal, up ) > sv_maxsteepness ) {
|
||||
VectorSubtract( end, steptrace.endpos, left_test_vel );
|
||||
left_test_vel[2] = 0;
|
||||
frame_test_vel[2] = 0;
|
||||
//#ifdef AAS_MOVE_DEBUG
|
||||
if ( visualize ) {
|
||||
if ( steptrace.endpos[2] - org[2] > 0.125 ) {
|
||||
VectorCopy( org, start );
|
||||
start[2] = steptrace.endpos[2];
|
||||
AAS_DebugLine( org, start, LINECOLOR_BLUE );
|
||||
} //end if
|
||||
} //end if
|
||||
//#endif //AAS_MOVE_DEBUG
|
||||
org[2] = steptrace.endpos[2];
|
||||
step = qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
//
|
||||
if ( !step ) {
|
||||
//velocity left to test for this frame is the projection
|
||||
//of the current test velocity into the hit plane
|
||||
VectorMA( left_test_vel, -DotProduct( left_test_vel, plane->normal ),
|
||||
plane->normal, left_test_vel );
|
||||
//store the old velocity for landing check
|
||||
VectorCopy( frame_test_vel, old_frame_test_vel );
|
||||
//test velocity for the next frame is the projection
|
||||
//of the velocity of the current frame into the hit plane
|
||||
VectorMA( frame_test_vel, -DotProduct( frame_test_vel, plane->normal ),
|
||||
plane->normal, frame_test_vel );
|
||||
//check for a landing on an almost horizontal floor
|
||||
if ( DotProduct( plane->normal, up ) > sv_maxsteepness ) {
|
||||
onground = qtrue;
|
||||
} //end if
|
||||
if ( stopevent & SE_HITGROUNDDAMAGE ) {
|
||||
delta = 0;
|
||||
if ( old_frame_test_vel[2] < 0 &&
|
||||
frame_test_vel[2] > old_frame_test_vel[2] &&
|
||||
!onground ) {
|
||||
delta = old_frame_test_vel[2];
|
||||
} //end if
|
||||
else if ( onground ) {
|
||||
delta = frame_test_vel[2] - old_frame_test_vel[2];
|
||||
} //end else
|
||||
if ( delta ) {
|
||||
delta = delta * 10;
|
||||
delta = delta * delta * 0.0001;
|
||||
if ( swimming ) {
|
||||
delta = 0;
|
||||
}
|
||||
// never take falling damage if completely underwater
|
||||
/*
|
||||
if (ent->waterlevel == 3) return;
|
||||
if (ent->waterlevel == 2) delta *= 0.25;
|
||||
if (ent->waterlevel == 1) delta *= 0.5;
|
||||
*/
|
||||
if ( delta > 40 ) {
|
||||
VectorCopy( org, move->endpos );
|
||||
VectorCopy( frame_test_vel, move->velocity );
|
||||
move->trace = trace;
|
||||
move->stopevent = SE_HITGROUNDDAMAGE;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = 0;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
//extra check to prevent endless loop
|
||||
if ( ++j > 20 ) {
|
||||
return qfalse;
|
||||
}
|
||||
//while there is a plane hit
|
||||
} while ( trace.fraction < 1.0 );
|
||||
//if going down
|
||||
if ( frame_test_vel[2] <= 10 ) {
|
||||
//check for a liquid at the feet of the bot
|
||||
VectorCopy( org, feet );
|
||||
feet[2] -= 22;
|
||||
pc = AAS_PointContents( feet );
|
||||
//get event from pc
|
||||
event = SE_NONE;
|
||||
if ( pc & CONTENTS_LAVA ) {
|
||||
event |= SE_ENTERLAVA;
|
||||
}
|
||||
if ( pc & CONTENTS_SLIME ) {
|
||||
event |= SE_ENTERSLIME;
|
||||
}
|
||||
if ( pc & CONTENTS_WATER ) {
|
||||
event |= SE_ENTERWATER;
|
||||
}
|
||||
//
|
||||
areanum = AAS_PointAreaNum( org );
|
||||
if ( ( *aasworld ).areasettings[areanum].contents & AREACONTENTS_LAVA ) {
|
||||
event |= SE_ENTERLAVA;
|
||||
}
|
||||
if ( ( *aasworld ).areasettings[areanum].contents & AREACONTENTS_SLIME ) {
|
||||
event |= SE_ENTERSLIME;
|
||||
}
|
||||
if ( ( *aasworld ).areasettings[areanum].contents & AREACONTENTS_WATER ) {
|
||||
event |= SE_ENTERWATER;
|
||||
}
|
||||
//if in lava or slime
|
||||
if ( event & stopevent ) {
|
||||
VectorCopy( org, move->endpos );
|
||||
VectorScale( frame_test_vel, 1 / frametime, move->velocity );
|
||||
move->stopevent = event & stopevent;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = pc;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
//
|
||||
onground = AAS_OnGround( org, presencetype, entnum );
|
||||
//if onground and on the ground for at least one whole frame
|
||||
if ( onground ) {
|
||||
if ( stopevent & SE_HITGROUND ) {
|
||||
VectorCopy( org, move->endpos );
|
||||
VectorScale( frame_test_vel, 1 / frametime, move->velocity );
|
||||
move->trace = trace;
|
||||
move->stopevent = SE_HITGROUND;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = 0;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
else if ( stopevent & SE_LEAVEGROUND ) {
|
||||
VectorCopy( org, move->endpos );
|
||||
VectorScale( frame_test_vel, 1 / frametime, move->velocity );
|
||||
move->trace = trace;
|
||||
move->stopevent = SE_LEAVEGROUND;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = 0;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
return qtrue;
|
||||
} //end else if
|
||||
else if ( stopevent & SE_GAP ) {
|
||||
aas_trace_t gaptrace;
|
||||
|
||||
VectorCopy( org, start );
|
||||
VectorCopy( start, end );
|
||||
end[2] -= 48 + aassettings.sv_maxbarrier;
|
||||
gaptrace = AAS_TraceClientBBox( start, end, PRESENCE_CROUCH, -1 );
|
||||
//if solid is found the bot cannot walk any further and will not fall into a gap
|
||||
if ( !gaptrace.startsolid ) {
|
||||
//if it is a gap (lower than one step height)
|
||||
if ( gaptrace.endpos[2] < org[2] - aassettings.sv_maxstep - 1 ) {
|
||||
if ( !( AAS_PointContents( end ) & ( CONTENTS_WATER | CONTENTS_SLIME ) ) ) { //----(SA) modified since slime is no longer deadly
|
||||
// if (!(AAS_PointContents(end) & CONTENTS_WATER))
|
||||
VectorCopy( lastorg, move->endpos );
|
||||
VectorScale( frame_test_vel, 1 / frametime, move->velocity );
|
||||
move->trace = trace;
|
||||
move->stopevent = SE_GAP;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = 0;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
} //end else if
|
||||
if ( stopevent & SE_TOUCHJUMPPAD ) {
|
||||
if ( ( *aasworld ).areasettings[AAS_PointAreaNum( org )].contents & AREACONTENTS_JUMPPAD ) {
|
||||
VectorCopy( org, move->endpos );
|
||||
VectorScale( frame_test_vel, 1 / frametime, move->velocity );
|
||||
move->trace = trace;
|
||||
move->stopevent = SE_TOUCHJUMPPAD;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = 0;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
if ( stopevent & SE_TOUCHTELEPORTER ) {
|
||||
if ( ( *aasworld ).areasettings[AAS_PointAreaNum( org )].contents & AREACONTENTS_TELEPORTER ) {
|
||||
VectorCopy( org, move->endpos );
|
||||
VectorScale( frame_test_vel, 1 / frametime, move->velocity );
|
||||
move->trace = trace;
|
||||
move->stopevent = SE_TOUCHTELEPORTER;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = 0;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
return qtrue;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
//
|
||||
VectorCopy( org, move->endpos );
|
||||
VectorScale( frame_test_vel, 1 / frametime, move->velocity );
|
||||
move->stopevent = SE_NONE;
|
||||
move->presencetype = presencetype;
|
||||
move->endcontents = 0;
|
||||
move->time = n * frametime;
|
||||
move->frames = n;
|
||||
//
|
||||
return qtrue;
|
||||
} //end of the function AAS_PredictClientMovement
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_TestMovementPrediction( int entnum, vec3_t origin, vec3_t dir ) {
|
||||
vec3_t velocity, cmdmove;
|
||||
aas_clientmove_t move;
|
||||
|
||||
VectorClear( velocity );
|
||||
if ( !AAS_Swimming( origin ) ) {
|
||||
dir[2] = 0;
|
||||
}
|
||||
VectorNormalize( dir );
|
||||
VectorScale( dir, 400, cmdmove );
|
||||
cmdmove[2] = 224;
|
||||
AAS_ClearShownDebugLines();
|
||||
AAS_PredictClientMovement( &move, entnum, origin, PRESENCE_NORMAL, qtrue,
|
||||
velocity, cmdmove, 13, 13, 0.1, SE_HITGROUND, 0, qtrue ); //SE_LEAVEGROUND);
|
||||
if ( move.stopevent & SE_LEAVEGROUND ) {
|
||||
botimport.Print( PRT_MESSAGE, "leave ground\n" );
|
||||
} //end if
|
||||
} //end of the function TestMovementPrediction
|
||||
//===========================================================================
|
||||
// calculates the horizontal velocity needed to perform a jump from start
|
||||
// to end
|
||||
//
|
||||
// Parameter: zvel : z velocity for jump
|
||||
// start : start position of jump
|
||||
// end : end position of jump
|
||||
// *speed : returned speed for jump
|
||||
// Returns: qfalse if too high or too far from start to end
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_HorizontalVelocityForJump( float zvel, vec3_t start, vec3_t end, float *velocity ) {
|
||||
float sv_gravity, sv_maxvelocity;
|
||||
float maxjump, height2fall, t, top;
|
||||
vec3_t dir;
|
||||
|
||||
sv_gravity = aassettings.sv_gravity;
|
||||
sv_maxvelocity = aassettings.sv_maxvelocity;
|
||||
|
||||
//maximum height a player can jump with the given initial z velocity
|
||||
maxjump = 0.5 * sv_gravity * ( zvel / sv_gravity ) * ( zvel / sv_gravity );
|
||||
//top of the parabolic jump
|
||||
top = start[2] + maxjump;
|
||||
//height the bot will fall from the top
|
||||
height2fall = top - end[2];
|
||||
//if the goal is to high to jump to
|
||||
if ( height2fall < 0 ) {
|
||||
*velocity = sv_maxvelocity;
|
||||
return 0;
|
||||
} //end if
|
||||
//time a player takes to fall the height
|
||||
t = sqrt( height2fall / ( 0.5 * sv_gravity ) );
|
||||
//direction from start to end
|
||||
VectorSubtract( end, start, dir );
|
||||
//calculate horizontal speed
|
||||
*velocity = sqrt( dir[0] * dir[0] + dir[1] * dir[1] ) / ( t + zvel / sv_gravity );
|
||||
//the horizontal speed must be lower than the max speed
|
||||
if ( *velocity > sv_maxvelocity ) {
|
||||
*velocity = sv_maxvelocity;
|
||||
return 0;
|
||||
} //end if
|
||||
return 1;
|
||||
} //end of the function AAS_HorizontalVelocityForJump
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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;
|
||||
//
|
||||
int *vertexoptimizeindex;
|
||||
int *edgeoptimizeindex;
|
||||
int *faceoptimizeindex;
|
||||
} optimized_t;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_KeepEdge( aas_edge_t *edge ) {
|
||||
return 1;
|
||||
} //end of the function AAS_KeepFace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_OptimizeEdge( optimized_t *optimized, int edgenum ) {
|
||||
int i, optedgenum;
|
||||
aas_edge_t *edge, *optedge;
|
||||
|
||||
edge = &( *aasworld ).edges[abs( edgenum )];
|
||||
if ( !AAS_KeepEdge( edge ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
optedgenum = optimized->edgeoptimizeindex[abs( edgenum )];
|
||||
if ( optedgenum ) {
|
||||
//keep the edge reversed sign
|
||||
if ( edgenum > 0 ) {
|
||||
return optedgenum;
|
||||
} else { return -optedgenum;}
|
||||
} //end if
|
||||
|
||||
optedge = &optimized->edges[optimized->numedges];
|
||||
|
||||
for ( i = 0; i < 2; i++ )
|
||||
{
|
||||
if ( optimized->vertexoptimizeindex[edge->v[i]] ) {
|
||||
optedge->v[i] = optimized->vertexoptimizeindex[edge->v[i]];
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
VectorCopy( ( *aasworld ).vertexes[edge->v[i]], optimized->vertexes[optimized->numvertexes] );
|
||||
optedge->v[i] = optimized->numvertexes;
|
||||
optimized->vertexoptimizeindex[edge->v[i]] = optimized->numvertexes;
|
||||
optimized->numvertexes++;
|
||||
} //end else
|
||||
} //end for
|
||||
optimized->edgeoptimizeindex[abs( edgenum )] = optimized->numedges;
|
||||
optedgenum = optimized->numedges;
|
||||
optimized->numedges++;
|
||||
//keep the edge reversed sign
|
||||
if ( edgenum > 0 ) {
|
||||
return optedgenum;
|
||||
} else { return -optedgenum;}
|
||||
} //end of the function AAS_OptimizeEdge
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_KeepFace( aas_face_t *face ) {
|
||||
if ( !( face->faceflags & FACE_LADDER ) ) {
|
||||
return 0;
|
||||
} else { return 1;}
|
||||
} //end of the function AAS_KeepFace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_OptimizeFace( optimized_t *optimized, int facenum ) {
|
||||
int i, edgenum, optedgenum, optfacenum;
|
||||
aas_face_t *face, *optface;
|
||||
|
||||
face = &( *aasworld ).faces[abs( facenum )];
|
||||
if ( !AAS_KeepFace( face ) ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
optfacenum = optimized->faceoptimizeindex[abs( facenum )];
|
||||
if ( optfacenum ) {
|
||||
//keep the face side sign
|
||||
if ( facenum > 0 ) {
|
||||
return optfacenum;
|
||||
} else { return -optfacenum;}
|
||||
} //end if
|
||||
|
||||
optface = &optimized->faces[optimized->numfaces];
|
||||
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
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
//returns true if a player can swim in this area
|
||||
int AAS_AreaSwim( int areanum );
|
||||
//returns true if the area is filled with a liquid
|
||||
int AAS_AreaLiquid( int areanum );
|
||||
//returns true if the area contains lava
|
||||
int AAS_AreaLava( int areanum );
|
||||
//returns true if the area contains slime
|
||||
int AAS_AreaSlime( int areanum );
|
||||
//returns true if the area has one or more ground faces
|
||||
int AAS_AreaGrounded( int areanum );
|
||||
//returns true if the area has one or more ladder faces
|
||||
int AAS_AreaLadder( int areanum );
|
||||
//returns true if the area is a jump pad
|
||||
int AAS_AreaJumpPad( int areanum );
|
||||
//returns true if the area is donotenter
|
||||
int AAS_AreaDoNotEnter( int areanum );
|
||||
//returns true if the area is donotenterlarge
|
||||
int AAS_AreaDoNotEnterLarge( int areanum );
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
//returns the travel time from the area to the goal area using the given travel flags
|
||||
int AAS_AreaTravelTimeToGoalAreaCheckLoop( int areanum, vec3_t origin, int goalareanum, int travelflags, int loopareanum );
|
||||
|
||||
extern int BotFuzzyPointReachabilityArea( vec3_t origin );
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_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;
|
||||
#ifdef DEBUG
|
||||
int startmillisecs;
|
||||
|
||||
startmillisecs = Sys_MilliSeconds();
|
||||
#endif
|
||||
|
||||
startareanum = AAS_PointAreaNum( start );
|
||||
if ( !startareanum ) {
|
||||
return 0;
|
||||
}
|
||||
goalareanum = AAS_PointAreaNum( goal );
|
||||
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 ) ) {
|
||||
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 > 1.5 * 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 > 1.5 * goaltraveltime ) {
|
||||
continue;
|
||||
}
|
||||
//this is a mid range area
|
||||
midrangeareas[i].valid = qtrue;
|
||||
midrangeareas[i].starttime = starttime;
|
||||
midrangeareas[i].goaltime = goaltime;
|
||||
Log_Write( "%d midrange area %d", nummidrangeareas, i );
|
||||
nummidrangeareas++;
|
||||
} //end for
|
||||
//
|
||||
for ( i = 1; i < ( *aasworld ).numareas; i++ )
|
||||
{
|
||||
if ( !midrangeareas[i].valid ) {
|
||||
continue;
|
||||
}
|
||||
//get the areas in one cluster
|
||||
numclusterareas = 0;
|
||||
AAS_AltRoutingFloodCluster_r( i );
|
||||
//now we've got a cluster with areas through which an alternative route could go
|
||||
//get the 'center' of the cluster
|
||||
VectorClear( mid );
|
||||
for ( j = 0; j < numclusterareas; j++ )
|
||||
{
|
||||
VectorAdd( mid, ( *aasworld ).areas[clusterareas[j]].center, mid );
|
||||
} //end for
|
||||
VectorScale( mid, 1.0 / numclusterareas, mid );
|
||||
//get the area closest to the center of the cluster
|
||||
bestdist = 999999;
|
||||
bestareanum = 0;
|
||||
for ( j = 0; j < numclusterareas; j++ )
|
||||
{
|
||||
VectorSubtract( mid, ( *aasworld ).areas[clusterareas[j]].center, dir );
|
||||
dist = VectorLength( dir );
|
||||
if ( dist < bestdist ) {
|
||||
bestdist = dist;
|
||||
bestareanum = clusterareas[j];
|
||||
} //end if
|
||||
} //end for
|
||||
//now we've got an area for an alternative route
|
||||
//FIXME: add alternative goal origin
|
||||
VectorCopy( ( *aasworld ).areas[bestareanum].center, altroutegoals[numaltroutegoals].origin );
|
||||
altroutegoals[numaltroutegoals].areanum = bestareanum;
|
||||
altroutegoals[numaltroutegoals].starttraveltime = midrangeareas[bestareanum].starttime;
|
||||
altroutegoals[numaltroutegoals].goaltraveltime = midrangeareas[bestareanum].goaltime;
|
||||
altroutegoals[numaltroutegoals].extratraveltime =
|
||||
( midrangeareas[bestareanum].starttime + midrangeareas[bestareanum].goaltime ) -
|
||||
goaltraveltime;
|
||||
numaltroutegoals++;
|
||||
//
|
||||
#ifdef 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
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
|
@ -0,0 +1,765 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
source = LoadSourceFile( charfile );
|
||||
if ( !source ) {
|
||||
botimport.Print( PRT_ERROR, "counldn't load %s\n", charfile );
|
||||
return NULL;
|
||||
} //end if
|
||||
ch = (bot_character_t *) GetClearedMemory( sizeof( bot_character_t ) +
|
||||
MAX_CHARACTERISTICS * sizeof( bot_characteristic_t ) );
|
||||
strcpy( ch->filename, charfile );
|
||||
while ( PC_ReadToken( source, &token ) )
|
||||
{
|
||||
if ( !strcmp( token.string, "skill" ) ) {
|
||||
if ( !PC_ExpectTokenType( source, TT_NUMBER, 0, &token ) ) {
|
||||
FreeSource( source );
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end if
|
||||
if ( !PC_ExpectTokenString( source, "{" ) ) {
|
||||
FreeSource( source );
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end if
|
||||
//if it's the correct skill
|
||||
if ( skill < 0 || token.intvalue == skill ) {
|
||||
foundcharacter = qtrue;
|
||||
ch->skill = token.intvalue;
|
||||
while ( PC_ExpectAnyToken( source, &token ) )
|
||||
{
|
||||
if ( !strcmp( token.string, "}" ) ) {
|
||||
break;
|
||||
}
|
||||
if ( token.type != TT_NUMBER || !( token.subtype & TT_INTEGER ) ) {
|
||||
SourceError( source, "expected integer index, found %s\n", token.string );
|
||||
FreeSource( source );
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end if
|
||||
index = token.intvalue;
|
||||
if ( index < 0 || index > MAX_CHARACTERISTICS ) {
|
||||
SourceError( source, "characteristic index out of range [0, %d]\n", MAX_CHARACTERISTICS );
|
||||
FreeSource( source );
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end if
|
||||
if ( ch->c[index].type ) {
|
||||
SourceError( source, "characteristic %d already initialized\n", index );
|
||||
FreeSource( source );
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end if
|
||||
if ( !PC_ExpectAnyToken( source, &token ) ) {
|
||||
FreeSource( source );
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end if
|
||||
if ( token.type == TT_NUMBER ) {
|
||||
if ( token.subtype & TT_FLOAT ) {
|
||||
ch->c[index].value._float = token.floatvalue;
|
||||
ch->c[index].type = CT_FLOAT;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
ch->c[index].value.integer = token.intvalue;
|
||||
ch->c[index].type = CT_INTEGER;
|
||||
} //end else
|
||||
} //end if
|
||||
else if ( token.type == TT_STRING ) {
|
||||
StripDoubleQuotes( token.string );
|
||||
ch->c[index].value.string = GetMemory( strlen( token.string ) + 1 );
|
||||
strcpy( ch->c[index].value.string, token.string );
|
||||
ch->c[index].type = CT_STRING;
|
||||
} //end else if
|
||||
else
|
||||
{
|
||||
SourceError( source, "expected integer, float or string, found %s\n", token.string );
|
||||
FreeSource( source );
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end else
|
||||
} //end if
|
||||
break;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
indent = 1;
|
||||
while ( indent )
|
||||
{
|
||||
if ( !PC_ExpectAnyToken( source, &token ) ) {
|
||||
FreeSource( source );
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end if
|
||||
if ( !strcmp( token.string, "{" ) ) {
|
||||
indent++;
|
||||
} else if ( !strcmp( token.string, "}" ) ) {
|
||||
indent--;
|
||||
}
|
||||
} //end while
|
||||
} //end else
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
SourceError( source, "unknown definition %s\n", token.string );
|
||||
FreeSource( source );
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end else
|
||||
} //end while
|
||||
FreeSource( source );
|
||||
//
|
||||
if ( !foundcharacter ) {
|
||||
BotFreeCharacterStrings( ch );
|
||||
FreeMemory( ch );
|
||||
return NULL;
|
||||
} //end if
|
||||
return ch;
|
||||
} //end of the function BotLoadCharacterFromFile
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int BotFindCachedCharacter( char *charfile, 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
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,547 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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: -
|
||||
//========================================================================
|
||||
int BotValidWeaponNumber( int weaponnum ) {
|
||||
if ( weaponnum <= 0 || weaponnum > weaponconfig->numweapons ) {
|
||||
botimport.Print( PRT_ERROR, "weapon number out of range\n" );
|
||||
return qfalse;
|
||||
} //end if
|
||||
return qtrue;
|
||||
} //end of the function BotValidWeaponNumber
|
||||
//========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//========================================================================
|
||||
bot_weaponstate_t *BotWeaponStateFromHandle( int handle ) {
|
||||
if ( handle <= 0 || handle > MAX_CLIENTS ) {
|
||||
botimport.Print( PRT_FATAL, "move state handle %d out of range\n", handle );
|
||||
return NULL;
|
||||
} //end if
|
||||
if ( !botweaponstates[handle] ) {
|
||||
botimport.Print( PRT_FATAL, "invalid move state %d\n", handle );
|
||||
return NULL;
|
||||
} //end if
|
||||
return botweaponstates[handle];
|
||||
} //end of the function BotWeaponStateFromHandle
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
#ifdef DEBUG_AI_WEAP
|
||||
void DumpWeaponConfig( weaponconfig_t *wc ) {
|
||||
FILE *fp;
|
||||
int i;
|
||||
|
||||
fp = Log_FileStruct();
|
||||
if ( !fp ) {
|
||||
return;
|
||||
}
|
||||
for ( i = 0; i < wc->numprojectiles; i++ )
|
||||
{
|
||||
WriteStructure( fp, &projectileinfo_struct, (char *) &wc->projectileinfo[i] );
|
||||
Log_Flush();
|
||||
} //end for
|
||||
for ( i = 0; i < wc->numweapons; i++ )
|
||||
{
|
||||
WriteStructure( fp, &weaponinfo_struct, (char *) &wc->weaponinfo[i] );
|
||||
Log_Flush();
|
||||
} //end for
|
||||
} //end of the function DumpWeaponConfig
|
||||
#endif //DEBUG_AI_WEAP
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
weaponconfig_t *LoadWeaponConfig( char *filename ) {
|
||||
int max_weaponinfo, max_projectileinfo;
|
||||
token_t token;
|
||||
char path[MAX_PATH];
|
||||
int i, j;
|
||||
source_t *source;
|
||||
weaponconfig_t *wc;
|
||||
weaponinfo_t weaponinfo;
|
||||
|
||||
max_weaponinfo = (int) LibVarValue( "max_weaponinfo", "32" );
|
||||
if ( max_weaponinfo < 0 ) {
|
||||
botimport.Print( PRT_ERROR, "max_weaponinfo = %d\n", max_weaponinfo );
|
||||
max_weaponinfo = 32;
|
||||
LibVarSet( "max_weaponinfo", "32" );
|
||||
} //end if
|
||||
max_projectileinfo = (int) LibVarValue( "max_projectileinfo", "32" );
|
||||
if ( max_projectileinfo < 0 ) {
|
||||
botimport.Print( PRT_ERROR, "max_projectileinfo = %d\n", max_projectileinfo );
|
||||
max_projectileinfo = 32;
|
||||
LibVarSet( "max_projectileinfo", "32" );
|
||||
} //end if
|
||||
strncpy( path, filename, MAX_PATH );
|
||||
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 );
|
||||
//
|
||||
ws->weaponweightconfig = ReadWeightConfig( filename );
|
||||
if ( !ws->weaponweightconfig ) {
|
||||
botimport.Print( PRT_FATAL, "couldn't load weapon config %s\n", filename );
|
||||
return BLERR_CANNOTLOADWEAPONWEIGHTS;
|
||||
} //end if
|
||||
if ( !weaponconfig ) {
|
||||
return BLERR_CANNOTLOADWEAPONCONFIG;
|
||||
}
|
||||
ws->weaponweightindex = WeaponWeightIndex( ws->weaponweightconfig, weaponconfig );
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function BotLoadWeaponWeights
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotGetWeaponInfo( int weaponstate, int weapon, weaponinfo_t *weaponinfo ) {
|
||||
bot_weaponstate_t *ws;
|
||||
|
||||
if ( !BotValidWeaponNumber( weapon ) ) {
|
||||
return;
|
||||
}
|
||||
ws = BotWeaponStateFromHandle( weaponstate );
|
||||
if ( !ws ) {
|
||||
return;
|
||||
}
|
||||
if ( !weaponconfig ) {
|
||||
return;
|
||||
}
|
||||
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;
|
||||
|
||||
file = LibVarString( "weaponconfig", "weapons.c" );
|
||||
weaponconfig = LoadWeaponConfig( file );
|
||||
if ( !weaponconfig ) {
|
||||
botimport.Print( PRT_FATAL, "couldn't load the weapon config\n" );
|
||||
return BLERR_CANNOTLOADWEAPONCONFIG;
|
||||
} //end if
|
||||
|
||||
#ifdef DEBUG_AI_WEAP
|
||||
DumpWeaponConfig( weaponconfig );
|
||||
#endif //DEBUG_AI_WEAP
|
||||
//
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function BotSetupWeaponAI
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotShutdownWeaponAI( void ) {
|
||||
int i;
|
||||
|
||||
if ( weaponconfig ) {
|
||||
FreeMemory( weaponconfig );
|
||||
}
|
||||
weaponconfig = NULL;
|
||||
|
||||
for ( i = 1; i <= MAX_CLIENTS; i++ )
|
||||
{
|
||||
if ( botweaponstates[i] ) {
|
||||
BotFreeWeaponState( i );
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function BotShutdownWeaponAI
|
||||
|
|
@ -0,0 +1,972 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
botimport.Print( PRT_MESSAGE, "loaded %s\n", filename );
|
||||
#ifdef DEBUG
|
||||
if ( bot_developer ) {
|
||||
botimport.Print( PRT_MESSAGE, "weights loaded in %d msec\n", Sys_MilliSeconds() - starttime );
|
||||
} //end if
|
||||
#endif //DEBUG
|
||||
//
|
||||
if ( !LibVarGetValue( "bot_reloadcharacters" ) ) {
|
||||
weightFileList[avail] = config;
|
||||
} //end if
|
||||
//
|
||||
return config;
|
||||
} //end of the function ReadWeightConfig
|
||||
#if 0
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean WriteFuzzyWeight( FILE *fp, fuzzyseperator_t *fs ) {
|
||||
if ( fs->type == WT_BALANCE ) {
|
||||
if ( fprintf( fp, " return balance(" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( !WriteFloat( fp, fs->weight ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fprintf( fp, "," ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( !WriteFloat( fp, fs->minweight ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fprintf( fp, "," ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( !WriteFloat( fp, fs->maxweight ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fprintf( fp, ");\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if ( fprintf( fp, " return " ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( !WriteFloat( fp, fs->weight ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fprintf( fp, ";\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end else
|
||||
return qtrue;
|
||||
} //end of the function WriteFuzzyWeight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean WriteFuzzySeperators_r( FILE *fp, fuzzyseperator_t *fs, int indent ) {
|
||||
if ( !WriteIndent( fp, indent ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fprintf( fp, "switch(%d)\n", fs->index ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( !WriteIndent( fp, indent ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fprintf( fp, "{\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
indent++;
|
||||
do
|
||||
{
|
||||
if ( !WriteIndent( fp, indent ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fs->next ) {
|
||||
if ( fprintf( fp, "case %d:", fs->value ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if ( fprintf( fp, "default:" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end else
|
||||
if ( fs->child ) {
|
||||
if ( fprintf( fp, "\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( !WriteIndent( fp, indent ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fprintf( fp, "{\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( !WriteFuzzySeperators_r( fp, fs->child, indent + 1 ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( !WriteIndent( fp, indent ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fs->next ) {
|
||||
if ( fprintf( fp, "} //end case\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if ( fprintf( fp, "} //end default\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end else
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if ( !WriteFuzzyWeight( fp, fs ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end else
|
||||
fs = fs->next;
|
||||
} while ( fs );
|
||||
indent--;
|
||||
if ( !WriteIndent( fp, indent ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fprintf( fp, "} //end switch\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
return qtrue;
|
||||
} //end of the function WriteItemFuzzyWeights_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean WriteWeightConfig( char *filename, weightconfig_t *config ) {
|
||||
int i;
|
||||
FILE *fp;
|
||||
weight_t *ifw;
|
||||
|
||||
fp = fopen( filename, "wb" );
|
||||
if ( !fp ) {
|
||||
return qfalse;
|
||||
}
|
||||
|
||||
for ( i = 0; i < config->numweights; i++ )
|
||||
{
|
||||
ifw = &config->weights[i];
|
||||
if ( fprintf( fp, "\nweight \"%s\"\n", ifw->name ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( fprintf( fp, "{\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( ifw->firstseperator->index > 0 ) {
|
||||
if ( !WriteFuzzySeperators_r( fp, ifw->firstseperator, 1 ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if ( !WriteIndent( fp, 1 ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
if ( !WriteFuzzyWeight( fp, ifw->firstseperator ) ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end else
|
||||
if ( fprintf( fp, "} //end weight\n" ) < 0 ) {
|
||||
return qfalse;
|
||||
}
|
||||
} //end for
|
||||
fclose( fp );
|
||||
return qtrue;
|
||||
} //end of the function WriteWeightConfig
|
||||
#endif
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int FindFuzzyWeight( weightconfig_t *wc, char *name ) {
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < wc->numweights; i++ )
|
||||
{
|
||||
if ( !strcmp( wc->weights[i].name, name ) ) {
|
||||
return i;
|
||||
} //end if
|
||||
} //end if
|
||||
return -1;
|
||||
} //end of the function FindFuzzyWeight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float FuzzyWeight_r( int *inventory, fuzzyseperator_t *fs ) {
|
||||
float scale, w1, w2;
|
||||
|
||||
if ( inventory[fs->index] < fs->value ) {
|
||||
if ( fs->child ) {
|
||||
return FuzzyWeight_r( inventory, fs->child );
|
||||
} else { return fs->weight;}
|
||||
} //end if
|
||||
else if ( fs->next ) {
|
||||
if ( inventory[fs->index] < fs->next->value ) {
|
||||
//first weight
|
||||
if ( fs->child ) {
|
||||
w1 = FuzzyWeight_r( inventory, fs->child );
|
||||
} else { w1 = fs->weight;}
|
||||
//second weight
|
||||
if ( fs->next->child ) {
|
||||
w2 = FuzzyWeight_r( inventory, fs->next->child );
|
||||
} else { w2 = fs->next->weight;}
|
||||
//the scale factor
|
||||
scale = ( inventory[fs->index] - fs->value ) / ( fs->next->value - fs->value );
|
||||
//scale between the two weights
|
||||
return scale * w1 + ( 1 - scale ) * w2;
|
||||
} //end if
|
||||
return FuzzyWeight_r( inventory, fs->next );
|
||||
} //end else if
|
||||
return fs->weight;
|
||||
} //end of the function FuzzyWeight_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float FuzzyWeightUndecided_r( int *inventory, fuzzyseperator_t *fs ) {
|
||||
float scale, w1, w2;
|
||||
|
||||
if ( inventory[fs->index] < fs->value ) {
|
||||
if ( fs->child ) {
|
||||
return FuzzyWeightUndecided_r( inventory, fs->child );
|
||||
} else { return fs->minweight + random() * ( fs->maxweight - fs->minweight );}
|
||||
} //end if
|
||||
else if ( fs->next ) {
|
||||
if ( inventory[fs->index] < fs->next->value ) {
|
||||
//first weight
|
||||
if ( fs->child ) {
|
||||
w1 = FuzzyWeightUndecided_r( inventory, fs->child );
|
||||
} else { w1 = fs->minweight + random() * ( fs->maxweight - fs->minweight );}
|
||||
//second weight
|
||||
if ( fs->next->child ) {
|
||||
w2 = FuzzyWeight_r( inventory, fs->next->child );
|
||||
} else { w2 = fs->next->minweight + random() * ( fs->next->maxweight - fs->next->minweight );}
|
||||
//the scale factor
|
||||
scale = ( inventory[fs->index] - fs->value ) / ( fs->next->value - fs->value );
|
||||
//scale between the two weights
|
||||
return scale * w1 + ( 1 - scale ) * w2;
|
||||
} //end if
|
||||
return FuzzyWeightUndecided_r( inventory, fs->next );
|
||||
} //end else if
|
||||
return fs->weight;
|
||||
} //end of the function FuzzyWeightUndecided_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float FuzzyWeight( int *inventory, weightconfig_t *wc, int weightnum ) {
|
||||
#ifdef EVALUATERECURSIVELY
|
||||
return FuzzyWeight_r( inventory, wc->weights[weightnum].firstseperator );
|
||||
#else
|
||||
fuzzyseperator_t *s;
|
||||
|
||||
s = wc->weights[weightnum].firstseperator;
|
||||
if ( !s ) {
|
||||
return 0;
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
if ( inventory[s->index] < s->value ) {
|
||||
if ( s->child ) {
|
||||
s = s->child;
|
||||
} else { return s->weight;}
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if ( s->next ) {
|
||||
s = s->next;
|
||||
} else { return s->weight;}
|
||||
} //end else
|
||||
} //end if
|
||||
return 0;
|
||||
#endif
|
||||
} //end of the function FuzzyWeight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
float FuzzyWeightUndecided( int *inventory, weightconfig_t *wc, int weightnum ) {
|
||||
#ifdef EVALUATERECURSIVELY
|
||||
return FuzzyWeightUndecided_r( inventory, wc->weights[weightnum].firstseperator );
|
||||
#else
|
||||
fuzzyseperator_t *s;
|
||||
|
||||
s = wc->weights[weightnum].firstseperator;
|
||||
if ( !s ) {
|
||||
return 0;
|
||||
}
|
||||
while ( 1 )
|
||||
{
|
||||
if ( inventory[s->index] < s->value ) {
|
||||
if ( s->child ) {
|
||||
s = s->child;
|
||||
} else { return s->minweight + random() * ( s->maxweight - s->minweight );}
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if ( s->next ) {
|
||||
s = s->next;
|
||||
} else { return s->minweight + random() * ( s->maxweight - s->minweight );}
|
||||
} //end else
|
||||
} //end if
|
||||
return 0;
|
||||
#endif
|
||||
} //end of the function FuzzyWeightUndecided
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EvolveFuzzySeperator_r( fuzzyseperator_t *fs ) {
|
||||
if ( fs->child ) {
|
||||
EvolveFuzzySeperator_r( fs->child );
|
||||
} //end if
|
||||
else if ( fs->type == WT_BALANCE ) {
|
||||
//every once in a while an evolution leap occurs, mutation
|
||||
if ( random() < 0.01 ) {
|
||||
fs->weight += crandom() * ( fs->maxweight - fs->minweight );
|
||||
} else { fs->weight += crandom() * ( fs->maxweight - fs->minweight ) * 0.5;}
|
||||
//modify bounds if necesary because of mutation
|
||||
if ( fs->weight < fs->minweight ) {
|
||||
fs->minweight = fs->weight;
|
||||
} else if ( fs->weight > fs->maxweight ) {
|
||||
fs->maxweight = fs->weight;
|
||||
}
|
||||
} //end else if
|
||||
if ( fs->next ) {
|
||||
EvolveFuzzySeperator_r( fs->next );
|
||||
}
|
||||
} //end of the function EvolveFuzzySeperator_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void EvolveWeightConfig( weightconfig_t *config ) {
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < config->numweights; i++ )
|
||||
{
|
||||
EvolveFuzzySeperator_r( config->weights[i].firstseperator );
|
||||
} //end for
|
||||
} //end of the function EvolveWeightConfig
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void ScaleFuzzySeperator_r( fuzzyseperator_t *fs, float scale ) {
|
||||
if ( fs->child ) {
|
||||
ScaleFuzzySeperator_r( fs->child, scale );
|
||||
} //end if
|
||||
else if ( fs->type == WT_BALANCE ) {
|
||||
//
|
||||
fs->weight = ( fs->maxweight + fs->minweight ) * scale;
|
||||
//get the weight between bounds
|
||||
if ( fs->weight < fs->minweight ) {
|
||||
fs->weight = fs->minweight;
|
||||
} else if ( fs->weight > fs->maxweight ) {
|
||||
fs->weight = fs->maxweight;
|
||||
}
|
||||
} //end else if
|
||||
if ( fs->next ) {
|
||||
ScaleFuzzySeperator_r( fs->next, scale );
|
||||
}
|
||||
} //end of the function ScaleFuzzySeperator_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void ScaleWeight( weightconfig_t *config, char *name, float scale ) {
|
||||
int i;
|
||||
|
||||
if ( scale < 0 ) {
|
||||
scale = 0;
|
||||
} else if ( scale > 1 ) {
|
||||
scale = 1;
|
||||
}
|
||||
for ( i = 0; i < config->numweights; i++ )
|
||||
{
|
||||
if ( !strcmp( name, config->weights[i].name ) ) {
|
||||
ScaleFuzzySeperator_r( config->weights[i].firstseperator, scale );
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function ScaleWeight
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void ScaleFuzzySeperatorBalanceRange_r( fuzzyseperator_t *fs, float scale ) {
|
||||
if ( fs->child ) {
|
||||
ScaleFuzzySeperatorBalanceRange_r( fs->child, scale );
|
||||
} //end if
|
||||
else if ( fs->type == WT_BALANCE ) {
|
||||
float mid = ( fs->minweight + fs->maxweight ) * 0.5;
|
||||
//get the weight between bounds
|
||||
fs->maxweight = mid + ( fs->maxweight - mid ) * scale;
|
||||
fs->minweight = mid + ( fs->minweight - mid ) * scale;
|
||||
if ( fs->maxweight < fs->minweight ) {
|
||||
fs->maxweight = fs->minweight;
|
||||
} //end if
|
||||
} //end else if
|
||||
if ( fs->next ) {
|
||||
ScaleFuzzySeperatorBalanceRange_r( fs->next, scale );
|
||||
}
|
||||
} //end of the function ScaleFuzzySeperatorBalanceRange_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void ScaleFuzzyBalanceRange( weightconfig_t *config, float scale ) {
|
||||
int i;
|
||||
|
||||
if ( scale < 0 ) {
|
||||
scale = 0;
|
||||
} else if ( scale > 100 ) {
|
||||
scale = 100;
|
||||
}
|
||||
for ( i = 0; i < config->numweights; i++ )
|
||||
{
|
||||
ScaleFuzzySeperatorBalanceRange_r( config->weights[i].firstseperator, scale );
|
||||
} //end for
|
||||
} //end of the function ScaleFuzzyBalanceRange
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int InterbreedFuzzySeperator_r( fuzzyseperator_t *fs1, fuzzyseperator_t *fs2,
|
||||
fuzzyseperator_t *fsout ) {
|
||||
if ( fs1->child ) {
|
||||
if ( !fs2->child || !fsout->child ) {
|
||||
botimport.Print( PRT_ERROR, "cannot interbreed weight configs, unequal child\n" );
|
||||
return qfalse;
|
||||
} //end if
|
||||
if ( !InterbreedFuzzySeperator_r( fs2->child, fs2->child, fsout->child ) ) {
|
||||
return qfalse;
|
||||
} //end if
|
||||
} //end if
|
||||
else if ( fs1->type == WT_BALANCE ) {
|
||||
if ( fs2->type != WT_BALANCE || fsout->type != WT_BALANCE ) {
|
||||
botimport.Print( PRT_ERROR, "cannot interbreed weight configs, unequal balance\n" );
|
||||
return qfalse;
|
||||
} //end if
|
||||
fsout->weight = ( fs1->weight + fs2->weight ) / 2;
|
||||
if ( fsout->weight > fsout->maxweight ) {
|
||||
fsout->maxweight = fsout->weight;
|
||||
}
|
||||
if ( fsout->weight > fsout->minweight ) {
|
||||
fsout->minweight = fsout->weight;
|
||||
}
|
||||
} //end else if
|
||||
if ( fs1->next ) {
|
||||
if ( !fs2->next || !fsout->next ) {
|
||||
botimport.Print( PRT_ERROR, "cannot interbreed weight configs, unequal next\n" );
|
||||
return qfalse;
|
||||
} //end if
|
||||
if ( !InterbreedFuzzySeperator_r( fs1->next, fs2->next, fsout->next ) ) {
|
||||
return qfalse;
|
||||
} //end if
|
||||
} //end if
|
||||
return qtrue;
|
||||
} //end of the function InterbreedFuzzySeperator_r
|
||||
//===========================================================================
|
||||
// config1 and config2 are interbreeded and stored in configout
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void InterbreedWeightConfigs( weightconfig_t *config1, weightconfig_t *config2,
|
||||
weightconfig_t *configout ) {
|
||||
int i;
|
||||
|
||||
if ( config1->numweights != config2->numweights ||
|
||||
config1->numweights != configout->numweights ) {
|
||||
botimport.Print( PRT_ERROR, "cannot interbreed weight configs, unequal numweights\n" );
|
||||
return;
|
||||
} //end if
|
||||
for ( i = 0; i < config1->numweights; i++ )
|
||||
{
|
||||
InterbreedFuzzySeperator_r( config1->weights[i].firstseperator,
|
||||
config2->weights[i].firstseperator,
|
||||
configout->weights[i].firstseperator );
|
||||
} //end for
|
||||
} //end of the function InterbreedWeightConfigs
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void BotShutdownWeights( void ) {
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < MAX_WEIGHT_FILES; i++ )
|
||||
{
|
||||
if ( weightFileList[i] ) {
|
||||
FreeWeightConfig2( weightFileList[i] );
|
||||
weightFileList[i] = NULL;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end of the function BotShutdownWeights
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
|
@ -0,0 +1,480 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_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
|
|
@ -0,0 +1,936 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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: -
|
||||
//===========================================================================
|
||||
int Export_BotLibSetup( void ) {
|
||||
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", "2048" );
|
||||
|
||||
errnum = AAS_Setup(); //be_aas_main.c
|
||||
if ( errnum != BLERR_NOERROR ) {
|
||||
return errnum;
|
||||
}
|
||||
errnum = EA_Setup(); //be_ea.c
|
||||
if ( errnum != BLERR_NOERROR ) {
|
||||
return errnum;
|
||||
}
|
||||
// errnum = BotSetupWeaponAI(); //be_ai_weap.c
|
||||
// if (errnum != BLERR_NOERROR)return errnum;
|
||||
// errnum = BotSetupGoalAI(); //be_ai_goal.c
|
||||
// if (errnum != BLERR_NOERROR) return errnum;
|
||||
// errnum = BotSetupChatAI(); //be_ai_chat.c
|
||||
// if (errnum != BLERR_NOERROR) return errnum;
|
||||
errnum = BotSetupMoveAI(); //be_ai_move.c
|
||||
if ( errnum != BLERR_NOERROR ) {
|
||||
return errnum;
|
||||
}
|
||||
|
||||
botlibsetup = qtrue;
|
||||
botlibglobals.botlibsetup = qtrue;
|
||||
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function Export_BotLibSetup
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Export_BotLibShutdown( void ) {
|
||||
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: -
|
||||
//===========================================================================
|
||||
int Export_BotLibLoadMap( const char *mapname ) {
|
||||
#ifdef DEBUG
|
||||
int starttime = Sys_MilliSeconds();
|
||||
#endif
|
||||
int errnum;
|
||||
|
||||
if ( !BotLibSetup( "BotLoadMap" ) ) {
|
||||
return BLERR_LIBRARYNOTSETUP;
|
||||
}
|
||||
//
|
||||
botimport.Print( PRT_MESSAGE, "------------ Map Loading ------------\n" );
|
||||
//startup AAS for the current map, model and sound index
|
||||
errnum = AAS_LoadMap( mapname );
|
||||
if ( errnum != BLERR_NOERROR ) {
|
||||
return errnum;
|
||||
}
|
||||
//initialize the items in the level
|
||||
BotInitLevelItems(); //be_ai_goal.h
|
||||
BotSetBrushModelTypes(); //be_ai_move.h
|
||||
//
|
||||
botimport.Print( PRT_MESSAGE, "-------------------------------------\n" );
|
||||
#ifdef DEBUG
|
||||
botimport.Print( PRT_MESSAGE, "map loaded in %d msec\n", Sys_MilliSeconds() - starttime );
|
||||
#endif
|
||||
//
|
||||
return BLERR_NOERROR;
|
||||
} //end of the function Export_BotLibLoadMap
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int Export_BotLibUpdateEntity( int ent, bot_entitystate_t *state ) {
|
||||
if ( !BotLibSetup( "BotUpdateEntity" ) ) {
|
||||
return BLERR_LIBRARYNOTSETUP;
|
||||
}
|
||||
if ( !ValidEntityNumber( ent, "BotUpdateEntity" ) ) {
|
||||
return BLERR_INVALIDENTITYNUMBER;
|
||||
}
|
||||
|
||||
return AAS_UpdateEntity( ent, state );
|
||||
} //end of the function Export_BotLibUpdateEntity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_TestMovementPrediction( int entnum, vec3_t origin, vec3_t dir );
|
||||
void ElevatorBottomCenter( aas_reachability_t *reach, vec3_t bottomcenter );
|
||||
int BotGetReachabilityToGoal( vec3_t origin, int areanum, int 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 );
|
||||
|
||||
int AAS_FindAttackSpotWithinRange( int srcnum, int rangenum, int enemynum, float rangedist, int travelflags, float *outpos );
|
||||
|
||||
qboolean AAS_GetRouteFirstVisPos( vec3_t srcpos, vec3_t destpos, int travelflags, vec3_t retpos );
|
||||
|
||||
void AAS_SetAASBlockingEntity( vec3_t absmin, vec3_t absmax, qboolean blocking );
|
||||
|
||||
int BotExportTest( int parm0, char *parm1, vec3_t parm2, vec3_t parm3 ) {
|
||||
|
||||
// return AAS_PointLight(parm2, NULL, NULL, NULL);
|
||||
|
||||
#ifdef DEBUG
|
||||
static int area = -1;
|
||||
static int line[2];
|
||||
int newarea, i, highlightarea, bot_testhidepos, hideposarea, bot_testroutevispos;
|
||||
// int reachnum;
|
||||
vec3_t eye, forward, right, end, origin;
|
||||
// vec3_t bottomcenter;
|
||||
// aas_trace_t trace;
|
||||
// aas_face_t *face;
|
||||
// aas_entity_t *ent;
|
||||
// bsp_trace_t bsptrace;
|
||||
// aas_reachability_t reach;
|
||||
// bot_goal_t goal;
|
||||
|
||||
// clock_t start_time, end_time;
|
||||
vec3_t mins = {-16, -16, -24};
|
||||
vec3_t maxs = {16, 16, 32};
|
||||
// int areas[10], numareas;
|
||||
|
||||
|
||||
//return 0;
|
||||
|
||||
if ( !( *aasworld ).loaded ) {
|
||||
return 0;
|
||||
}
|
||||
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( -1, origin, AAS_PointAreaNum( origin ), 0,
|
||||
botlibglobals.goalorigin, botlibglobals.goalareanum, TFL_DEFAULT );
|
||||
|
||||
if ( bot_testhidepos > 1 ) {
|
||||
if ( hideposarea ) {
|
||||
botimport.Print( PRT_MESSAGE, "hidepos (%i) %2.1f %2.1f %2.1f\n",
|
||||
hideposarea,
|
||||
( *aasworld ).areawaypoints[hideposarea][0],
|
||||
( *aasworld ).areawaypoints[hideposarea][1],
|
||||
( *aasworld ).areawaypoints[hideposarea][2] );
|
||||
} else {
|
||||
botimport.Print( PRT_MESSAGE, "no hidepos found\n" );
|
||||
}
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
|
||||
bot_testroutevispos = LibVarGetValue( "bot_testroutevispos" );
|
||||
if ( bot_testroutevispos ) {
|
||||
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();
|
||||
AAS_GetRouteFirstVisPos( botlibglobals.goalorigin, origin, TFL_DEFAULT, eye );
|
||||
//area we are currently in
|
||||
AAS_ShowAreaPolygons( newarea, 1, qtrue );
|
||||
//enemy position
|
||||
AAS_ShowAreaPolygons( botlibglobals.goalareanum, 2, qtrue );
|
||||
//area that is visible in path from enemy pos
|
||||
hideposarea = BotFuzzyPointReachabilityArea( eye );
|
||||
AAS_ShowAreaPolygons( hideposarea, 4, qtrue );
|
||||
return 0;
|
||||
}
|
||||
|
||||
//if (AAS_AgainstLadder(parm2)) botimport.Print(PRT_MESSAGE, "against ladder\n");
|
||||
//BotOnGround(parm2, PRESENCE_NORMAL, 1, &newarea, &newarea);
|
||||
//botimport.Print(PRT_MESSAGE, "%f %f %f\n", parm2[0], parm2[1], parm2[2]);
|
||||
//*
|
||||
highlightarea = LibVarGetValue( "bot_highlightarea" );
|
||||
if ( highlightarea > 0 ) {
|
||||
newarea = highlightarea;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
VectorCopy( parm2, origin );
|
||||
origin[2] += 0.5;
|
||||
//newarea = AAS_PointAreaNum(origin);
|
||||
newarea = BotFuzzyPointReachabilityArea( origin );
|
||||
} //end else
|
||||
|
||||
botimport.Print( PRT_MESSAGE, "\rtravel time to goal (%d) = %d ", botlibglobals.goalareanum,
|
||||
AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT ) );
|
||||
//newarea = BotReachabilityArea(origin, qtrue);
|
||||
if ( newarea != area ) {
|
||||
botimport.Print( PRT_MESSAGE, "origin = %f, %f, %f\n", origin[0], origin[1], origin[2] );
|
||||
area = newarea;
|
||||
botimport.Print( PRT_MESSAGE, "new area %d, cluster %d, presence type %d\n",
|
||||
area, AAS_AreaCluster( area ), AAS_PointPresenceType( origin ) );
|
||||
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_WATER ) {
|
||||
botimport.Print( PRT_MESSAGE, "water " );
|
||||
} //end if
|
||||
if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_LAVA ) {
|
||||
botimport.Print( PRT_MESSAGE, "lava " );
|
||||
} //end if
|
||||
if ( ( *aasworld ).areasettings[area].contents & AREACONTENTS_SLIME ) {
|
||||
// botimport.Print(PRT_MESSAGE, "slime ");
|
||||
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
|
||||
if ( ( *aasworld ).areasettings[area].areaflags & AREA_DISABLED ) {
|
||||
botimport.Print( PRT_MESSAGE, "DISABLED" );
|
||||
} //end if
|
||||
botimport.Print( PRT_MESSAGE, "\n" );
|
||||
botimport.Print( PRT_MESSAGE, "travel time to goal (%d) = %d\n", botlibglobals.goalareanum,
|
||||
AAS_AreaTravelTimeToGoalArea( newarea, origin, botlibglobals.goalareanum, TFL_DEFAULT | TFL_ROCKETJUMP ) );
|
||||
/*
|
||||
VectorCopy(origin, end);
|
||||
end[2] += 5;
|
||||
numareas = AAS_TraceAreas(origin, end, areas, NULL, 10);
|
||||
AAS_TraceClientBBox(origin, end, PRESENCE_CROUCH, -1);
|
||||
botimport.Print(PRT_MESSAGE, "num areas = %d, area = %d\n", numareas, areas[0]);
|
||||
*/
|
||||
/*
|
||||
botlibglobals.goalareanum = newarea;
|
||||
VectorCopy(parm2, botlibglobals.goalorigin);
|
||||
botimport.Print(PRT_MESSAGE, "new goal %2.1f %2.1f %2.1f area %d\n",
|
||||
origin[0], origin[1], origin[2], newarea);
|
||||
*/
|
||||
} //end if
|
||||
//*
|
||||
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 );
|
||||
} //end if*/
|
||||
// if (parm0 & BUTTON_USE)
|
||||
// {
|
||||
// botlibglobals.runai = !botlibglobals.runai;
|
||||
// if (botlibglobals.runai) botimport.Print(PRT_MESSAGE, "started AI\n");
|
||||
// else botimport.Print(PRT_MESSAGE, "stopped AI\n");
|
||||
//* /
|
||||
/*
|
||||
goal.areanum = botlibglobals.goalareanum;
|
||||
reachnum = BotGetReachabilityToGoal(parm2, newarea, 1,
|
||||
ms.avoidreach, ms.avoidreachtimes,
|
||||
&goal, TFL_DEFAULT);
|
||||
if (!reachnum)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "goal not reachable\n");
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
AAS_ReachabilityFromNum(reachnum, &reach);
|
||||
AAS_ClearShownDebugLines();
|
||||
AAS_ShowArea(area, qtrue);
|
||||
AAS_ShowArea(reach.areanum, qtrue);
|
||||
AAS_DrawCross(reach.start, 6, LINECOLOR_BLUE);
|
||||
AAS_DrawCross(reach.end, 6, LINECOLOR_RED);
|
||||
//
|
||||
if (reach.traveltype == TRAVEL_ELEVATOR)
|
||||
{
|
||||
ElevatorBottomCenter(&reach, bottomcenter);
|
||||
AAS_DrawCross(bottomcenter, 10, LINECOLOR_GREEN);
|
||||
} //end if
|
||||
} //end else*/
|
||||
// botimport.Print(PRT_MESSAGE, "travel time to goal = %d\n",
|
||||
// AAS_AreaTravelTimeToGoalArea(area, origin, botlibglobals.goalareanum, TFL_DEFAULT));
|
||||
// botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n");
|
||||
// AAS_Reachability_WeaponJump(703, 716);
|
||||
// } //end if*/
|
||||
|
||||
/* face = AAS_AreaGroundFace(newarea, parm2);
|
||||
if (face)
|
||||
{
|
||||
AAS_ShowFace(face - (*aasworld).faces);
|
||||
} //end if*/
|
||||
/*
|
||||
AAS_ClearShownDebugLines();
|
||||
AAS_ShowArea(newarea, parm0 & BUTTON_USE);
|
||||
AAS_ShowReachableAreas(area);
|
||||
*/
|
||||
AAS_ClearShownPolygons();
|
||||
AAS_ClearShownDebugLines();
|
||||
AAS_ShowAreaPolygons( newarea, 1, parm0 & 4 );
|
||||
if ( parm0 & 2 ) {
|
||||
AAS_ShowReachableAreas( area );
|
||||
} else
|
||||
{
|
||||
static int lastgoalareanum, lastareanum;
|
||||
static int avoidreach[MAX_AVOIDREACH];
|
||||
static float avoidreachtimes[MAX_AVOIDREACH];
|
||||
static int avoidreachtries[MAX_AVOIDREACH];
|
||||
int reachnum;
|
||||
bot_goal_t goal;
|
||||
aas_reachability_t reach;
|
||||
|
||||
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 | TFL_FUNCBOB );
|
||||
AAS_ReachabilityFromNum( reachnum, &reach );
|
||||
AAS_ShowReachability( &reach );
|
||||
} //end else
|
||||
VectorClear( forward );
|
||||
//BotGapDistance(origin, forward, 0);
|
||||
/*
|
||||
if (parm0 & BUTTON_USE)
|
||||
{
|
||||
botimport.Print(PRT_MESSAGE, "test rj from 703 to 716\n");
|
||||
AAS_Reachability_WeaponJump(703, 716);
|
||||
} //end if*/
|
||||
|
||||
AngleVectors( parm3, forward, right, NULL );
|
||||
//get the eye 16 units to the right of the origin
|
||||
VectorMA( parm2, 8, right, eye );
|
||||
//get the eye 24 units up
|
||||
eye[2] += 24;
|
||||
//get the end point for the line to be traced
|
||||
VectorMA( eye, 800, forward, end );
|
||||
|
||||
// AAS_TestMovementPrediction(1, parm2, forward);
|
||||
/* //trace the line to find the hit point
|
||||
trace = AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1);
|
||||
if (!line[0]) line[0] = botimport.DebugLineCreate();
|
||||
botimport.DebugLineShow(line[0], eye, trace.endpos, LINECOLOR_BLUE);
|
||||
//
|
||||
AAS_ClearShownDebugLines();
|
||||
if (trace.ent)
|
||||
{
|
||||
ent = &(*aasworld).entities[trace.ent];
|
||||
AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
|
||||
} //end if*/
|
||||
|
||||
/*
|
||||
start_time = clock();
|
||||
for (i = 0; i < 2000; i++)
|
||||
{
|
||||
AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
|
||||
// AAS_TraceClientBBox(eye, end, PRESENCE_NORMAL, 1);
|
||||
} //end for
|
||||
end_time = clock();
|
||||
botimport.Print(PRT_MESSAGE, "me %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC);
|
||||
start_time = clock();
|
||||
for (i = 0; i < 2000; i++)
|
||||
{
|
||||
AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
|
||||
} //end for
|
||||
end_time = clock();
|
||||
botimport.Print(PRT_MESSAGE, "id %lu clocks, %lu CLOCKS_PER_SEC\n", end_time - start_time, CLOCKS_PER_SEC);
|
||||
*/
|
||||
|
||||
/*
|
||||
AAS_ClearShownDebugLines();
|
||||
//bsptrace = AAS_Trace(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID);
|
||||
bsptrace = AAS_Trace(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
|
||||
if (!line[0]) line[0] = botimport.DebugLineCreate();
|
||||
botimport.DebugLineShow(line[0], eye, bsptrace.endpos, LINECOLOR_YELLOW);
|
||||
if (bsptrace.fraction < 1.0)
|
||||
{
|
||||
face = AAS_TraceEndFace(&trace);
|
||||
if (face)
|
||||
{
|
||||
AAS_ShowFace(face - (*aasworld).faces);
|
||||
} //end if
|
||||
AAS_DrawPlaneCross(bsptrace.endpos,
|
||||
bsptrace.plane.normal,
|
||||
bsptrace.plane.dist + bsptrace.exp_dist,
|
||||
bsptrace.plane.type, LINECOLOR_GREEN);
|
||||
if (trace.ent)
|
||||
{
|
||||
ent = &(*aasworld).entities[trace.ent];
|
||||
AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
|
||||
} //end if
|
||||
} //end if*/
|
||||
/*/
|
||||
//bsptrace = AAS_Trace2(eye, NULL, NULL, end, 1, MASK_PLAYERSOLID);
|
||||
bsptrace = AAS_Trace2(eye, mins, maxs, end, 1, MASK_PLAYERSOLID);
|
||||
botimport.DebugLineShow(line[1], eye, bsptrace.endpos, LINECOLOR_BLUE);
|
||||
if (bsptrace.fraction < 1.0)
|
||||
{
|
||||
AAS_DrawPlaneCross(bsptrace.endpos,
|
||||
bsptrace.plane.normal,
|
||||
bsptrace.plane.dist,// + bsptrace.exp_dist,
|
||||
bsptrace.plane.type, LINECOLOR_RED);
|
||||
if (bsptrace.ent)
|
||||
{
|
||||
ent = &(*aasworld).entities[bsptrace.ent];
|
||||
AAS_ShowBoundingBox(ent->origin, ent->mins, ent->maxs);
|
||||
} //end if
|
||||
} //end if
|
||||
*/
|
||||
#endif
|
||||
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;
|
||||
//--------------------------------------------
|
||||
// be_aas_bspq3.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_PointContents = AAS_PointContents;
|
||||
aas->AAS_NextBSPEntity = AAS_NextBSPEntity;
|
||||
aas->AAS_ValueForBSPEpairKey = AAS_ValueForBSPEpairKey;
|
||||
aas->AAS_VectorForBSPEpairKey = AAS_VectorForBSPEpairKey;
|
||||
aas->AAS_FloatForBSPEpairKey = AAS_FloatForBSPEpairKey;
|
||||
aas->AAS_IntForBSPEpairKey = AAS_IntForBSPEpairKey;
|
||||
//--------------------------------------------
|
||||
// be_aas_reach.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_AreaReachability = AAS_AreaReachability;
|
||||
//--------------------------------------------
|
||||
// be_aas_route.c
|
||||
//--------------------------------------------
|
||||
aas->AAS_AreaTravelTimeToGoalArea = AAS_AreaTravelTimeToGoalArea;
|
||||
//--------------------------------------------
|
||||
// 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_GetRouteFirstVisPos = AAS_GetRouteFirstVisPos;
|
||||
aas->AAS_SetAASBlockingEntity = AAS_SetAASBlockingEntity;
|
||||
// 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_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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
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_LoadSourceHandle = PC_LoadSourceHandle;
|
||||
be_botlib_export.PC_FreeSourceHandle = PC_FreeSourceHandle;
|
||||
be_botlib_export.PC_ReadTokenHandle = PC_ReadTokenHandle;
|
||||
be_botlib_export.PC_SourceFileAndLine = PC_SourceFileAndLine;
|
||||
|
||||
be_botlib_export.BotLibStartFrame = Export_BotLibStartFrame;
|
||||
be_botlib_export.BotLibLoadMap = Export_BotLibLoadMap;
|
||||
be_botlib_export.BotLibUpdateEntity = Export_BotLibUpdateEntity;
|
||||
be_botlib_export.Test = BotExportTest;
|
||||
|
||||
return &be_botlib_export;
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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;
|
||||
#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 );
|
||||
|
|
@ -0,0 +1,512 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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: botlib.h
|
||||
// Function: bot AI Library
|
||||
// Programmer: Mr Elusive (MrElusive@idsoftware.com)
|
||||
// Last update: 1999-08-18
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
#define BOTLIB_API_VERSION 2
|
||||
|
||||
struct aas_clientmove_s;
|
||||
struct aas_entityinfo_s;
|
||||
struct bot_consolemessage_s;
|
||||
struct bot_match_s;
|
||||
struct bot_goal_s;
|
||||
struct bot_moveresult_s;
|
||||
struct bot_initmove_s;
|
||||
struct weaponinfo_s;
|
||||
|
||||
|
||||
//debug line colors
|
||||
#define LINECOLOR_NONE -1
|
||||
#define LINECOLOR_RED 1 //0xf2f2f0f0L
|
||||
#define LINECOLOR_GREEN 2 //0xd0d1d2d3L
|
||||
#define LINECOLOR_BLUE 3 //0xf3f3f1f1L
|
||||
#define LINECOLOR_YELLOW 4 //0xdcdddedfL
|
||||
#define LINECOLOR_ORANGE 5 //0xe0e1e2e3L
|
||||
|
||||
//Print types
|
||||
#define PRT_MESSAGE 1
|
||||
#define PRT_WARNING 2
|
||||
#define PRT_ERROR 3
|
||||
#define PRT_FATAL 4
|
||||
#define PRT_EXIT 5
|
||||
|
||||
//console message types
|
||||
#define CMS_NORMAL 0
|
||||
#define CMS_CHAT 1
|
||||
|
||||
//botlib error codes
|
||||
#define BLERR_NOERROR 0 //no error
|
||||
#define BLERR_LIBRARYNOTSETUP 1 //library not setup
|
||||
#define BLERR_LIBRARYALREADYSETUP 2 //BotSetupLibrary: library already setup
|
||||
#define BLERR_INVALIDCLIENTNUMBER 3 //invalid client number
|
||||
#define BLERR_INVALIDENTITYNUMBER 4 //invalid entity number
|
||||
#define BLERR_NOAASFILE 5 //BotLoadMap: no AAS file available
|
||||
#define BLERR_CANNOTOPENAASFILE 6 //BotLoadMap: cannot open AAS file
|
||||
#define BLERR_CANNOTSEEKTOAASFILE 7 //BotLoadMap: cannot seek to AAS file
|
||||
#define BLERR_CANNOTREADAASHEADER 8 //BotLoadMap: cannot read AAS header
|
||||
#define BLERR_WRONGAASFILEID 9 //BotLoadMap: incorrect AAS file id
|
||||
#define BLERR_WRONGAASFILEVERSION 10 //BotLoadMap: incorrect AAS file version
|
||||
#define BLERR_CANNOTREADAASLUMP 11 //BotLoadMap: cannot read AAS file lump
|
||||
#define BLERR_NOBSPFILE 12 //BotLoadMap: no BSP file available
|
||||
#define BLERR_CANNOTOPENBSPFILE 13 //BotLoadMap: cannot open BSP file
|
||||
#define BLERR_CANNOTSEEKTOBSPFILE 14 //BotLoadMap: cannot seek to BSP file
|
||||
#define BLERR_CANNOTREADBSPHEADER 15 //BotLoadMap: cannot read BSP header
|
||||
#define BLERR_WRONGBSPFILEID 16 //BotLoadMap: incorrect BSP file id
|
||||
#define BLERR_WRONGBSPFILEVERSION 17 //BotLoadMap: incorrect BSP file version
|
||||
#define BLERR_CANNOTREADBSPLUMP 18 //BotLoadMap: cannot read BSP file lump
|
||||
#define BLERR_AICLIENTNOTSETUP 19 //BotAI: client not setup
|
||||
#define BLERR_AICLIENTALREADYSETUP 20 //BotSetupClient: client already setup
|
||||
#define BLERR_AIMOVEINACTIVECLIENT 21 //BotMoveClient: cannot move inactive client
|
||||
#define BLERR_AIMOVETOACTIVECLIENT 22 //BotMoveClient: cannot move to active client
|
||||
#define BLERR_AICLIENTALREADYSHUTDOWN 23 //BotShutdownClient: client not setup
|
||||
#define BLERR_AIUPDATEINACTIVECLIENT 24 //BotUpdateClient: called for inactive client
|
||||
#define BLERR_AICMFORINACTIVECLIENT 25 //BotConsoleMessage: called for inactive client
|
||||
#define BLERR_SETTINGSINACTIVECLIENT 26 //BotClientSettings: called for inactive client
|
||||
#define BLERR_CANNOTLOADICHAT 27 //BotSetupClient: cannot load initial chats
|
||||
#define BLERR_CANNOTLOADITEMWEIGHTS 28 //BotSetupClient: cannot load item weights
|
||||
#define BLERR_CANNOTLOADITEMCONFIG 29 //BotSetupLibrary: cannot load item config
|
||||
#define BLERR_CANNOTLOADWEAPONWEIGHTS 30 //BotSetupClient: cannot load weapon weights
|
||||
#define BLERR_CANNOTLOADWEAPONCONFIG 31 //BotSetupLibrary: cannot load weapon config
|
||||
#define BLERR_INVALIDSOUNDINDEX 32 //BotAddSound: invalid sound index value
|
||||
|
||||
//action flags
|
||||
#define ACTION_ATTACK 1
|
||||
#define ACTION_USE 2
|
||||
#define ACTION_RESPAWN 4
|
||||
#define ACTION_JUMP 8
|
||||
#define ACTION_MOVEUP 8
|
||||
#define ACTION_CROUCH 16
|
||||
#define ACTION_MOVEDOWN 16
|
||||
#define ACTION_MOVEFORWARD 32
|
||||
#define ACTION_MOVEBACK 64
|
||||
#define ACTION_MOVELEFT 128
|
||||
#define ACTION_MOVERIGHT 256
|
||||
#define ACTION_DELAYEDJUMP 512
|
||||
#define ACTION_TALK 1024
|
||||
#define ACTION_GESTURE 2048
|
||||
#define ACTION_WALK 4096
|
||||
|
||||
//the bot input, will be converted to an usercmd_t
|
||||
typedef struct bot_input_s
|
||||
{
|
||||
float thinktime; //time since last output (in seconds)
|
||||
vec3_t dir; //movement direction
|
||||
float speed; //speed in the range [0, 400]
|
||||
vec3_t viewangles; //the view angles
|
||||
int actionflags; //one of the ACTION_? flags
|
||||
int weapon; //weapon to use
|
||||
} bot_input_t;
|
||||
|
||||
#ifndef BSPTRACE
|
||||
|
||||
//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
|
||||
|
||||
//entity state
|
||||
typedef struct bot_entitystate_s
|
||||
{
|
||||
int type; // entity type
|
||||
int flags; // entity flags
|
||||
vec3_t origin; // origin of the entity
|
||||
vec3_t angles; // angles of the model
|
||||
vec3_t old_origin; // for lerping
|
||||
vec3_t mins; // bounding box minimums
|
||||
vec3_t maxs; // bounding box maximums
|
||||
int groundent; // ground entity
|
||||
int solid; // solid type
|
||||
int modelindex; // model used
|
||||
int modelindex2; // weapons, CTF flags, etc
|
||||
int frame; // model frame number
|
||||
int event; // impulse events -- muzzle flashes, footsteps, etc
|
||||
int eventParm; // even parameter
|
||||
int powerups; // bit flags
|
||||
int weapon; // determines weapon and flash model, etc
|
||||
int legsAnim; // mask off ANIM_TOGGLEBIT
|
||||
int torsoAnim; // mask off ANIM_TOGGLEBIT
|
||||
// int weapAnim; // mask off ANIM_TOGGLEBIT //----(SA) added
|
||||
//----(SA) didn't want to comment in as I wasn't sure of any implications of changing this structure.
|
||||
} bot_entitystate_t;
|
||||
|
||||
//bot AI library exported functions
|
||||
typedef struct botlib_import_s
|
||||
{
|
||||
//print messages from the bot library
|
||||
void ( QDECL * Print )( int type, char *fmt, ... );
|
||||
//trace a bbox through the world
|
||||
void ( *Trace )( bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask );
|
||||
//trace a bbox against a specific entity
|
||||
void ( *EntityTrace )( bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask );
|
||||
//retrieve the contents at the given point
|
||||
int ( *PointContents )( vec3_t point );
|
||||
//check if the point is in potential visible sight
|
||||
int ( *inPVS )( vec3_t p1, vec3_t p2 );
|
||||
//retrieve the BSP entity data lump
|
||||
char *( *BSPEntityData )( void );
|
||||
//
|
||||
void ( *BSPModelMinsMaxsOrigin )( int modelnum, vec3_t angles, vec3_t mins, vec3_t maxs, vec3_t origin );
|
||||
//send a bot client command
|
||||
void ( *BotClientCommand )( int client, char *command );
|
||||
//memory allocation
|
||||
void *( *GetMemory )( int size );
|
||||
void ( *FreeMemory )( void *ptr );
|
||||
void ( *FreeZoneMemory )( void );
|
||||
void *( *HunkAlloc )( int size );
|
||||
//file system access
|
||||
int ( *FS_FOpenFile )( const char *qpath, fileHandle_t *file, fsMode_t mode );
|
||||
int ( *FS_Read )( void *buffer, int len, fileHandle_t f );
|
||||
int ( *FS_Write )( const void *buffer, int len, fileHandle_t f );
|
||||
void ( *FS_FCloseFile )( fileHandle_t f );
|
||||
int ( *FS_Seek )( fileHandle_t f, long offset, int origin );
|
||||
//debug visualisation stuff
|
||||
int ( *DebugLineCreate )( void );
|
||||
void ( *DebugLineDelete )( int line );
|
||||
void ( *DebugLineShow )( int line, vec3_t start, vec3_t end, int color );
|
||||
//
|
||||
int ( *DebugPolygonCreate )( int color, int numPoints, vec3_t *points );
|
||||
void ( *DebugPolygonDelete )( int id );
|
||||
//
|
||||
// Ridah, Cast AI stuff
|
||||
qboolean ( *AICast_VisibleFromPos )( vec3_t srcpos, int srcnum,
|
||||
vec3_t destpos, int destnum, qboolean updateVisPos );
|
||||
qboolean ( *AICast_CheckAttackAtPos )( int entnum, int enemy, vec3_t pos, qboolean ducking, qboolean allowHitWorld );
|
||||
// done.
|
||||
} botlib_import_t;
|
||||
|
||||
typedef struct aas_export_s
|
||||
{
|
||||
//-----------------------------------
|
||||
// be_aas_entity.h
|
||||
//-----------------------------------
|
||||
void ( *AAS_EntityInfo )( int entnum, struct aas_entityinfo_s *info );
|
||||
//-----------------------------------
|
||||
// be_aas_main.h
|
||||
//-----------------------------------
|
||||
int ( *AAS_Initialized )( void );
|
||||
void ( *AAS_PresenceTypeBoundingBox )( int presencetype, vec3_t mins, vec3_t maxs );
|
||||
float ( *AAS_Time )( void );
|
||||
//--------------------------------------------
|
||||
// be_aas_sample.c
|
||||
//--------------------------------------------
|
||||
int ( *AAS_PointAreaNum )( vec3_t point );
|
||||
int ( *AAS_TraceAreas )( vec3_t start, vec3_t end, int *areas, vec3_t *points, int maxareas );
|
||||
//--------------------------------------------
|
||||
// be_aas_bspq3.c
|
||||
//--------------------------------------------
|
||||
int ( *AAS_PointContents )( vec3_t point );
|
||||
int ( *AAS_NextBSPEntity )( int ent );
|
||||
int ( *AAS_ValueForBSPEpairKey )( int ent, char *key, char *value, int size );
|
||||
int ( *AAS_VectorForBSPEpairKey )( int ent, char *key, vec3_t v );
|
||||
int ( *AAS_FloatForBSPEpairKey )( int ent, char *key, float *value );
|
||||
int ( *AAS_IntForBSPEpairKey )( int ent, char *key, int *value );
|
||||
//--------------------------------------------
|
||||
// be_aas_reach.c
|
||||
//--------------------------------------------
|
||||
int ( *AAS_AreaReachability )( int areanum );
|
||||
//--------------------------------------------
|
||||
// be_aas_route.c
|
||||
//--------------------------------------------
|
||||
int ( *AAS_AreaTravelTimeToGoalArea )( int areanum, vec3_t origin, int goalareanum, int travelflags );
|
||||
//--------------------------------------------
|
||||
// be_aas_move.c
|
||||
//--------------------------------------------
|
||||
int ( *AAS_Swimming )( vec3_t origin );
|
||||
int ( *AAS_PredictClientMovement )( struct aas_clientmove_s *move,
|
||||
int entnum, vec3_t origin,
|
||||
int presencetype, int onground,
|
||||
vec3_t velocity, vec3_t cmdmove,
|
||||
int cmdframes,
|
||||
int maxframes, float frametime,
|
||||
int stopevent, int stopareanum, int visualize );
|
||||
|
||||
// Ridah, route-tables
|
||||
//--------------------------------------------
|
||||
// be_aas_routetable.c
|
||||
//--------------------------------------------
|
||||
void ( *AAS_RT_ShowRoute )( vec3_t srcpos, int srcnum, int destnum );
|
||||
qboolean ( *AAS_RT_GetHidePos )( vec3_t srcpos, int srcnum, int srcarea, vec3_t destpos, int destnum, int destarea, vec3_t returnPos );
|
||||
int ( *AAS_FindAttackSpotWithinRange )( int srcnum, int rangenum, int enemynum, float rangedist, int travelflags, float *outpos );
|
||||
void ( *AAS_SetAASBlockingEntity )( vec3_t absmin, vec3_t absmax, qboolean blocking );
|
||||
// done.
|
||||
|
||||
// Ridah
|
||||
void ( *AAS_SetCurrentWorld )( int index );
|
||||
// done.
|
||||
|
||||
} aas_export_t;
|
||||
|
||||
typedef struct ea_export_s
|
||||
{
|
||||
//ClientCommand elementary actions
|
||||
void ( *EA_Say )( int client, char *str );
|
||||
void ( *EA_SayTeam )( int client, char *str );
|
||||
void ( *EA_UseItem )( int client, char *it );
|
||||
void ( *EA_DropItem )( int client, char *it );
|
||||
void ( *EA_UseInv )( int client, char *inv );
|
||||
void ( *EA_DropInv )( int client, char *inv );
|
||||
void ( *EA_Gesture )( int client );
|
||||
void ( *EA_Command )( int client, char *command );
|
||||
//regular elementary actions
|
||||
void ( *EA_SelectWeapon )( int client, int weapon );
|
||||
void ( *EA_Talk )( int client );
|
||||
void ( *EA_Attack )( int client );
|
||||
void ( *EA_Use )( int client );
|
||||
void ( *EA_Respawn )( int client );
|
||||
void ( *EA_Jump )( int client );
|
||||
void ( *EA_DelayedJump )( int client );
|
||||
void ( *EA_Crouch )( int client );
|
||||
void ( *EA_MoveUp )( int client );
|
||||
void ( *EA_MoveDown )( int client );
|
||||
void ( *EA_MoveForward )( int client );
|
||||
void ( *EA_MoveBack )( int client );
|
||||
void ( *EA_MoveLeft )( int client );
|
||||
void ( *EA_MoveRight )( int client );
|
||||
void ( *EA_Move )( int client, vec3_t dir, float speed );
|
||||
void ( *EA_View )( int client, vec3_t viewangles );
|
||||
//send regular input to the server
|
||||
void ( *EA_EndRegular )( int client, float thinktime );
|
||||
void ( *EA_GetInput )( int client, float thinktime, bot_input_t *input );
|
||||
void ( *EA_ResetInput )( int client, bot_input_t *init );
|
||||
} ea_export_t;
|
||||
|
||||
typedef struct ai_export_s
|
||||
{
|
||||
//-----------------------------------
|
||||
// be_ai_char.h
|
||||
//-----------------------------------
|
||||
int ( *BotLoadCharacter )( char *charfile, int skill );
|
||||
void ( *BotFreeCharacter )( int character );
|
||||
float ( *Characteristic_Float )( int character, int index );
|
||||
float ( *Characteristic_BFloat )( int character, int index, float min, float max );
|
||||
int ( *Characteristic_Integer )( int character, int index );
|
||||
int ( *Characteristic_BInteger )( int character, int index, int min, int max );
|
||||
void ( *Characteristic_String )( int character, int index, char *buf, int size );
|
||||
//-----------------------------------
|
||||
// be_ai_chat.h
|
||||
//-----------------------------------
|
||||
int ( *BotAllocChatState )( void );
|
||||
void ( *BotFreeChatState )( int handle );
|
||||
void ( *BotQueueConsoleMessage )( int chatstate, int type, char *message );
|
||||
void ( *BotRemoveConsoleMessage )( int chatstate, int handle );
|
||||
int ( *BotNextConsoleMessage )( int chatstate, struct bot_consolemessage_s *cm );
|
||||
int ( *BotNumConsoleMessages )( int chatstate );
|
||||
void ( *BotInitialChat )( int chatstate, char *type, int mcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7 );
|
||||
int ( *BotNumInitialChats )( int chatstate, char *type );
|
||||
int ( *BotReplyChat )( int chatstate, char *message, int mcontext, int vcontext, char *var0, char *var1, char *var2, char *var3, char *var4, char *var5, char *var6, char *var7 );
|
||||
int ( *BotChatLength )( int chatstate );
|
||||
void ( *BotEnterChat )( int chatstate, int client, int sendto );
|
||||
void ( *BotGetChatMessage )( int chatstate, char *buf, int size );
|
||||
int ( *StringContains )( char *str1, char *str2, int casesensitive );
|
||||
int ( *BotFindMatch )( char *str, struct bot_match_s *match, unsigned long int context );
|
||||
void ( *BotMatchVariable )( struct bot_match_s *match, int variable, char *buf, int size );
|
||||
void ( *UnifyWhiteSpaces )( char *string );
|
||||
void ( *BotReplaceSynonyms )( char *string, unsigned long int context );
|
||||
int ( *BotLoadChatFile )( int chatstate, char *chatfile, char *chatname );
|
||||
void ( *BotSetChatGender )( int chatstate, int gender );
|
||||
void ( *BotSetChatName )( int chatstate, char *name );
|
||||
//-----------------------------------
|
||||
// be_ai_goal.h
|
||||
//-----------------------------------
|
||||
void ( *BotResetGoalState )( int goalstate );
|
||||
void ( *BotResetAvoidGoals )( int goalstate );
|
||||
void ( *BotRemoveFromAvoidGoals )( int goalstate, int number );
|
||||
void ( *BotPushGoal )( int goalstate, struct bot_goal_s *goal );
|
||||
void ( *BotPopGoal )( int goalstate );
|
||||
void ( *BotEmptyGoalStack )( int goalstate );
|
||||
void ( *BotDumpAvoidGoals )( int goalstate );
|
||||
void ( *BotDumpGoalStack )( int goalstate );
|
||||
void ( *BotGoalName )( int number, char *name, int size );
|
||||
int ( *BotGetTopGoal )( int goalstate, struct bot_goal_s *goal );
|
||||
int ( *BotGetSecondGoal )( int goalstate, struct bot_goal_s *goal );
|
||||
int ( *BotChooseLTGItem )( int goalstate, vec3_t origin, int *inventory, int travelflags );
|
||||
int ( *BotChooseNBGItem )( int goalstate, vec3_t origin, int *inventory, int travelflags,
|
||||
struct bot_goal_s *ltg, float maxtime );
|
||||
int ( *BotTouchingGoal )( vec3_t origin, struct bot_goal_s *goal );
|
||||
int ( *BotItemGoalInVisButNotVisible )( int viewer, vec3_t eye, vec3_t viewangles, struct bot_goal_s *goal );
|
||||
int ( *BotGetLevelItemGoal )( int index, char *classname, struct bot_goal_s *goal );
|
||||
int ( *BotGetNextCampSpotGoal )( int num, struct bot_goal_s *goal );
|
||||
int ( *BotGetMapLocationGoal )( char *name, struct bot_goal_s *goal );
|
||||
float ( *BotAvoidGoalTime )( int goalstate, int number );
|
||||
void ( *BotInitLevelItems )( void );
|
||||
void ( *BotUpdateEntityItems )( void );
|
||||
int ( *BotLoadItemWeights )( int goalstate, char *filename );
|
||||
void ( *BotFreeItemWeights )( int goalstate );
|
||||
void ( *BotInterbreedGoalFuzzyLogic )( int parent1, int parent2, int child );
|
||||
void ( *BotSaveGoalFuzzyLogic )( int goalstate, char *filename );
|
||||
void ( *BotMutateGoalFuzzyLogic )( int goalstate, float range );
|
||||
int ( *BotAllocGoalState )( int client );
|
||||
void ( *BotFreeGoalState )( int handle );
|
||||
//-----------------------------------
|
||||
// be_ai_move.h
|
||||
//-----------------------------------
|
||||
void ( *BotResetMoveState )( int movestate );
|
||||
void ( *BotMoveToGoal )( struct bot_moveresult_s *result, int movestate, struct bot_goal_s *goal, int travelflags );
|
||||
int ( *BotMoveInDirection )( int movestate, vec3_t dir, float speed, int type );
|
||||
void ( *BotResetAvoidReach )( int movestate );
|
||||
void ( *BotResetLastAvoidReach )( int movestate );
|
||||
int ( *BotReachabilityArea )( vec3_t origin, int testground );
|
||||
int ( *BotMovementViewTarget )( int movestate, struct bot_goal_s *goal, int travelflags, float lookahead, vec3_t target );
|
||||
int ( *BotPredictVisiblePosition )( vec3_t origin, int areanum, struct bot_goal_s *goal, int travelflags, vec3_t target );
|
||||
int ( *BotAllocMoveState )( void );
|
||||
void ( *BotFreeMoveState )( int handle );
|
||||
void ( *BotInitMoveState )( int handle, struct bot_initmove_s *initmove );
|
||||
// Ridah
|
||||
void ( *BotInitAvoidReach )( int handle );
|
||||
// done.
|
||||
//-----------------------------------
|
||||
// be_ai_weap.h
|
||||
//-----------------------------------
|
||||
int ( *BotChooseBestFightWeapon )( int weaponstate, int *inventory );
|
||||
void ( *BotGetWeaponInfo )( int weaponstate, int weapon, struct weaponinfo_s *weaponinfo );
|
||||
int ( *BotLoadWeaponWeights )( int weaponstate, char *filename );
|
||||
int ( *BotAllocWeaponState )( void );
|
||||
void ( *BotFreeWeaponState )( int weaponstate );
|
||||
void ( *BotResetWeaponState )( int weaponstate );
|
||||
//-----------------------------------
|
||||
// be_ai_gen.h
|
||||
//-----------------------------------
|
||||
int ( *GeneticParentsAndChildSelection )( int numranks, float *ranks, int *parent1, int *parent2, int *child );
|
||||
} ai_export_t;
|
||||
|
||||
//bot AI library imported functions
|
||||
typedef struct botlib_export_s
|
||||
{
|
||||
//Area Awareness System functions
|
||||
aas_export_t aas;
|
||||
//Elementary Action functions
|
||||
ea_export_t ea;
|
||||
//AI functions
|
||||
ai_export_t ai;
|
||||
//setup the bot library, returns BLERR_
|
||||
int ( *BotLibSetup )( void );
|
||||
//shutdown the bot library, returns BLERR_
|
||||
int ( *BotLibShutdown )( void );
|
||||
//sets a library variable returns BLERR_
|
||||
int ( *BotLibVarSet )( char *var_name, char *value );
|
||||
//gets a library variable returns BLERR_
|
||||
int ( *BotLibVarGet )( char *var_name, char *value, int size );
|
||||
//sets a C-like define returns BLERR_
|
||||
int ( *BotLibDefine )( char *string );
|
||||
//start a frame in the bot library
|
||||
int ( *BotLibStartFrame )( float time );
|
||||
//load a new map in the bot library
|
||||
int ( *BotLibLoadMap )( const char *mapname );
|
||||
//entity updates
|
||||
int ( *BotLibUpdateEntity )( int ent, bot_entitystate_t *state );
|
||||
//just for testing
|
||||
int ( *Test )( int parm0, char *parm1, vec3_t parm2, vec3_t parm3 );
|
||||
} botlib_export_t;
|
||||
|
||||
//linking of bot library
|
||||
botlib_export_t *GetBotLibAPI( int apiVersion, botlib_import_t *import );
|
||||
|
||||
/* Library variables:
|
||||
|
||||
name: default: module(s): description:
|
||||
|
||||
"basedir" "" l_utils.c Quake2 base directory
|
||||
"gamedir" "" l_utils.c Quake2 game directory
|
||||
"cddir" "" l_utils.c Quake2 CD directory
|
||||
|
||||
"autolaunchbspc" "0" be_aas_load.c automatically launch (Win)BSPC
|
||||
"log" "0" l_log.c enable/disable creating a log file
|
||||
"maxclients" "4" be_interface.c maximum number of clients
|
||||
"maxentities" "1024" be_interface.c maximum number of entities
|
||||
|
||||
"sv_friction" "6" be_aas_move.c ground friction
|
||||
"sv_stopspeed" "100" be_aas_move.c stop speed
|
||||
"sv_gravity" "800" be_aas_move.c gravity value
|
||||
"sv_waterfriction" "1" be_aas_move.c water friction
|
||||
"sv_watergravity" "400" be_aas_move.c gravity in water
|
||||
"sv_maxvelocity" "300" be_aas_move.c maximum velocity
|
||||
"sv_maxwalkvelocity" "300" be_aas_move.c maximum walk velocity
|
||||
"sv_maxcrouchvelocity" "100" be_aas_move.c maximum crouch velocity
|
||||
"sv_maxswimvelocity" "150" be_aas_move.c maximum swim velocity
|
||||
"sv_walkaccelerate" "10" be_aas_move.c walk acceleration
|
||||
"sv_airaccelerate" "1" be_aas_move.c air acceleration
|
||||
"sv_swimaccelerate" "4" be_aas_move.c swim acceleration
|
||||
"sv_maxstep" "18" be_aas_move.c maximum step height
|
||||
"sv_maxbarrier" "32" be_aas_move.c maximum barrier height
|
||||
"sv_maxsteepness" "0.7" be_aas_move.c maximum floor steepness
|
||||
"sv_jumpvel" "270" be_aas_move.c jump z velocity
|
||||
"sv_maxwaterjump" "20" be_aas_move.c maximum waterjump height
|
||||
|
||||
"max_aaslinks" "4096" be_aas_sample.c maximum links in the AAS
|
||||
"max_bsplinks" "4096" be_aas_bsp.c maximum links in the BSP
|
||||
|
||||
"notspawnflags" "2048" be_ai_goal.c entities with these spawnflags will be removed
|
||||
"itemconfig" "items.c" be_ai_goal.c item configuration file
|
||||
"weaponconfig" "weapons.c" be_ai_weap.c weapon configuration file
|
||||
"synfile" "syn.c" be_ai_chat.c file with synonyms
|
||||
"rndfile" "rnd.c" be_ai_chat.c file with random strings
|
||||
"matchfile" "match.c" be_ai_chat.c file with match strings
|
||||
"max_messages" "1024" be_ai_chat.c console message heap size
|
||||
"max_weaponinfo" "32" be_ai_weap.c maximum number of weapon info
|
||||
"max_projectileinfo" "32" be_ai_weap.c maximum number of projectile info
|
||||
"max_iteminfo" "256" be_ai_goal.c maximum number of item info
|
||||
"max_levelitems" "256" be_ai_goal.c maximum number of level items
|
||||
"framereachability" "" be_aas_reach.c number of reachabilities to calucate per frame
|
||||
"forceclustering" "0" be_aas_main.c force recalculation of clusters
|
||||
"forcereachability" "0" be_aas_main.c force recalculation of reachabilities
|
||||
"forcewrite" "0" be_aas_main.c force writing of aas file
|
||||
"nooptimize" "0" be_aas_main.c no aas optimization
|
||||
|
||||
"laserhook" "0" be_ai_move.c 0 = CTF hook, 1 = laser hook
|
||||
|
||||
*/
|
||||
|
|
@ -0,0 +1,911 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="botlib"
|
||||
ProjectGUID="{86691FDD-E0C6-4D71-9FFD-E0F30F19AA3E}"
|
||||
TargetFrameworkVersion="0"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.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="2"
|
||||
InlineFunctionExpansion="1"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;BOTLIB;_CRT_SECURE_NO_WARNINGS"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
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"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/botlib.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.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"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
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"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/botlib.bsc"
|
||||
/>
|
||||
<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"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_cluster.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_debug.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_entity.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_file.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_main.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_move.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_optimize.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_reach.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_route.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_routealt.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_routetable.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_aas_sample.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_ai_char.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_ai_chat.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_ai_gen.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_ai_goal.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_ai_move.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_ai_weap.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_ai_weight.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_ea.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="be_interface.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="l_crc.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="l_libvar.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="l_log.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="l_memory.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="l_precomp.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="l_script.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="l_struct.c"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</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>
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 // because process string allows value 256 through and it was undefined
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// 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
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
|
@ -0,0 +1,282 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
|
|
@ -0,0 +1,446 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
#ifndef BSPC
|
||||
#define MEMDEBUG
|
||||
#endif
|
||||
#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 );
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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, ... );
|
||||
|
||||
#ifdef BSPC
|
||||
// some of BSPC source does include game/q_shared.h and some does not
|
||||
// we define pc_token_s pc_token_t if needed (yes, it's ugly)
|
||||
#ifndef __Q_SHARED_H
|
||||
#define MAX_TOKENLENGTH 1024
|
||||
typedef struct pc_token_s
|
||||
{
|
||||
int type;
|
||||
int subtype;
|
||||
int intvalue;
|
||||
float floatvalue;
|
||||
char string[MAX_TOKENLENGTH];
|
||||
} pc_token_t;
|
||||
#endif //!_Q_SHARED_H
|
||||
#endif //BSPC
|
||||
|
||||
//
|
||||
int PC_LoadSourceHandle( const char *filename );
|
||||
int PC_FreeSourceHandle( int handle );
|
||||
int PC_ReadTokenHandle( int handle, struct pc_token_s *pc_token );
|
||||
int PC_SourceFileAndLine( int handle, char *filename, int *line );
|
||||
void PC_CheckOpenSourceHandles( void );
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,268 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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, ... );
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,507 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 )
|
||||
#define MAX_PATH MAX_QPATH
|
||||
#define Maximum( x,y ) ( x > y ? x : y )
|
||||
#define Minimum( x,y ) ( x < y ? x : y )
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
|
||||
*/
|
|
@ -0,0 +1,424 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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
|
||||
|
||||
void AAS_MergeAreas( void ) {
|
||||
int side, nummerges, merges, groundfirst;
|
||||
tmp_area_t *tmparea, *othertmparea;
|
||||
tmp_face_t *face;
|
||||
|
||||
nummerges = 0;
|
||||
Log_Write( "AAS_MergeAreas\r\n" );
|
||||
qprintf( "%6d areas merged", 1 );
|
||||
//
|
||||
groundfirst = true;
|
||||
//for (i = 0; i < 4 || merges; i++)
|
||||
while ( 1 )
|
||||
{
|
||||
//if (i < 2) groundfirst = true;
|
||||
//else groundfirst = false;
|
||||
//
|
||||
merges = 0;
|
||||
//first merge grounded areas only
|
||||
for ( tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next )
|
||||
{
|
||||
//if the area is invalid
|
||||
if ( tmparea->invalid ) {
|
||||
continue;
|
||||
} //end if
|
||||
//
|
||||
if ( groundfirst ) {
|
||||
if ( !AAS_GroundArea( tmparea ) ) {
|
||||
continue;
|
||||
}
|
||||
} //end if
|
||||
//
|
||||
for ( face = tmparea->tmpfaces; face; face = face->next[side] )
|
||||
{
|
||||
side = ( face->frontarea != tmparea );
|
||||
//if the face has both a front and back area
|
||||
if ( face->frontarea && face->backarea ) {
|
||||
//
|
||||
if ( face->frontarea == tmparea ) {
|
||||
othertmparea = face->backarea;
|
||||
} else { othertmparea = face->frontarea;}
|
||||
//
|
||||
if ( groundfirst ) {
|
||||
if ( !AAS_GroundArea( othertmparea ) ) {
|
||||
continue;
|
||||
}
|
||||
} //end if
|
||||
if ( AAS_TryMergeFaceAreas( face ) ) {
|
||||
qprintf( "\r%6d", ++nummerges );
|
||||
merges++;
|
||||
break;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
if ( !merges ) {
|
||||
if ( groundfirst ) {
|
||||
groundfirst = false;
|
||||
} else { break;}
|
||||
} //end if
|
||||
} //end for
|
||||
qprintf( "\n" );
|
||||
Log_Write( "%6d areas merged\r\n", nummerges );
|
||||
//refresh the merged tree
|
||||
AAS_RefreshMergedTree_r( tmpaasworld.nodes );
|
||||
} //end of the function AAS_MergeAreas
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
||||
|
|
@ -0,0 +1,317 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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"
|
||||
|
||||
// TTimo: this is a f*g mess
|
||||
// I got rid of all occurences except for bspc it seems
|
||||
// all code *should* be using Q_stricmp
|
||||
#ifdef BSPC
|
||||
#define stricmp strcasecmp
|
||||
#endif
|
||||
|
||||
///////////////////////////////////
|
||||
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
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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 );
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_edgemelting.c
|
||||
// Function: Melting of Edges
|
||||
// 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"
|
||||
|
||||
//===========================================================================
|
||||
// try to melt the windings of the two faces
|
||||
// FIXME: this is buggy
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_MeltFaceWinding( tmp_face_t *face1, tmp_face_t *face2 ) {
|
||||
int i, n;
|
||||
int splits = 0;
|
||||
winding_t *w2, *neww;
|
||||
plane_t *plane1;
|
||||
|
||||
#ifdef DEBUG
|
||||
if ( !face1->winding ) {
|
||||
Error( "face1 %d without winding", face1->num );
|
||||
}
|
||||
if ( !face2->winding ) {
|
||||
Error( "face2 %d without winding", face2->num );
|
||||
}
|
||||
#endif //DEBUG
|
||||
w2 = face2->winding;
|
||||
plane1 = &mapplanes[face1->planenum];
|
||||
for ( i = 0; i < w2->numpoints; i++ )
|
||||
{
|
||||
if ( PointOnWinding( face1->winding, plane1->normal, plane1->dist, w2->p[i], &n ) ) {
|
||||
neww = AddWindingPoint( face1->winding, w2->p[i], n );
|
||||
FreeWinding( face1->winding );
|
||||
face1->winding = neww;
|
||||
|
||||
splits++;
|
||||
} //end if
|
||||
} //end for
|
||||
return splits;
|
||||
} //end of the function AAS_MeltFaceWinding
|
||||
//===========================================================================
|
||||
// melt the windings of the area faces
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_MeltFaceWindingsOfArea( tmp_area_t *tmparea ) {
|
||||
int side1, side2, num_windingsplits = 0;
|
||||
tmp_face_t *face1, *face2;
|
||||
|
||||
for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
for ( face2 = tmparea->tmpfaces; face2; face2 = face2->next[side2] )
|
||||
{
|
||||
side2 = face2->frontarea != tmparea;
|
||||
if ( face1 == face2 ) {
|
||||
continue;
|
||||
}
|
||||
num_windingsplits += AAS_MeltFaceWinding( face1, face2 );
|
||||
} //end for
|
||||
} //end for
|
||||
return num_windingsplits;
|
||||
} //end of the function AAS_MeltFaceWindingsOfArea
|
||||
//===========================================================================
|
||||
// melt the windings of the faces of all areas
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_MeltAreaFaceWindings( void ) {
|
||||
tmp_area_t *tmparea;
|
||||
int num_windingsplits = 0;
|
||||
|
||||
Log_Write( "AAS_MeltAreaFaceWindings\r\n" );
|
||||
qprintf( "%6d edges melted", num_windingsplits );
|
||||
//NOTE: first convex area (zero) is a dummy
|
||||
for ( tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next )
|
||||
{
|
||||
num_windingsplits += AAS_MeltFaceWindingsOfArea( tmparea );
|
||||
qprintf( "\r%6d", num_windingsplits );
|
||||
} //end for
|
||||
qprintf( "\n" );
|
||||
Log_Write( "%6d edges melted\r\n", num_windingsplits );
|
||||
} //end of the function AAS_MeltAreaFaceWindings
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_edgemelting.h
|
||||
// Function: Melting of Edges
|
||||
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
|
||||
// Last update: 1997-12-04
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
|
||||
void AAS_MeltAreaFaceWindings( void );
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_facemerging.c
|
||||
// Function: Merging of Faces
|
||||
// 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"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_TryMergeFaces( tmp_face_t *face1, tmp_face_t *face2 ) {
|
||||
winding_t *neww;
|
||||
|
||||
#ifdef DEBUG
|
||||
if ( !face1->winding ) {
|
||||
Error( "face1 %d without winding", face1->num );
|
||||
}
|
||||
if ( !face2->winding ) {
|
||||
Error( "face2 %d without winding", face2->num );
|
||||
}
|
||||
#endif //DEBUG
|
||||
//
|
||||
if ( face1->faceflags != face2->faceflags ) {
|
||||
return false;
|
||||
}
|
||||
//NOTE: if the front or back area is zero this doesn't mean there's
|
||||
//a real area. It means there's solid at that side of the face
|
||||
//if both faces have the same front area
|
||||
if ( face1->frontarea == face2->frontarea ) {
|
||||
//if both faces have the same back area
|
||||
if ( face1->backarea == face2->backarea ) {
|
||||
//if the faces are in the same plane
|
||||
if ( face1->planenum == face2->planenum ) {
|
||||
//if they have both a front and a back area (no solid on either side)
|
||||
if ( face1->frontarea && face1->backarea ) {
|
||||
neww = MergeWindings( face1->winding, face2->winding,
|
||||
mapplanes[face1->planenum].normal );
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
//this function is to be found in l_poly.c
|
||||
neww = TryMergeWinding( face1->winding, face2->winding,
|
||||
mapplanes[face1->planenum].normal );
|
||||
} //end else
|
||||
if ( neww ) {
|
||||
FreeWinding( face1->winding );
|
||||
face1->winding = neww;
|
||||
if ( face2->frontarea ) {
|
||||
AAS_RemoveFaceFromArea( face2, face2->frontarea );
|
||||
}
|
||||
if ( face2->backarea ) {
|
||||
AAS_RemoveFaceFromArea( face2, face2->backarea );
|
||||
}
|
||||
AAS_FreeTmpFace( face2 );
|
||||
return true;
|
||||
} //end if
|
||||
} //end if
|
||||
else if ( ( face1->planenum & ~1 ) == ( face2->planenum & ~1 ) ) {
|
||||
Log_Write( "face %d and %d, same front and back area but flipped planes\r\n",
|
||||
face1->num, face2->num );
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
return false;
|
||||
} //end of the function AAS_TryMergeFaces
|
||||
/*
|
||||
int AAS_TryMergeFaces(tmp_face_t *face1, tmp_face_t *face2)
|
||||
{
|
||||
winding_t *neww;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (!face1->winding) Error("face1 %d without winding", face1->num);
|
||||
if (!face2->winding) Error("face2 %d without winding", face2->num);
|
||||
#endif //DEBUG
|
||||
//if the faces are in the same plane
|
||||
if ((face1->planenum & ~1) != (face2->planenum & ~1)) return false;
|
||||
// if (face1->planenum != face2->planenum) return false;
|
||||
//NOTE: if the front or back area is zero this doesn't mean there's
|
||||
//a real area. It means there's solid at that side of the face
|
||||
//if both faces have the same front area
|
||||
if (face1->frontarea != face2->frontarea ||
|
||||
face1->backarea != face2->backarea)
|
||||
{
|
||||
if (!face1->frontarea || !face1->backarea ||
|
||||
!face2->frontarea || !face2->backarea) return false;
|
||||
else if (face1->frontarea != face2->backarea ||
|
||||
face1->backarea != face2->frontarea) return false;
|
||||
// return false;
|
||||
} //end if
|
||||
//this function is to be found in l_poly.c
|
||||
neww = TryMergeWinding(face1->winding, face2->winding,
|
||||
mapplanes[face1->planenum].normal);
|
||||
if (!neww) return false;
|
||||
//
|
||||
FreeWinding(face1->winding);
|
||||
face1->winding = neww;
|
||||
//remove face2
|
||||
if (face2->frontarea)
|
||||
AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->frontarea]);
|
||||
if (face2->backarea)
|
||||
AAS_RemoveFaceFromArea(face2, &tmpaasworld.areas[face2->backarea]);
|
||||
return true;
|
||||
} //end of the function AAS_TryMergeFaces*/
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_MergeAreaFaces( void ) {
|
||||
int num_facemerges = 0;
|
||||
int side1, side2, restart;
|
||||
tmp_area_t *tmparea, *lasttmparea;
|
||||
tmp_face_t *face1, *face2;
|
||||
|
||||
Log_Write( "AAS_MergeAreaFaces\r\n" );
|
||||
qprintf( "%6d face merges", num_facemerges );
|
||||
//NOTE: first convex area is a dummy
|
||||
lasttmparea = tmpaasworld.areas;
|
||||
for ( tmparea = tmpaasworld.areas; tmparea; tmparea = tmparea->l_next )
|
||||
{
|
||||
restart = false;
|
||||
//
|
||||
if ( tmparea->invalid ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
for ( face2 = face1->next[side1]; face2; face2 = face2->next[side2] )
|
||||
{
|
||||
side2 = face2->frontarea != tmparea;
|
||||
//if succesfully merged
|
||||
if ( AAS_TryMergeFaces( face1, face2 ) ) {
|
||||
//start over again after merging two faces
|
||||
restart = true;
|
||||
num_facemerges++;
|
||||
qprintf( "\r%6d", num_facemerges );
|
||||
AAS_CheckArea( tmparea );
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
if ( restart ) {
|
||||
tmparea = lasttmparea;
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
lasttmparea = tmparea;
|
||||
} //end for
|
||||
qprintf( "\n" );
|
||||
Log_Write( "%6d face merges\r\n", num_facemerges );
|
||||
} //end of the function AAS_MergeAreaFaces
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_MergePlaneFaces( tmp_area_t *tmparea, int planenum ) {
|
||||
tmp_face_t *face1, *face2, *nextface2;
|
||||
winding_t *neww;
|
||||
int side1, side2;
|
||||
|
||||
for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
if ( face1->planenum != planenum ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
for ( face2 = face1->next[side1]; face2; face2 = nextface2 )
|
||||
{
|
||||
side2 = face2->frontarea != tmparea;
|
||||
nextface2 = face2->next[side2];
|
||||
//
|
||||
if ( ( face2->planenum & ~1 ) != ( planenum & ~1 ) ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
neww = MergeWindings( face1->winding, face2->winding,
|
||||
mapplanes[face1->planenum].normal );
|
||||
FreeWinding( face1->winding );
|
||||
face1->winding = neww;
|
||||
if ( face2->frontarea ) {
|
||||
AAS_RemoveFaceFromArea( face2, face2->frontarea );
|
||||
}
|
||||
if ( face2->backarea ) {
|
||||
AAS_RemoveFaceFromArea( face2, face2->backarea );
|
||||
}
|
||||
AAS_FreeTmpFace( face2 );
|
||||
//
|
||||
nextface2 = face1->next[side1];
|
||||
} //end for
|
||||
} //end for
|
||||
} //end of the function AAS_MergePlaneFaces
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_CanMergePlaneFaces( tmp_area_t *tmparea, int planenum ) {
|
||||
tmp_area_t *frontarea, *backarea;
|
||||
tmp_face_t *face1;
|
||||
int side1, merge, faceflags = 0; // TTimo: init
|
||||
|
||||
frontarea = backarea = NULL;
|
||||
merge = false;
|
||||
for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
if ( ( face1->planenum & ~1 ) != ( planenum & ~1 ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( !frontarea && !backarea ) {
|
||||
frontarea = face1->frontarea;
|
||||
backarea = face1->backarea;
|
||||
faceflags = face1->faceflags;
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if ( frontarea != face1->frontarea ) {
|
||||
return false;
|
||||
}
|
||||
if ( backarea != face1->backarea ) {
|
||||
return false;
|
||||
}
|
||||
if ( faceflags != face1->faceflags ) {
|
||||
return false;
|
||||
}
|
||||
merge = true;
|
||||
} //end else
|
||||
} //end for
|
||||
return merge;
|
||||
} //end of the function AAS_CanMergePlaneFaces
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_MergeAreaPlaneFaces( void ) {
|
||||
int num_facemerges = 0;
|
||||
int side1;
|
||||
tmp_area_t *tmparea, *nexttmparea;
|
||||
tmp_face_t *face1;
|
||||
|
||||
Log_Write( "AAS_MergePlaneFaces\r\n" );
|
||||
qprintf( "%6d plane face merges", num_facemerges );
|
||||
//NOTE: first convex area is a dummy
|
||||
for ( tmparea = tmpaasworld.areas; tmparea; tmparea = nexttmparea )
|
||||
{
|
||||
nexttmparea = tmparea->l_next;
|
||||
//
|
||||
if ( tmparea->invalid ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
|
||||
{
|
||||
side1 = face1->frontarea != tmparea;
|
||||
//
|
||||
if ( AAS_CanMergePlaneFaces( tmparea, face1->planenum ) ) {
|
||||
AAS_MergePlaneFaces( tmparea, face1->planenum );
|
||||
nexttmparea = tmparea;
|
||||
num_facemerges++;
|
||||
qprintf( "\r%6d", num_facemerges );
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
qprintf( "\n" );
|
||||
Log_Write( "%6d plane face merges\r\n", num_facemerges );
|
||||
} //end of the function AAS_MergeAreaPlaneFaces
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_facemerging.h
|
||||
// Function: Merging of Faces
|
||||
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
|
||||
// Last update: 1997-12-04
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
void AAS_MergeAreaFaces( void );
|
||||
void AAS_MergeAreaPlaneFaces( void );
|
|
@ -0,0 +1,603 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_file.c
|
||||
// Function: AAS file loading and writing
|
||||
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
|
||||
// Last update: 1997-12-04
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
#include "qbsp.h"
|
||||
#include "../botlib/aasfile.h"
|
||||
#include "aas_file.h"
|
||||
#include "aas_store.h"
|
||||
#include "aas_create.h"
|
||||
|
||||
#define AAS_Error Error
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SwapAASData( void ) {
|
||||
int i, j;
|
||||
//bounding boxes
|
||||
for ( i = 0; i < ( *aasworld ).numbboxes; i++ )
|
||||
{
|
||||
( *aasworld ).bboxes[i].presencetype = LittleLong( ( *aasworld ).bboxes[i].presencetype );
|
||||
( *aasworld ).bboxes[i].flags = LittleLong( ( *aasworld ).bboxes[i].flags );
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
( *aasworld ).bboxes[i].mins[j] = LittleLong( ( *aasworld ).bboxes[i].mins[j] );
|
||||
( *aasworld ).bboxes[i].maxs[j] = LittleLong( ( *aasworld ).bboxes[i].maxs[j] );
|
||||
} //end for
|
||||
} //end for
|
||||
//vertexes
|
||||
for ( i = 0; i < ( *aasworld ).numvertexes; i++ )
|
||||
{
|
||||
for ( j = 0; j < 3; j++ )
|
||||
( *aasworld ).vertexes[i][j] = LittleFloat( ( *aasworld ).vertexes[i][j] );
|
||||
} //end for
|
||||
//planes
|
||||
for ( i = 0; i < ( *aasworld ).numplanes; i++ )
|
||||
{
|
||||
for ( j = 0; j < 3; j++ )
|
||||
( *aasworld ).planes[i].normal[j] = LittleFloat( ( *aasworld ).planes[i].normal[j] );
|
||||
( *aasworld ).planes[i].dist = LittleFloat( ( *aasworld ).planes[i].dist );
|
||||
( *aasworld ).planes[i].type = LittleLong( ( *aasworld ).planes[i].type );
|
||||
} //end for
|
||||
//edges
|
||||
for ( i = 0; i < ( *aasworld ).numedges; i++ )
|
||||
{
|
||||
( *aasworld ).edges[i].v[0] = LittleLong( ( *aasworld ).edges[i].v[0] );
|
||||
( *aasworld ).edges[i].v[1] = LittleLong( ( *aasworld ).edges[i].v[1] );
|
||||
} //end for
|
||||
//edgeindex
|
||||
for ( i = 0; i < ( *aasworld ).edgeindexsize; i++ )
|
||||
{
|
||||
( *aasworld ).edgeindex[i] = LittleLong( ( *aasworld ).edgeindex[i] );
|
||||
} //end for
|
||||
//faces
|
||||
for ( i = 0; i < ( *aasworld ).numfaces; i++ )
|
||||
{
|
||||
( *aasworld ).faces[i].planenum = LittleLong( ( *aasworld ).faces[i].planenum );
|
||||
( *aasworld ).faces[i].faceflags = LittleLong( ( *aasworld ).faces[i].faceflags );
|
||||
( *aasworld ).faces[i].numedges = LittleLong( ( *aasworld ).faces[i].numedges );
|
||||
( *aasworld ).faces[i].firstedge = LittleLong( ( *aasworld ).faces[i].firstedge );
|
||||
( *aasworld ).faces[i].frontarea = LittleLong( ( *aasworld ).faces[i].frontarea );
|
||||
( *aasworld ).faces[i].backarea = LittleLong( ( *aasworld ).faces[i].backarea );
|
||||
} //end for
|
||||
//face index
|
||||
for ( i = 0; i < ( *aasworld ).faceindexsize; i++ )
|
||||
{
|
||||
( *aasworld ).faceindex[i] = LittleLong( ( *aasworld ).faceindex[i] );
|
||||
} //end for
|
||||
//convex areas
|
||||
for ( i = 0; i < ( *aasworld ).numareas; i++ )
|
||||
{
|
||||
( *aasworld ).areas[i].areanum = LittleLong( ( *aasworld ).areas[i].areanum );
|
||||
( *aasworld ).areas[i].numfaces = LittleLong( ( *aasworld ).areas[i].numfaces );
|
||||
( *aasworld ).areas[i].firstface = LittleLong( ( *aasworld ).areas[i].firstface );
|
||||
for ( j = 0; j < 3; j++ )
|
||||
{
|
||||
( *aasworld ).areas[i].mins[j] = LittleFloat( ( *aasworld ).areas[i].mins[j] );
|
||||
( *aasworld ).areas[i].maxs[j] = LittleFloat( ( *aasworld ).areas[i].maxs[j] );
|
||||
( *aasworld ).areas[i].center[j] = LittleFloat( ( *aasworld ).areas[i].center[j] );
|
||||
} //end for
|
||||
} //end for
|
||||
//area settings
|
||||
for ( i = 0; i < ( *aasworld ).numareasettings; i++ )
|
||||
{
|
||||
( *aasworld ).areasettings[i].contents = LittleLong( ( *aasworld ).areasettings[i].contents );
|
||||
( *aasworld ).areasettings[i].areaflags = LittleLong( ( *aasworld ).areasettings[i].areaflags );
|
||||
( *aasworld ).areasettings[i].presencetype = LittleLong( ( *aasworld ).areasettings[i].presencetype );
|
||||
( *aasworld ).areasettings[i].cluster = LittleLong( ( *aasworld ).areasettings[i].cluster );
|
||||
( *aasworld ).areasettings[i].clusterareanum = LittleLong( ( *aasworld ).areasettings[i].clusterareanum );
|
||||
( *aasworld ).areasettings[i].numreachableareas = LittleLong( ( *aasworld ).areasettings[i].numreachableareas );
|
||||
( *aasworld ).areasettings[i].firstreachablearea = LittleLong( ( *aasworld ).areasettings[i].firstreachablearea );
|
||||
// Ridah
|
||||
( *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].numportals = LittleLong( ( *aasworld ).clusters[i].numportals );
|
||||
( *aasworld ).clusters[i].firstportal = LittleLong( ( *aasworld ).clusters[i].firstportal );
|
||||
} //end for
|
||||
} //end of the function AAS_SwapAASData
|
||||
//===========================================================================
|
||||
// dump the current loaded aas file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DumpAASData( void ) {
|
||||
/*
|
||||
if ((*aasworld).vertexes) FreeMemory((*aasworld).vertexes);
|
||||
(*aasworld).vertexes = NULL;
|
||||
if ((*aasworld).planes) FreeMemory((*aasworld).planes);
|
||||
(*aasworld).planes = NULL;
|
||||
if ((*aasworld).edges) FreeMemory((*aasworld).edges);
|
||||
(*aasworld).edges = NULL;
|
||||
if ((*aasworld).edgeindex) FreeMemory((*aasworld).edgeindex);
|
||||
(*aasworld).edgeindex = NULL;
|
||||
if ((*aasworld).faces) FreeMemory((*aasworld).faces);
|
||||
(*aasworld).faces = NULL;
|
||||
if ((*aasworld).faceindex) FreeMemory((*aasworld).faceindex);
|
||||
(*aasworld).faceindex = NULL;
|
||||
if ((*aasworld).areas) FreeMemory((*aasworld).areas);
|
||||
(*aasworld).areas = NULL;
|
||||
if ((*aasworld).areasettings) FreeMemory((*aasworld).areasettings);
|
||||
(*aasworld).areasettings = NULL;
|
||||
if ((*aasworld).reachability) FreeMemory((*aasworld).reachability);
|
||||
(*aasworld).reachability = NULL;
|
||||
*/
|
||||
( *aasworld ).loaded = false;
|
||||
} //end of the function AAS_DumpAASData
|
||||
//===========================================================================
|
||||
// allocate memory and read a lump of a AAS file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
char *AAS_LoadAASLump( FILE *fp, int offset, int length, void *buf ) {
|
||||
if ( !length ) {
|
||||
printf( "lump size 0\n" );
|
||||
return buf;
|
||||
} //end if
|
||||
//seek to the data
|
||||
if ( fseek( fp, offset, SEEK_SET ) ) {
|
||||
AAS_Error( "can't seek to lump\n" );
|
||||
AAS_DumpAASData();
|
||||
fclose( fp );
|
||||
return 0;
|
||||
} //end if
|
||||
//allocate memory
|
||||
if ( !buf ) {
|
||||
buf = (void *) GetClearedMemory( length );
|
||||
}
|
||||
//read the data
|
||||
if ( fread( (char *) buf, 1, length, fp ) != length ) {
|
||||
AAS_Error( "can't read lump\n" );
|
||||
FreeMemory( buf );
|
||||
AAS_DumpAASData();
|
||||
fclose( fp );
|
||||
return NULL;
|
||||
} //end if
|
||||
return buf;
|
||||
} //end of the function AAS_LoadAASLump
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_DData( unsigned char *data, int size ) {
|
||||
int i;
|
||||
|
||||
for ( i = 0; i < size; i++ )
|
||||
{
|
||||
data[i] ^= (unsigned char) i * 119;
|
||||
} //end for
|
||||
} //end of the function AAS_DData
|
||||
//===========================================================================
|
||||
// load an aas file
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_LoadAASFile( char *filename, int fpoffset, int fplength ) {
|
||||
FILE *fp;
|
||||
aas_header_t header;
|
||||
int offset, length;
|
||||
|
||||
//dump current loaded aas file
|
||||
AAS_DumpAASData();
|
||||
//open the file
|
||||
fp = fopen( filename, "rb" );
|
||||
if ( !fp ) {
|
||||
AAS_Error( "can't open %s\n", filename );
|
||||
return false;
|
||||
} //end if
|
||||
//seek to the correct position (in the pak file)
|
||||
if ( fseek( fp, fpoffset, SEEK_SET ) ) {
|
||||
AAS_Error( "can't seek to file %s\n" );
|
||||
fclose( fp );
|
||||
return false;
|
||||
} //end if
|
||||
//read the header
|
||||
if ( fread( &header, sizeof( aas_header_t ), 1, fp ) != 1 ) {
|
||||
AAS_Error( "can't read header of file %s\n", filename );
|
||||
fclose( fp );
|
||||
return false;
|
||||
} //end if
|
||||
//check header identification
|
||||
header.ident = LittleLong( header.ident );
|
||||
if ( header.ident != AASID ) {
|
||||
AAS_Error( "%s is not an AAS file\n", filename );
|
||||
fclose( fp );
|
||||
return false;
|
||||
} //end if
|
||||
//check the version
|
||||
header.version = LittleLong( header.version );
|
||||
if ( header.version != AASVERSION ) {
|
||||
AAS_Error( "%s is version %i, not %i\n", filename, header.version, AASVERSION );
|
||||
fclose( fp );
|
||||
return false;
|
||||
} //end if
|
||||
//
|
||||
if ( header.version == AASVERSION ) {
|
||||
AAS_DData( (unsigned char *) &header + 8, sizeof( aas_header_t ) - 8 );
|
||||
} //end if
|
||||
( *aasworld ).bspchecksum = LittleLong( header.bspchecksum );
|
||||
//load the lumps:
|
||||
//bounding boxes
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_BBOXES].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_BBOXES].filelen );
|
||||
( *aasworld ).bboxes = (aas_bbox_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).bboxes );
|
||||
if ( !( *aasworld ).bboxes ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numbboxes = length / sizeof( aas_bbox_t );
|
||||
//vertexes
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_VERTEXES].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_VERTEXES].filelen );
|
||||
( *aasworld ).vertexes = (aas_vertex_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).vertexes );
|
||||
if ( !( *aasworld ).vertexes ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numvertexes = length / sizeof( aas_vertex_t );
|
||||
//planes
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_PLANES].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_PLANES].filelen );
|
||||
( *aasworld ).planes = (aas_plane_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).planes );
|
||||
if ( !( *aasworld ).planes ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numplanes = length / sizeof( aas_plane_t );
|
||||
//edges
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_EDGES].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_EDGES].filelen );
|
||||
( *aasworld ).edges = (aas_edge_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).edges );
|
||||
if ( !( *aasworld ).edges ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numedges = length / sizeof( aas_edge_t );
|
||||
//edgeindex
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_EDGEINDEX].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_EDGEINDEX].filelen );
|
||||
( *aasworld ).edgeindex = (aas_edgeindex_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).edgeindex );
|
||||
if ( !( *aasworld ).edgeindex ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).edgeindexsize = length / sizeof( aas_edgeindex_t );
|
||||
//faces
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_FACES].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_FACES].filelen );
|
||||
( *aasworld ).faces = (aas_face_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).faces );
|
||||
if ( !( *aasworld ).faces ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numfaces = length / sizeof( aas_face_t );
|
||||
//faceindex
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_FACEINDEX].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_FACEINDEX].filelen );
|
||||
( *aasworld ).faceindex = (aas_faceindex_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).faceindex );
|
||||
if ( !( *aasworld ).faceindex ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).faceindexsize = length / sizeof( int );
|
||||
//convex areas
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_AREAS].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_AREAS].filelen );
|
||||
( *aasworld ).areas = (aas_area_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).areas );
|
||||
if ( !( *aasworld ).areas ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numareas = length / sizeof( aas_area_t );
|
||||
//area settings
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_AREASETTINGS].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_AREASETTINGS].filelen );
|
||||
( *aasworld ).areasettings = (aas_areasettings_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).areasettings );
|
||||
if ( !( *aasworld ).areasettings ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numareasettings = length / sizeof( aas_areasettings_t );
|
||||
//reachability list
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_REACHABILITY].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_REACHABILITY].filelen );
|
||||
( *aasworld ).reachability = (aas_reachability_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).reachability );
|
||||
if ( length && !( *aasworld ).reachability ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).reachabilitysize = length / sizeof( aas_reachability_t );
|
||||
//nodes
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_NODES].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_NODES].filelen );
|
||||
( *aasworld ).nodes = (aas_node_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).nodes );
|
||||
if ( !( *aasworld ).nodes ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numnodes = length / sizeof( aas_node_t );
|
||||
//cluster portals
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_PORTALS].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_PORTALS].filelen );
|
||||
( *aasworld ).portals = (aas_portal_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).portals );
|
||||
if ( length && !( *aasworld ).portals ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numportals = length / sizeof( aas_portal_t );
|
||||
//cluster portal index
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_PORTALINDEX].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_PORTALINDEX].filelen );
|
||||
( *aasworld ).portalindex = (aas_portalindex_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).portalindex );
|
||||
if ( length && !( *aasworld ).portalindex ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).portalindexsize = length / sizeof( aas_portalindex_t );
|
||||
//clusters
|
||||
offset = fpoffset + LittleLong( header.lumps[AASLUMP_CLUSTERS].fileofs );
|
||||
length = LittleLong( header.lumps[AASLUMP_CLUSTERS].filelen );
|
||||
( *aasworld ).clusters = (aas_cluster_t *) AAS_LoadAASLump( fp, offset, length, ( *aasworld ).clusters );
|
||||
if ( length && !( *aasworld ).clusters ) {
|
||||
return false;
|
||||
}
|
||||
( *aasworld ).numclusters = length / sizeof( aas_cluster_t );
|
||||
//swap everything
|
||||
AAS_SwapAASData();
|
||||
//aas file is loaded
|
||||
( *aasworld ).loaded = true;
|
||||
//close the file
|
||||
fclose( fp );
|
||||
return true;
|
||||
} //end of the function AAS_LoadAASFile
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_WriteAASLump( FILE *fp, aas_header_t *h, int lumpnum, void *data, int length ) {
|
||||
aas_lump_t *lump;
|
||||
|
||||
lump = &h->lumps[lumpnum];
|
||||
|
||||
lump->fileofs = LittleLong( ftell( fp ) );
|
||||
lump->filelen = LittleLong( length );
|
||||
|
||||
if ( length > 0 ) {
|
||||
if ( fwrite( data, length, 1, fp ) < 1 ) {
|
||||
Log_Print( "error writing lump %s\n", lumpnum );
|
||||
fclose( fp );
|
||||
return false;
|
||||
} //end if
|
||||
} //end if
|
||||
return true;
|
||||
} //end of the function AAS_WriteAASLump
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowNumReachabilities( int tt, char *name ) {
|
||||
int i, num;
|
||||
|
||||
num = 0;
|
||||
for ( i = 0; i < ( *aasworld ).reachabilitysize; i++ )
|
||||
{
|
||||
if ( ( ( *aasworld ).reachability[i].traveltype & TRAVELTYPE_MASK ) == tt ) {
|
||||
num++;
|
||||
}
|
||||
} //end for
|
||||
Log_Print( "%6d %s\n", num, name );
|
||||
} //end of the function AAS_ShowNumReachabilities
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ShowTotals( void ) {
|
||||
Log_Print( "numvertexes = %d\r\n", ( *aasworld ).numvertexes );
|
||||
Log_Print( "numplanes = %d\r\n", ( *aasworld ).numplanes );
|
||||
Log_Print( "numedges = %d\r\n", ( *aasworld ).numedges );
|
||||
Log_Print( "edgeindexsize = %d\r\n", ( *aasworld ).edgeindexsize );
|
||||
Log_Print( "numfaces = %d\r\n", ( *aasworld ).numfaces );
|
||||
Log_Print( "faceindexsize = %d\r\n", ( *aasworld ).faceindexsize );
|
||||
Log_Print( "numareas = %d\r\n", ( *aasworld ).numareas );
|
||||
Log_Print( "numareasettings = %d\r\n", ( *aasworld ).numareasettings );
|
||||
Log_Print( "reachabilitysize = %d\r\n", ( *aasworld ).reachabilitysize );
|
||||
Log_Print( "numnodes = %d\r\n", ( *aasworld ).numnodes );
|
||||
Log_Print( "numportals = %d\r\n", ( *aasworld ).numportals );
|
||||
Log_Print( "portalindexsize = %d\r\n", ( *aasworld ).portalindexsize );
|
||||
Log_Print( "numclusters = %d\r\n", ( *aasworld ).numclusters );
|
||||
AAS_ShowNumReachabilities( TRAVEL_WALK, "walk" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_CROUCH, "crouch" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_BARRIERJUMP, "barrier jump" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_JUMP, "jump" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_LADDER, "ladder" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_WALKOFFLEDGE, "walk off ledge" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_SWIM, "swim" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_WATERJUMP, "water jump" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_TELEPORT, "teleport" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_ELEVATOR, "elevator" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_ROCKETJUMP, "rocket jump" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_BFGJUMP, "bfg jump" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_GRAPPLEHOOK, "grapple hook" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_DOUBLEJUMP, "double jump" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_RAMPJUMP, "ramp jump" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_STRAFEJUMP, "strafe jump" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_JUMPPAD, "jump pad" );
|
||||
AAS_ShowNumReachabilities( TRAVEL_FUNCBOB, "func bob" );
|
||||
|
||||
} //end of the function AAS_ShowTotals
|
||||
//===========================================================================
|
||||
// aas data is useless after writing to file because it is byte swapped
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_WriteAASFile( char *filename ) {
|
||||
aas_header_t header;
|
||||
FILE *fp;
|
||||
|
||||
Log_Print( "writing %s\n", filename );
|
||||
AAS_ShowTotals();
|
||||
//swap the aas data
|
||||
AAS_SwapAASData();
|
||||
//initialize the file header
|
||||
memset( &header, 0, sizeof( aas_header_t ) );
|
||||
header.ident = LittleLong( AASID );
|
||||
header.version = LittleLong( AASVERSION );
|
||||
header.bspchecksum = LittleLong( ( *aasworld ).bspchecksum );
|
||||
//open a new file
|
||||
fp = fopen( filename, "wb" );
|
||||
if ( !fp ) {
|
||||
Log_Print( "error opening %s\n", filename );
|
||||
return false;
|
||||
} //end if
|
||||
//write the header
|
||||
if ( fwrite( &header, sizeof( aas_header_t ), 1, fp ) < 1 ) {
|
||||
fclose( fp );
|
||||
return false;
|
||||
} //end if
|
||||
//add the data lumps to the file
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_BBOXES, ( *aasworld ).bboxes,
|
||||
( *aasworld ).numbboxes * sizeof( aas_bbox_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_VERTEXES, ( *aasworld ).vertexes,
|
||||
( *aasworld ).numvertexes * sizeof( aas_vertex_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_PLANES, ( *aasworld ).planes,
|
||||
( *aasworld ).numplanes * sizeof( aas_plane_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_EDGES, ( *aasworld ).edges,
|
||||
( *aasworld ).numedges * sizeof( aas_edge_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_EDGEINDEX, ( *aasworld ).edgeindex,
|
||||
( *aasworld ).edgeindexsize * sizeof( aas_edgeindex_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_FACES, ( *aasworld ).faces,
|
||||
( *aasworld ).numfaces * sizeof( aas_face_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_FACEINDEX, ( *aasworld ).faceindex,
|
||||
( *aasworld ).faceindexsize * sizeof( aas_faceindex_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_AREAS, ( *aasworld ).areas,
|
||||
( *aasworld ).numareas * sizeof( aas_area_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_AREASETTINGS, ( *aasworld ).areasettings,
|
||||
( *aasworld ).numareasettings * sizeof( aas_areasettings_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_REACHABILITY, ( *aasworld ).reachability,
|
||||
( *aasworld ).reachabilitysize * sizeof( aas_reachability_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_NODES, ( *aasworld ).nodes,
|
||||
( *aasworld ).numnodes * sizeof( aas_node_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_PORTALS, ( *aasworld ).portals,
|
||||
( *aasworld ).numportals * sizeof( aas_portal_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_PORTALINDEX, ( *aasworld ).portalindex,
|
||||
( *aasworld ).portalindexsize * sizeof( aas_portalindex_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( !AAS_WriteAASLump( fp, &header, AASLUMP_CLUSTERS, ( *aasworld ).clusters,
|
||||
( *aasworld ).numclusters * sizeof( aas_cluster_t ) ) ) {
|
||||
return false;
|
||||
}
|
||||
//rewrite the header with the added lumps
|
||||
fseek( fp, 0, SEEK_SET );
|
||||
AAS_DData( (unsigned char *) &header + 8, sizeof( aas_header_t ) - 8 );
|
||||
if ( fwrite( &header, sizeof( aas_header_t ), 1, fp ) < 1 ) {
|
||||
fclose( fp );
|
||||
return false;
|
||||
} //end if
|
||||
//close the file
|
||||
fclose( fp );
|
||||
return true;
|
||||
} //end of the function AAS_WriteAASFile
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_write.h
|
||||
// Function:
|
||||
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
|
||||
// Last update: 1997-12-04
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
qboolean AAS_WriteAASFile( char *filename );
|
||||
qboolean AAS_LoadAASFile( char *filename, int fpoffset, int fplength );
|
||||
|
|
@ -0,0 +1,688 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_gsubdiv.c
|
||||
// Function: Gravitational Subdivision
|
||||
// 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"
|
||||
#include "aas_cfg.h"
|
||||
|
||||
#define FACECLIP_EPSILON 0.2
|
||||
#define FACE_EPSILON 1.0
|
||||
|
||||
int numgravitationalsubdivisions = 0;
|
||||
int numladdersubdivisions = 0;
|
||||
|
||||
//NOTE: only do gravitational subdivision BEFORE area merging!!!!!!!
|
||||
// because the bsp tree isn't refreshes like with ladder subdivision
|
||||
|
||||
//===========================================================================
|
||||
// NOTE: the original face is invalid after splitting
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SplitFace( tmp_face_t *face, vec3_t normal, float dist,
|
||||
tmp_face_t **frontface, tmp_face_t **backface ) {
|
||||
winding_t *frontw, *backw;
|
||||
|
||||
//
|
||||
*frontface = *backface = NULL;
|
||||
|
||||
ClipWindingEpsilon( face->winding, normal, dist, FACECLIP_EPSILON, &frontw, &backw );
|
||||
|
||||
#ifdef DEBUG
|
||||
//
|
||||
if ( frontw ) {
|
||||
if ( WindingIsTiny( frontw ) ) {
|
||||
Log_Write( "AAS_SplitFace: tiny back face\r\n" );
|
||||
FreeWinding( frontw );
|
||||
frontw = NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
if ( backw ) {
|
||||
if ( WindingIsTiny( backw ) ) {
|
||||
Log_Write( "AAS_SplitFace: tiny back face\r\n" );
|
||||
FreeWinding( backw );
|
||||
backw = NULL;
|
||||
} //end if
|
||||
} //end if
|
||||
#endif //DEBUG
|
||||
//if the winding was split
|
||||
if ( frontw ) {
|
||||
//check bounds
|
||||
( *frontface ) = AAS_AllocTmpFace();
|
||||
( *frontface )->planenum = face->planenum;
|
||||
( *frontface )->winding = frontw;
|
||||
( *frontface )->faceflags = face->faceflags;
|
||||
} //end if
|
||||
if ( backw ) {
|
||||
//check bounds
|
||||
( *backface ) = AAS_AllocTmpFace();
|
||||
( *backface )->planenum = face->planenum;
|
||||
( *backface )->winding = backw;
|
||||
( *backface )->faceflags = face->faceflags;
|
||||
} //end if
|
||||
} //end of the function AAS_SplitFace
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
winding_t *AAS_SplitWinding( tmp_area_t *tmparea, int planenum ) {
|
||||
tmp_face_t *face;
|
||||
plane_t *plane;
|
||||
int side;
|
||||
winding_t *splitwinding;
|
||||
|
||||
//
|
||||
plane = &mapplanes[planenum];
|
||||
//create a split winding, first base winding for plane
|
||||
splitwinding = BaseWindingForPlane( plane->normal, plane->dist );
|
||||
//chop with all the faces of the area
|
||||
for ( face = tmparea->tmpfaces; face && splitwinding; face = face->next[side] )
|
||||
{
|
||||
//side of the face the original area was on
|
||||
side = face->frontarea != tmparea;
|
||||
plane = &mapplanes[face->planenum ^ side];
|
||||
ChopWindingInPlace( &splitwinding, plane->normal, plane->dist, 0 ); // PLANESIDE_EPSILON);
|
||||
} //end for
|
||||
return splitwinding;
|
||||
} //end of the function AAS_SplitWinding
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_TestSplitPlane( tmp_area_t *tmparea, vec3_t normal, float dist,
|
||||
int *facesplits, int *groundsplits, int *epsilonfaces ) {
|
||||
int j, side, front, back, planenum;
|
||||
float d, d_front, d_back;
|
||||
tmp_face_t *face;
|
||||
winding_t *w;
|
||||
|
||||
*facesplits = *groundsplits = *epsilonfaces = 0;
|
||||
|
||||
planenum = FindFloatPlane( normal, dist );
|
||||
|
||||
w = AAS_SplitWinding( tmparea, planenum );
|
||||
if ( !w ) {
|
||||
return false;
|
||||
}
|
||||
FreeWinding( w );
|
||||
//
|
||||
for ( face = tmparea->tmpfaces; face; face = face->next[side] )
|
||||
{
|
||||
//side of the face the area is on
|
||||
side = face->frontarea != tmparea;
|
||||
|
||||
if ( ( face->planenum & ~1 ) == ( planenum & ~1 ) ) {
|
||||
Log_Print( "AAS_TestSplitPlane: tried face plane as splitter\n" );
|
||||
return false;
|
||||
} //end if
|
||||
w = face->winding;
|
||||
//reset distance at front and back side of plane
|
||||
d_front = d_back = 0;
|
||||
//reset front and back flags
|
||||
front = back = 0;
|
||||
for ( j = 0; j < w->numpoints; j++ )
|
||||
{
|
||||
d = DotProduct( w->p[j], normal ) - dist;
|
||||
if ( d > d_front ) {
|
||||
d_front = d;
|
||||
}
|
||||
if ( d < d_back ) {
|
||||
d_back = d;
|
||||
}
|
||||
|
||||
if ( d > 0.4 ) { // PLANESIDE_EPSILON)
|
||||
front = 1;
|
||||
}
|
||||
if ( d < -0.4 ) { // PLANESIDE_EPSILON)
|
||||
back = 1;
|
||||
}
|
||||
} //end for
|
||||
//check for an epsilon face
|
||||
if ( ( d_front > FACECLIP_EPSILON && d_front < FACE_EPSILON )
|
||||
|| ( d_back < -FACECLIP_EPSILON && d_back > -FACE_EPSILON ) ) {
|
||||
( *epsilonfaces )++;
|
||||
} //end if
|
||||
//if the face has points at both sides of the plane
|
||||
if ( front && back ) {
|
||||
( *facesplits )++;
|
||||
if ( face->faceflags & FACE_GROUND ) {
|
||||
( *groundsplits )++;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
return true;
|
||||
} //end of the function AAS_TestSplitPlane
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SplitArea( tmp_area_t *tmparea, int planenum, tmp_area_t **frontarea, tmp_area_t **backarea ) {
|
||||
int side;
|
||||
tmp_area_t *facefrontarea, *facebackarea, *faceotherarea;
|
||||
tmp_face_t *face, *frontface, *backface, *splitface, *nextface;
|
||||
winding_t *splitwinding;
|
||||
plane_t *splitplane;
|
||||
|
||||
/*
|
||||
#ifdef AW_DEBUG
|
||||
int facesplits, groundsplits, epsilonface;
|
||||
Log_Print("\n----------------------\n");
|
||||
Log_Print("splitting area %d\n", areanum);
|
||||
Log_Print("with normal = \'%f %f %f\', dist = %f\n", normal[0], normal[1], normal[2], dist);
|
||||
AAS_TestSplitPlane(areanum, normal, dist,
|
||||
&facesplits, &groundsplits, &epsilonface);
|
||||
Log_Print("face splits = %d\nground splits = %d\n", facesplits, groundsplits);
|
||||
if (epsilonface) Log_Print("aaahh epsilon face\n");
|
||||
#endif //AW_DEBUG*/
|
||||
//the original area
|
||||
|
||||
AAS_FlipAreaFaces( tmparea );
|
||||
AAS_CheckArea( tmparea );
|
||||
//
|
||||
splitplane = &mapplanes[planenum];
|
||||
/* //create a split winding, first base winding for plane
|
||||
splitwinding = BaseWindingForPlane(splitplane->normal, splitplane->dist);
|
||||
//chop with all the faces of the area
|
||||
for (face = tmparea->tmpfaces; face && splitwinding; face = face->next[side])
|
||||
{
|
||||
//side of the face the original area was on
|
||||
side = face->frontarea != tmparea->areanum;
|
||||
plane = &mapplanes[face->planenum ^ side];
|
||||
ChopWindingInPlace(&splitwinding, plane->normal, plane->dist, 0); // PLANESIDE_EPSILON);
|
||||
} //end for*/
|
||||
splitwinding = AAS_SplitWinding( tmparea, planenum );
|
||||
if ( !splitwinding ) {
|
||||
/*
|
||||
#ifdef DEBUG
|
||||
AAS_TestSplitPlane(areanum, normal, dist,
|
||||
&facesplits, &groundsplits, &epsilonface);
|
||||
Log_Print("\nface splits = %d\nground splits = %d\n", facesplits, groundsplits);
|
||||
if (epsilonface) Log_Print("aaahh epsilon face\n");
|
||||
#endif //DEBUG*/
|
||||
Error( "AAS_SplitArea: no split winding when splitting area %d\n", tmparea->areanum );
|
||||
} //end if
|
||||
//create a split face
|
||||
splitface = AAS_AllocTmpFace();
|
||||
//get the map plane
|
||||
splitface->planenum = planenum;
|
||||
//store the split winding
|
||||
splitface->winding = splitwinding;
|
||||
//the new front area
|
||||
( *frontarea ) = AAS_AllocTmpArea();
|
||||
( *frontarea )->presencetype = tmparea->presencetype;
|
||||
( *frontarea )->contents = tmparea->contents;
|
||||
( *frontarea )->modelnum = tmparea->modelnum;
|
||||
( *frontarea )->tmpfaces = NULL;
|
||||
//the new back area
|
||||
( *backarea ) = AAS_AllocTmpArea();
|
||||
( *backarea )->presencetype = tmparea->presencetype;
|
||||
( *backarea )->contents = tmparea->contents;
|
||||
( *backarea )->modelnum = tmparea->modelnum;
|
||||
( *backarea )->tmpfaces = NULL;
|
||||
//add the split face to the new areas
|
||||
AAS_AddFaceSideToArea( splitface, 0, ( *frontarea ) );
|
||||
AAS_AddFaceSideToArea( splitface, 1, ( *backarea ) );
|
||||
|
||||
//split all the faces of the original area
|
||||
for ( face = tmparea->tmpfaces; face; face = nextface )
|
||||
{
|
||||
//side of the face the original area was on
|
||||
side = face->frontarea != tmparea;
|
||||
//next face of the original area
|
||||
nextface = face->next[side];
|
||||
//front area of the face
|
||||
facefrontarea = face->frontarea;
|
||||
//back area of the face
|
||||
facebackarea = face->backarea;
|
||||
//remove the face from both the front and back areas
|
||||
if ( facefrontarea ) {
|
||||
AAS_RemoveFaceFromArea( face, facefrontarea );
|
||||
}
|
||||
if ( facebackarea ) {
|
||||
AAS_RemoveFaceFromArea( face, facebackarea );
|
||||
}
|
||||
//split the face
|
||||
AAS_SplitFace( face, splitplane->normal, splitplane->dist, &frontface, &backface );
|
||||
//free the original face
|
||||
AAS_FreeTmpFace( face );
|
||||
//get the number of the area at the other side of the face
|
||||
if ( side ) {
|
||||
faceotherarea = facefrontarea;
|
||||
} else { faceotherarea = facebackarea;}
|
||||
//if there is an area at the other side of the original face
|
||||
if ( faceotherarea ) {
|
||||
if ( frontface ) {
|
||||
AAS_AddFaceSideToArea( frontface, !side, faceotherarea );
|
||||
}
|
||||
if ( backface ) {
|
||||
AAS_AddFaceSideToArea( backface, !side, faceotherarea );
|
||||
}
|
||||
} //end if
|
||||
//add the front and back part left after splitting the original face to the new areas
|
||||
if ( frontface ) {
|
||||
AAS_AddFaceSideToArea( frontface, side, ( *frontarea ) );
|
||||
}
|
||||
if ( backface ) {
|
||||
AAS_AddFaceSideToArea( backface, side, ( *backarea ) );
|
||||
}
|
||||
} //end for
|
||||
|
||||
if ( !( *frontarea )->tmpfaces ) {
|
||||
Log_Print( "AAS_SplitArea: front area without faces\n" );
|
||||
}
|
||||
if ( !( *backarea )->tmpfaces ) {
|
||||
Log_Print( "AAS_SplitArea: back area without faces\n" );
|
||||
}
|
||||
|
||||
tmparea->invalid = true;
|
||||
/*
|
||||
#ifdef AW_DEBUG
|
||||
for (i = 0, face = frontarea->tmpfaces; face; face = face->next[side])
|
||||
{
|
||||
side = face->frontarea != frontarea->areanum;
|
||||
i++;
|
||||
} //end for
|
||||
Log_Print("created front area %d with %d faces\n", frontarea->areanum, i);
|
||||
|
||||
for (i = 0, face = backarea->tmpfaces; face; face = face->next[side])
|
||||
{
|
||||
side = face->frontarea != backarea->areanum;
|
||||
i++;
|
||||
} //end for
|
||||
Log_Print("created back area %d with %d faces\n", backarea->areanum, i);
|
||||
#endif //AW_DEBUG*/
|
||||
|
||||
AAS_FlipAreaFaces( ( *frontarea ) );
|
||||
AAS_FlipAreaFaces( ( *backarea ) );
|
||||
//
|
||||
AAS_CheckArea( ( *frontarea ) );
|
||||
AAS_CheckArea( ( *backarea ) );
|
||||
} //end of the function AAS_SplitArea
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_FindBestAreaSplitPlane( tmp_area_t *tmparea, vec3_t normal, float *dist ) {
|
||||
int side1, side2;
|
||||
int foundsplitter, facesplits, groundsplits, epsilonfaces, bestepsilonfaces;
|
||||
float bestvalue, value;
|
||||
tmp_face_t *face1, *face2;
|
||||
vec3_t tmpnormal, invgravity;
|
||||
float tmpdist;
|
||||
|
||||
//get inverse of gravity direction
|
||||
VectorCopy( cfg.phys_gravitydirection, invgravity );
|
||||
VectorInverse( invgravity );
|
||||
|
||||
foundsplitter = false;
|
||||
bestvalue = -999999;
|
||||
bestepsilonfaces = 0;
|
||||
//
|
||||
#ifdef AW_DEBUG
|
||||
Log_Print( "finding split plane for area %d\n", tmparea->areanum );
|
||||
#endif //AW_DEBUG
|
||||
for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
|
||||
{
|
||||
//side of the face the area is on
|
||||
side1 = face1->frontarea != tmparea;
|
||||
//
|
||||
if ( WindingIsTiny( face1->winding ) ) {
|
||||
Log_Write( "gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum );
|
||||
continue;
|
||||
} //end if
|
||||
//if the face isn't a gap or ground there's no split edge
|
||||
if ( !( face1->faceflags & FACE_GROUND ) && !AAS_GapFace( face1, side1 ) ) {
|
||||
continue;
|
||||
}
|
||||
//
|
||||
for ( face2 = face1->next[side1]; face2; face2 = face2->next[side2] )
|
||||
{
|
||||
//side of the face the area is on
|
||||
side2 = face2->frontarea != tmparea;
|
||||
//
|
||||
if ( WindingIsTiny( face1->winding ) ) {
|
||||
Log_Write( "gsubdiv: area %d has a tiny winding\r\n", tmparea->areanum );
|
||||
continue;
|
||||
} //end if
|
||||
//if the face isn't a gap or ground there's no split edge
|
||||
if ( !( face2->faceflags & FACE_GROUND ) && !AAS_GapFace( face2, side2 ) ) {
|
||||
continue;
|
||||
}
|
||||
//only split between gaps and ground
|
||||
if ( !( ( ( face1->faceflags & FACE_GROUND ) && AAS_GapFace( face2, side2 ) ) ||
|
||||
( ( face2->faceflags & FACE_GROUND ) && AAS_GapFace( face1, side1 ) ) ) ) {
|
||||
continue;
|
||||
}
|
||||
//find a plane seperating the windings of the faces
|
||||
if ( !FindPlaneSeperatingWindings( face1->winding, face2->winding, invgravity,
|
||||
tmpnormal, &tmpdist ) ) {
|
||||
continue;
|
||||
}
|
||||
#ifdef AW_DEBUG
|
||||
Log_Print( "normal = \'%f %f %f\', dist = %f\n",
|
||||
tmpnormal[0], tmpnormal[1], tmpnormal[2], tmpdist );
|
||||
#endif //AW_DEBUG
|
||||
//get metrics for this vertical plane
|
||||
if ( !AAS_TestSplitPlane( tmparea, tmpnormal, tmpdist,
|
||||
&facesplits, &groundsplits, &epsilonfaces ) ) {
|
||||
continue;
|
||||
} //end if
|
||||
#ifdef AW_DEBUG
|
||||
Log_Print( "face splits = %d\nground splits = %d\n",
|
||||
facesplits, groundsplits );
|
||||
#endif //AW_DEBUG
|
||||
value = 100 - facesplits - 2 * groundsplits;
|
||||
//avoid epsilon faces
|
||||
value += epsilonfaces * -1000;
|
||||
if ( value > bestvalue ) {
|
||||
VectorCopy( tmpnormal, normal );
|
||||
*dist = tmpdist;
|
||||
bestvalue = value;
|
||||
bestepsilonfaces = epsilonfaces;
|
||||
foundsplitter = true;
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
if ( bestepsilonfaces ) {
|
||||
Log_Write( "found %d epsilon faces trying to split area %d\r\n",
|
||||
epsilonfaces, tmparea->areanum );
|
||||
} //end else
|
||||
return foundsplitter;
|
||||
} //end of the function AAS_FindBestAreaSplitPlane
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_SubdivideArea_r( tmp_node_t *tmpnode ) {
|
||||
int planenum;
|
||||
tmp_area_t *frontarea, *backarea;
|
||||
tmp_node_t *tmpnode1, *tmpnode2;
|
||||
vec3_t normal;
|
||||
float dist;
|
||||
|
||||
if ( AAS_FindBestAreaSplitPlane( tmpnode->tmparea, normal, &dist ) ) {
|
||||
qprintf( "\r%6d", ++numgravitationalsubdivisions );
|
||||
//
|
||||
planenum = FindFloatPlane( normal, dist );
|
||||
//split the area
|
||||
AAS_SplitArea( tmpnode->tmparea, planenum, &frontarea, &backarea );
|
||||
//
|
||||
tmpnode->tmparea = NULL;
|
||||
tmpnode->planenum = FindFloatPlane( normal, dist );
|
||||
//
|
||||
tmpnode1 = AAS_AllocTmpNode();
|
||||
tmpnode1->planenum = 0;
|
||||
tmpnode1->tmparea = frontarea;
|
||||
//
|
||||
tmpnode2 = AAS_AllocTmpNode();
|
||||
tmpnode2->planenum = 0;
|
||||
tmpnode2->tmparea = backarea;
|
||||
//subdivide the areas created by splitting recursively
|
||||
tmpnode->children[0] = AAS_SubdivideArea_r( tmpnode1 );
|
||||
tmpnode->children[1] = AAS_SubdivideArea_r( tmpnode2 );
|
||||
} //end if
|
||||
return tmpnode;
|
||||
} //end of the function AAS_SubdivideArea_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_GravitationalSubdivision_r( tmp_node_t *tmpnode ) {
|
||||
//if this is a solid leaf
|
||||
if ( !tmpnode ) {
|
||||
return NULL;
|
||||
}
|
||||
//negative so it's an area
|
||||
if ( tmpnode->tmparea ) {
|
||||
return AAS_SubdivideArea_r( tmpnode );
|
||||
}
|
||||
//do the children recursively
|
||||
tmpnode->children[0] = AAS_GravitationalSubdivision_r( tmpnode->children[0] );
|
||||
tmpnode->children[1] = AAS_GravitationalSubdivision_r( tmpnode->children[1] );
|
||||
return tmpnode;
|
||||
} //end of the function AAS_GravitationalSubdivision_r
|
||||
//===========================================================================
|
||||
// NOTE: merge faces and melt edges first
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_GravitationalSubdivision( void ) {
|
||||
Log_Write( "AAS_GravitationalSubdivision\r\n" );
|
||||
numgravitationalsubdivisions = 0;
|
||||
qprintf( "%6i gravitational subdivisions", numgravitationalsubdivisions );
|
||||
//start with the head node
|
||||
AAS_GravitationalSubdivision_r( tmpaasworld.nodes );
|
||||
qprintf( "\n" );
|
||||
Log_Write( "%6i gravitational subdivisions\r\n", numgravitationalsubdivisions );
|
||||
} //end of the function AAS_GravitationalSubdivision
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_RefreshLadderSubdividedTree_r( tmp_node_t *tmpnode, tmp_area_t *tmparea,
|
||||
tmp_node_t *tmpnode1, tmp_node_t *tmpnode2, int planenum ) {
|
||||
//if this is a solid leaf
|
||||
if ( !tmpnode ) {
|
||||
return NULL;
|
||||
}
|
||||
//negative so it's an area
|
||||
if ( tmpnode->tmparea ) {
|
||||
if ( tmpnode->tmparea == tmparea ) {
|
||||
tmpnode->tmparea = NULL;
|
||||
tmpnode->planenum = planenum;
|
||||
tmpnode->children[0] = tmpnode1;
|
||||
tmpnode->children[1] = tmpnode2;
|
||||
} //end if
|
||||
return tmpnode;
|
||||
} //end if
|
||||
//do the children recursively
|
||||
tmpnode->children[0] = AAS_RefreshLadderSubdividedTree_r( tmpnode->children[0],
|
||||
tmparea, tmpnode1, tmpnode2, planenum );
|
||||
tmpnode->children[1] = AAS_RefreshLadderSubdividedTree_r( tmpnode->children[1],
|
||||
tmparea, tmpnode1, tmpnode2, planenum );
|
||||
return tmpnode;
|
||||
} //end of the function AAS_RefreshLadderSubdividedTree_r
|
||||
//===========================================================================
|
||||
// find an area with ladder faces and ground faces that are not connected
|
||||
// split the area with a horizontal plane at the lowest vertex of all
|
||||
// ladder faces in the area
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_LadderSubdivideArea_r( tmp_node_t *tmpnode ) {
|
||||
int side1, i, planenum;
|
||||
int foundladderface, foundgroundface;
|
||||
float dist;
|
||||
tmp_area_t *tmparea, *frontarea, *backarea;
|
||||
tmp_face_t *face1;
|
||||
tmp_node_t *tmpnode1, *tmpnode2;
|
||||
vec3_t lowestpoint, normal = {0, 0, 1};
|
||||
plane_t *plane;
|
||||
winding_t *w;
|
||||
|
||||
tmparea = tmpnode->tmparea;
|
||||
//skip areas with a liquid
|
||||
if ( tmparea->contents & ( AREACONTENTS_WATER
|
||||
| AREACONTENTS_LAVA
|
||||
| AREACONTENTS_SLIME ) ) {
|
||||
return tmpnode;
|
||||
}
|
||||
//must be possible to stand in the area
|
||||
if ( !( tmparea->presencetype & PRESENCE_NORMAL ) ) {
|
||||
return tmpnode;
|
||||
}
|
||||
//
|
||||
foundladderface = false;
|
||||
foundgroundface = false;
|
||||
lowestpoint[2] = 99999;
|
||||
//
|
||||
for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
|
||||
{
|
||||
//side of the face the area is on
|
||||
side1 = face1->frontarea != tmparea;
|
||||
//if the face is a ladder face
|
||||
if ( face1->faceflags & FACE_LADDER ) {
|
||||
plane = &mapplanes[face1->planenum];
|
||||
//the ladder face plane should be pretty much vertical
|
||||
if ( DotProduct( plane->normal, normal ) > -0.1 ) {
|
||||
foundladderface = true;
|
||||
//find lowest point
|
||||
for ( i = 0; i < face1->winding->numpoints; i++ )
|
||||
{
|
||||
if ( face1->winding->p[i][2] < lowestpoint[2] ) {
|
||||
VectorCopy( face1->winding->p[i], lowestpoint );
|
||||
} //end if
|
||||
} //end for
|
||||
} //end if
|
||||
} //end if
|
||||
else if ( face1->faceflags & FACE_GROUND ) {
|
||||
foundgroundface = true;
|
||||
} //end else if
|
||||
} //end for
|
||||
//
|
||||
if ( ( !foundladderface ) || ( !foundgroundface ) ) {
|
||||
return tmpnode;
|
||||
}
|
||||
//
|
||||
for ( face1 = tmparea->tmpfaces; face1; face1 = face1->next[side1] )
|
||||
{
|
||||
//side of the face the area is on
|
||||
side1 = face1->frontarea != tmparea;
|
||||
//if the face isn't a ground face
|
||||
if ( !( face1->faceflags & FACE_GROUND ) ) {
|
||||
continue;
|
||||
}
|
||||
//the ground plane
|
||||
plane = &mapplanes[face1->planenum];
|
||||
//get the difference between the ground plane and the lowest point
|
||||
dist = DotProduct( plane->normal, lowestpoint ) - plane->dist;
|
||||
//if the lowest point is very near one of the ground planes
|
||||
if ( dist > -1 && dist < 1 ) {
|
||||
return tmpnode;
|
||||
} //end if
|
||||
} //end for
|
||||
//
|
||||
dist = DotProduct( normal, lowestpoint );
|
||||
planenum = FindFloatPlane( normal, dist );
|
||||
//
|
||||
w = AAS_SplitWinding( tmparea, planenum );
|
||||
if ( !w ) {
|
||||
return tmpnode;
|
||||
}
|
||||
FreeWinding( w );
|
||||
//split the area with a horizontal plane through the lowest point
|
||||
qprintf( "\r%6d", ++numladdersubdivisions );
|
||||
//
|
||||
AAS_SplitArea( tmparea, planenum, &frontarea, &backarea );
|
||||
//
|
||||
tmpnode->tmparea = NULL;
|
||||
tmpnode->planenum = planenum;
|
||||
//
|
||||
tmpnode1 = AAS_AllocTmpNode();
|
||||
tmpnode1->planenum = 0;
|
||||
tmpnode1->tmparea = frontarea;
|
||||
//
|
||||
tmpnode2 = AAS_AllocTmpNode();
|
||||
tmpnode2->planenum = 0;
|
||||
tmpnode2->tmparea = backarea;
|
||||
//subdivide the areas created by splitting recursively
|
||||
tmpnode->children[0] = AAS_LadderSubdivideArea_r( tmpnode1 );
|
||||
tmpnode->children[1] = AAS_LadderSubdivideArea_r( tmpnode2 );
|
||||
//refresh the tree
|
||||
AAS_RefreshLadderSubdividedTree_r( tmpaasworld.nodes, tmparea, tmpnode1, tmpnode2, planenum );
|
||||
//
|
||||
return tmpnode;
|
||||
} //end of the function AAS_LadderSubdivideArea_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_LadderSubdivision_r( tmp_node_t *tmpnode ) {
|
||||
//if this is a solid leaf
|
||||
if ( !tmpnode ) {
|
||||
return 0;
|
||||
}
|
||||
//negative so it's an area
|
||||
if ( tmpnode->tmparea ) {
|
||||
return AAS_LadderSubdivideArea_r( tmpnode );
|
||||
}
|
||||
//do the children recursively
|
||||
tmpnode->children[0] = AAS_LadderSubdivision_r( tmpnode->children[0] );
|
||||
tmpnode->children[1] = AAS_LadderSubdivision_r( tmpnode->children[1] );
|
||||
return tmpnode;
|
||||
} //end of the function AAS_LadderSubdivision_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_LadderSubdivision( void ) {
|
||||
Log_Write( "AAS_LadderSubdivision\r\n" );
|
||||
numladdersubdivisions = 0;
|
||||
qprintf( "%6i ladder subdivisions", numladdersubdivisions );
|
||||
//start with the head node
|
||||
AAS_LadderSubdivision_r( tmpaasworld.nodes );
|
||||
//
|
||||
qprintf( "\n" );
|
||||
Log_Write( "%6i ladder subdivisions\r\n", numladdersubdivisions );
|
||||
} //end of the function AAS_LadderSubdivision
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_gsubdiv.h
|
||||
// Function: Gravitational subdivision
|
||||
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
|
||||
// Last update: 1997-12-04
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
//works with the global tmpaasworld
|
||||
void AAS_GravitationalSubdivision( void );
|
||||
void AAS_LadderSubdivision( void );
|
|
@ -0,0 +1,840 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_map.c
|
||||
// Function:
|
||||
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
|
||||
// Last update: 1997-12-03
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
#include "qbsp.h"
|
||||
#include "l_mem.h"
|
||||
#include "../botlib/aasfile.h" //aas_bbox_t
|
||||
#include "aas_store.h" //AAS_MAX_BBOXES
|
||||
#include "aas_cfg.h"
|
||||
#include "../game/surfaceflags.h"
|
||||
|
||||
#define SPAWNFLAG_NOT_EASY 0x00000100
|
||||
#define SPAWNFLAG_NOT_MEDIUM 0x00000200
|
||||
#define SPAWNFLAG_NOT_HARD 0x00000400
|
||||
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
|
||||
#define SPAWNFLAG_NOT_COOP 0x00001000
|
||||
|
||||
#define STATE_TOP 0
|
||||
#define STATE_BOTTOM 1
|
||||
#define STATE_UP 2
|
||||
#define STATE_DOWN 3
|
||||
|
||||
#define DOOR_START_OPEN 1
|
||||
#define DOOR_REVERSE 2
|
||||
#define DOOR_CRUSHER 4
|
||||
#define DOOR_NOMONSTER 8
|
||||
#define DOOR_TOGGLE 32
|
||||
#define DOOR_X_AXIS 64
|
||||
#define DOOR_Y_AXIS 128
|
||||
|
||||
#define BBOX_NORMAL_EPSILON 0.00001
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
vec_t BoxOriginDistanceFromPlane( vec3_t normal, vec3_t mins, vec3_t maxs, int side ) {
|
||||
vec3_t v1, v2;
|
||||
int i;
|
||||
|
||||
if ( side ) {
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
if ( normal[i] > BBOX_NORMAL_EPSILON ) {
|
||||
v1[i] = maxs[i];
|
||||
} else if ( normal[i] < -BBOX_NORMAL_EPSILON ) {
|
||||
v1[i] = mins[i];
|
||||
} else { v1[i] = 0;}
|
||||
} //end for
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
if ( normal[i] > BBOX_NORMAL_EPSILON ) {
|
||||
v1[i] = mins[i];
|
||||
} else if ( normal[i] < -BBOX_NORMAL_EPSILON ) {
|
||||
v1[i] = maxs[i];
|
||||
} else { v1[i] = 0;}
|
||||
} //end for
|
||||
} //end else
|
||||
VectorCopy( normal, v2 );
|
||||
VectorInverse( v2 );
|
||||
return DotProduct( v1, v2 );
|
||||
} //end of the function BoxOriginDistanceFromPlane
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
vec_t CapsuleOriginDistanceFromPlane( vec3_t normal, vec3_t mins, vec3_t maxs ) {
|
||||
float offset_up, offset_down, width, radius;
|
||||
|
||||
width = maxs[0] - mins[0];
|
||||
// if the box is less high then it is wide
|
||||
if ( maxs[2] - mins[2] < width ) {
|
||||
width = maxs[2] - mins[2];
|
||||
}
|
||||
radius = width * 0.5;
|
||||
// offset to upper and lower sphere
|
||||
offset_up = maxs[2] - radius;
|
||||
offset_down = -mins[2] - radius;
|
||||
|
||||
// if normal points upward
|
||||
if ( normal[2] > 0 ) {
|
||||
// touches lower sphere first
|
||||
return normal[2] * offset_down + radius;
|
||||
} else {
|
||||
// touched upper sphere first
|
||||
return -normal[2] * offset_up + radius;
|
||||
}
|
||||
}
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_ExpandMapBrush( mapbrush_t *brush, vec3_t mins, vec3_t maxs ) {
|
||||
int sn;
|
||||
float dist;
|
||||
side_t *s;
|
||||
plane_t *plane;
|
||||
|
||||
for ( sn = 0; sn < brush->numsides; sn++ )
|
||||
{
|
||||
s = brush->original_sides + sn;
|
||||
plane = &mapplanes[s->planenum];
|
||||
dist = plane->dist;
|
||||
if ( capsule_collision ) {
|
||||
dist += CapsuleOriginDistanceFromPlane( plane->normal, mins, maxs );
|
||||
} else {
|
||||
dist += BoxOriginDistanceFromPlane( plane->normal, mins, maxs, 0 );
|
||||
}
|
||||
s->planenum = FindFloatPlane( plane->normal, dist );
|
||||
//the side isn't a bevel after expanding
|
||||
s->flags &= ~SFL_BEVEL;
|
||||
//don't skip the surface
|
||||
s->surf &= ~SURF_SKIP;
|
||||
//make sure the texinfo is not TEXINFO_NODE
|
||||
//when player clip contents brushes are read from the bsp tree
|
||||
//they have the texinfo field set to TEXINFO_NODE
|
||||
//s->texinfo = 0;
|
||||
} //end for
|
||||
} //end of the function AAS_ExpandMapBrush
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_SetTexinfo( mapbrush_t *brush ) {
|
||||
int n;
|
||||
side_t *side;
|
||||
|
||||
if ( brush->contents & ( CONTENTS_LADDER
|
||||
| CONTENTS_AREAPORTAL
|
||||
| CONTENTS_CLUSTERPORTAL
|
||||
| CONTENTS_TELEPORTER
|
||||
| CONTENTS_JUMPPAD
|
||||
| CONTENTS_DONOTENTER
|
||||
| CONTENTS_DONOTENTER_LARGE
|
||||
| CONTENTS_WATER
|
||||
| CONTENTS_LAVA
|
||||
| CONTENTS_SLIME
|
||||
| CONTENTS_WINDOW
|
||||
| CONTENTS_PLAYERCLIP ) ) {
|
||||
//we just set texinfo to 0 because these brush sides MUST be used as
|
||||
//bsp splitters textured or not textured
|
||||
for ( n = 0; n < brush->numsides; n++ )
|
||||
{
|
||||
side = brush->original_sides + n;
|
||||
//side->flags |= SFL_TEXTURED|SFL_VISIBLE;
|
||||
side->texinfo = 0;
|
||||
} //end for
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
//only use brush sides as splitters if they are textured
|
||||
//texinfo of non-textured sides will be set to TEXINFO_NODE
|
||||
for ( n = 0; n < brush->numsides; n++ )
|
||||
{
|
||||
side = brush->original_sides + n;
|
||||
//don't use side as splitter (set texinfo to TEXINFO_NODE) if not textured
|
||||
if ( side->flags & ( SFL_TEXTURED | SFL_BEVEL ) ) {
|
||||
side->texinfo = 0;
|
||||
} else { side->texinfo = TEXINFO_NODE;}
|
||||
} //end for
|
||||
} //end else
|
||||
} //end of the function AAS_SetTexinfo
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void FreeBrushWindings( mapbrush_t *brush ) {
|
||||
int n;
|
||||
side_t *side;
|
||||
//
|
||||
for ( n = 0; n < brush->numsides; n++ )
|
||||
{
|
||||
side = brush->original_sides + n;
|
||||
//
|
||||
if ( side->winding ) {
|
||||
FreeWinding( side->winding );
|
||||
}
|
||||
} //end for
|
||||
} //end of the function FreeBrushWindings
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_AddMapBrushSide( mapbrush_t *brush, int planenum ) {
|
||||
side_t *side;
|
||||
//
|
||||
if ( nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES ) {
|
||||
Error( "MAX_MAPFILE_BRUSHSIDES" );
|
||||
}
|
||||
//
|
||||
side = brush->original_sides + brush->numsides;
|
||||
side->original = NULL;
|
||||
side->winding = NULL;
|
||||
side->contents = brush->contents;
|
||||
side->flags &= ~( SFL_BEVEL | SFL_VISIBLE );
|
||||
side->surf = 0;
|
||||
side->planenum = planenum;
|
||||
side->texinfo = 0;
|
||||
//
|
||||
nummapbrushsides++;
|
||||
brush->numsides++;
|
||||
} //end of the function AAS_AddMapBrushSide
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_FixMapBrush( mapbrush_t *brush ) {
|
||||
int i, j, planenum;
|
||||
float dist;
|
||||
winding_t *w;
|
||||
plane_t *plane, *plane1, *plane2;
|
||||
side_t *side;
|
||||
vec3_t normal;
|
||||
|
||||
//calculate the brush bounds
|
||||
ClearBounds( brush->mins, brush->maxs );
|
||||
for ( i = 0; i < brush->numsides; i++ )
|
||||
{
|
||||
plane = &mapplanes[brush->original_sides[i].planenum];
|
||||
w = BaseWindingForPlane( plane->normal, plane->dist );
|
||||
for ( j = 0; j < brush->numsides && w; j++ )
|
||||
{
|
||||
if ( i == j ) {
|
||||
continue;
|
||||
}
|
||||
//there are no brush bevels marked but who cares :)
|
||||
if ( brush->original_sides[j].flags & SFL_BEVEL ) {
|
||||
continue;
|
||||
}
|
||||
plane = &mapplanes[brush->original_sides[j].planenum ^ 1];
|
||||
ChopWindingInPlace( &w, plane->normal, plane->dist, 0 ); //CLIP_EPSILON);
|
||||
} //end for
|
||||
|
||||
side = &brush->original_sides[i];
|
||||
side->winding = w;
|
||||
if ( w ) {
|
||||
for ( j = 0; j < w->numpoints; j++ )
|
||||
{
|
||||
AddPointToBounds( w->p[j], brush->mins, brush->maxs );
|
||||
} //end for
|
||||
} //end if
|
||||
} //end for
|
||||
//
|
||||
for ( i = 0; i < brush->numsides; i++ )
|
||||
{
|
||||
for ( j = 0; j < brush->numsides; j++ )
|
||||
{
|
||||
if ( i == j ) {
|
||||
continue;
|
||||
}
|
||||
plane1 = &mapplanes[brush->original_sides[i].planenum];
|
||||
plane2 = &mapplanes[brush->original_sides[j].planenum];
|
||||
if ( WindingsNonConvex( brush->original_sides[i].winding,
|
||||
brush->original_sides[j].winding,
|
||||
plane1->normal, plane2->normal,
|
||||
plane1->dist, plane2->dist ) ) {
|
||||
Log_Print( "non convex brush" );
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
|
||||
//NOW close the fucking brush!!
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
if ( brush->mins[i] < -MAX_MAP_BOUNDS ) {
|
||||
VectorClear( normal );
|
||||
normal[i] = -1;
|
||||
dist = MAX_MAP_BOUNDS - 10;
|
||||
planenum = FindFloatPlane( normal, dist );
|
||||
//
|
||||
Log_Print( "mins out of range: added extra brush side\n" );
|
||||
AAS_AddMapBrushSide( brush, planenum );
|
||||
} //end if
|
||||
if ( brush->maxs[i] > MAX_MAP_BOUNDS ) {
|
||||
VectorClear( normal );
|
||||
normal[i] = 1;
|
||||
dist = MAX_MAP_BOUNDS - 10;
|
||||
planenum = FindFloatPlane( normal, dist );
|
||||
//
|
||||
Log_Print( "maxs out of range: added extra brush side\n" );
|
||||
AAS_AddMapBrushSide( brush, planenum );
|
||||
} //end if
|
||||
if ( brush->mins[i] > MAX_MAP_BOUNDS || brush->maxs[i] < -MAX_MAP_BOUNDS ) {
|
||||
Log_Print( "entity %i, brush %i: no visible sides on brush\n", brush->entitynum, brush->brushnum );
|
||||
} //end if
|
||||
} //end for
|
||||
//free all the windings
|
||||
FreeBrushWindings( brush );
|
||||
} //end of the function AAS_FixMapBrush
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
qboolean AAS_MakeBrushWindings( mapbrush_t *ob ) {
|
||||
int i, j;
|
||||
winding_t *w;
|
||||
side_t *side;
|
||||
plane_t *plane, *plane1, *plane2;
|
||||
|
||||
ClearBounds( ob->mins, ob->maxs );
|
||||
|
||||
for ( i = 0; i < ob->numsides; i++ )
|
||||
{
|
||||
plane = &mapplanes[ob->original_sides[i].planenum];
|
||||
w = BaseWindingForPlane( plane->normal, plane->dist );
|
||||
for ( j = 0; j < ob->numsides && w; j++ )
|
||||
{
|
||||
if ( i == j ) {
|
||||
continue;
|
||||
}
|
||||
if ( ob->original_sides[j].flags & SFL_BEVEL ) {
|
||||
continue;
|
||||
}
|
||||
plane = &mapplanes[ob->original_sides[j].planenum ^ 1];
|
||||
ChopWindingInPlace( &w, plane->normal, plane->dist, 0 ); //CLIP_EPSILON);
|
||||
}
|
||||
|
||||
side = &ob->original_sides[i];
|
||||
side->winding = w;
|
||||
if ( w ) {
|
||||
side->flags |= SFL_VISIBLE;
|
||||
for ( j = 0; j < w->numpoints; j++ )
|
||||
AddPointToBounds( w->p[j], ob->mins, ob->maxs );
|
||||
}
|
||||
}
|
||||
//check if the brush is convex
|
||||
for ( i = 0; i < ob->numsides; i++ )
|
||||
{
|
||||
for ( j = 0; j < ob->numsides; j++ )
|
||||
{
|
||||
if ( i == j ) {
|
||||
continue;
|
||||
}
|
||||
plane1 = &mapplanes[ob->original_sides[i].planenum];
|
||||
plane2 = &mapplanes[ob->original_sides[j].planenum];
|
||||
if ( WindingsNonConvex( ob->original_sides[i].winding,
|
||||
ob->original_sides[j].winding,
|
||||
plane1->normal, plane2->normal,
|
||||
plane1->dist, plane2->dist ) ) {
|
||||
Log_Print( "non convex brush" );
|
||||
} //end if
|
||||
} //end for
|
||||
} //end for
|
||||
//check for out of bound brushes
|
||||
for ( i = 0; i < 3; i++ )
|
||||
{
|
||||
//IDBUG: all the indexes into the mins and maxs were zero (not using i)
|
||||
if ( ob->mins[i] < -MAX_MAP_BOUNDS || ob->maxs[i] > MAX_MAP_BOUNDS ) {
|
||||
Log_Print( "entity %i, brush %i: bounds out of range\n", ob->entitynum, ob->brushnum );
|
||||
Log_Print( "ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, ob->mins[i], i, ob->maxs[i] );
|
||||
ob->numsides = 0; //remove the brush
|
||||
break;
|
||||
} //end if
|
||||
if ( ob->mins[i] > MAX_MAP_BOUNDS || ob->maxs[i] < -MAX_MAP_BOUNDS ) {
|
||||
Log_Print( "entity %i, brush %i: no visible sides on brush\n", ob->entitynum, ob->brushnum );
|
||||
Log_Print( "ob->mins[%d] = %f, ob->maxs[%d] = %f\n", i, ob->mins[i], i, ob->maxs[i] );
|
||||
ob->numsides = 0; //remove the brush
|
||||
break;
|
||||
} //end if
|
||||
} //end for
|
||||
return true;
|
||||
} //end of the function AAS_MakeBrushWindings
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
mapbrush_t *AAS_CopyMapBrush( mapbrush_t *brush, entity_t *mapent ) {
|
||||
int n;
|
||||
mapbrush_t *newbrush;
|
||||
side_t *side, *newside;
|
||||
|
||||
if ( nummapbrushes >= MAX_MAPFILE_BRUSHES ) {
|
||||
Error( "MAX_MAPFILE_BRUSHES" );
|
||||
}
|
||||
|
||||
newbrush = &mapbrushes[nummapbrushes];
|
||||
newbrush->original_sides = &brushsides[nummapbrushsides];
|
||||
newbrush->entitynum = brush->entitynum;
|
||||
newbrush->brushnum = nummapbrushes - mapent->firstbrush;
|
||||
newbrush->numsides = brush->numsides;
|
||||
newbrush->contents = brush->contents;
|
||||
|
||||
//copy the sides
|
||||
for ( n = 0; n < brush->numsides; n++ )
|
||||
{
|
||||
if ( nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES ) {
|
||||
Error( "MAX_MAPFILE_BRUSHSIDES" );
|
||||
}
|
||||
side = brush->original_sides + n;
|
||||
|
||||
newside = newbrush->original_sides + n;
|
||||
newside->original = NULL;
|
||||
newside->winding = NULL;
|
||||
newside->contents = side->contents;
|
||||
newside->flags = side->flags;
|
||||
newside->surf = side->surf;
|
||||
newside->planenum = side->planenum;
|
||||
newside->texinfo = side->texinfo;
|
||||
nummapbrushsides++;
|
||||
} //end for
|
||||
//
|
||||
nummapbrushes++;
|
||||
mapent->numbrushes++;
|
||||
return newbrush;
|
||||
} //end of the function AAS_CopyMapBrush
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_AlwaysTriggered( char *targetname ) {
|
||||
int i;
|
||||
|
||||
if ( !strlen( targetname ) ) {
|
||||
return false;
|
||||
}
|
||||
//
|
||||
for ( i = 0; i < num_entities; i++ )
|
||||
{
|
||||
//if the entity will activate the given targetname
|
||||
if ( !strcmp( targetname, ValueForKey( &entities[i], "target" ) ) ) {
|
||||
//if this activator is present in deathmatch
|
||||
if ( !( atoi( ValueForKey( &entities[i], "spawnflags" ) ) & SPAWNFLAG_NOT_DEATHMATCH ) ) {
|
||||
//if it is a trigger_always entity
|
||||
if ( !strcmp( "trigger_always", ValueForKey( &entities[i], "classname" ) ) ) {
|
||||
return true;
|
||||
} //end if
|
||||
//check for possible trigger_always entities activating this entity
|
||||
if ( AAS_AlwaysTriggered( ValueForKey( &entities[i], "targetname" ) ) ) {
|
||||
return true;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
return false;
|
||||
} //end of the function AAS_AlwaysTriggered
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_ValidEntity( entity_t *mapent ) {
|
||||
int i;
|
||||
char target[1024];
|
||||
|
||||
//all world brushes are used for AAS
|
||||
if ( mapent == &entities[0] ) {
|
||||
return true;
|
||||
} //end if
|
||||
//some of the func_wall brushes are also used for AAS
|
||||
else if ( !strcmp( "func_wall", ValueForKey( mapent, "classname" ) ) ) {
|
||||
//Log_Print("found func_wall entity %d\n", mapent - entities);
|
||||
//if the func wall is used in deathmatch
|
||||
//if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
|
||||
{
|
||||
//Log_Print("func_wall USED in deathmatch mode %d\n", atoi(ValueForKey(mapent, "spawnflags")));
|
||||
return true;
|
||||
} //end if
|
||||
} //end else if
|
||||
else if ( !strcmp( "func_door_rotating", ValueForKey( mapent, "classname" ) ) ||
|
||||
!strcmp( "func_door", ValueForKey( mapent, "classname" ) ) ||
|
||||
!strcmp( "func_invisible_user", ValueForKey( mapent, "classname" ) ) ) {
|
||||
//if the func_door_rotating is present in deathmatch
|
||||
//if (!(atoi(ValueForKey(mapent, "spawnflags")) & SPAWNFLAG_NOT_DEATHMATCH))
|
||||
{
|
||||
//if the func_door_rotating is always activated in deathmatch
|
||||
if ( AAS_AlwaysTriggered( ValueForKey( mapent, "targetname" ) ) ) {
|
||||
//Log_Print("found func_door_rotating in deathmatch\ntargetname %s\n", ValueForKey(mapent, "targetname"));
|
||||
return true;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end else if
|
||||
else if ( !strcmp( "trigger_hurt", ValueForKey( mapent, "classname" ) ) ) {
|
||||
// RF, spawnflag & 1 is for delayed spawn, so ignore it
|
||||
if ( atoi( ValueForKey( mapent, "spawnflags" ) ) & 1 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
//"dmg" is the damage, for instance: "dmg" "666"
|
||||
return true;
|
||||
} //end else if
|
||||
else if ( !strcmp( "trigger_push", ValueForKey( mapent, "classname" ) ) ) {
|
||||
return true;
|
||||
} //end else if
|
||||
else if ( !strcmp( "trigger_multiple", ValueForKey( mapent, "classname" ) ) ) {
|
||||
//find out if the trigger_multiple is pointing to a target_teleporter
|
||||
strcpy( target, ValueForKey( mapent, "target" ) );
|
||||
for ( i = 0; i < num_entities; i++ )
|
||||
{
|
||||
//if the entity will activate the given targetname
|
||||
if ( !strcmp( target, ValueForKey( &entities[i], "targetname" ) ) ) {
|
||||
if ( !strcmp( "target_teleporter", ValueForKey( &entities[i], "classname" ) ) ) {
|
||||
return true;
|
||||
} //end if
|
||||
} //end if
|
||||
} //end for
|
||||
} //end else if
|
||||
else if ( !strcmp( "trigger_teleport", ValueForKey( mapent, "classname" ) ) ) {
|
||||
return true;
|
||||
} //end else if
|
||||
else if ( !strcmp( "func_tramcar", ValueForKey( mapent, "classname" ) ) ) {
|
||||
return true;
|
||||
} //end else if
|
||||
else if ( !strcmp( "func_invisible_user", ValueForKey( mapent, "classname" ) ) ) {
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
else if (!strcmp("func_static", ValueForKey(mapent, "classname")))
|
||||
{
|
||||
//FIXME: easy/medium/hard/deathmatch specific?
|
||||
return true;
|
||||
} //end else if
|
||||
*/
|
||||
return false;
|
||||
} //end of the function AAS_ValidEntity
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
int AAS_TransformPlane( int planenum, vec3_t origin, vec3_t angles ) {
|
||||
float newdist, matrix[3][3];
|
||||
vec3_t normal;
|
||||
|
||||
//rotate the node plane
|
||||
VectorCopy( mapplanes[planenum].normal, normal );
|
||||
CreateRotationMatrix( angles, matrix );
|
||||
RotatePoint( normal, matrix );
|
||||
newdist = mapplanes[planenum].dist + DotProduct( normal, origin );
|
||||
return FindFloatPlane( normal, newdist );
|
||||
} //end of the function AAS_TransformPlane
|
||||
//===========================================================================
|
||||
// this function sets the func_rotating_door in it's final position
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PositionFuncRotatingBrush( entity_t *mapent, mapbrush_t *brush ) {
|
||||
int spawnflags, i;
|
||||
float distance;
|
||||
vec3_t movedir, angles, pos1, pos2;
|
||||
side_t *s;
|
||||
|
||||
spawnflags = FloatForKey( mapent, "spawnflags" );
|
||||
VectorClear( movedir );
|
||||
if ( spawnflags & DOOR_X_AXIS ) {
|
||||
movedir[2] = 1.0; //roll
|
||||
} else if ( spawnflags & DOOR_Y_AXIS ) {
|
||||
movedir[0] = 1.0; //pitch
|
||||
} else { // Z_AXIS
|
||||
movedir[1] = 1.0; //yaw
|
||||
|
||||
}
|
||||
// check for reverse rotation
|
||||
if ( spawnflags & DOOR_REVERSE ) {
|
||||
VectorInverse( movedir );
|
||||
}
|
||||
|
||||
distance = FloatForKey( mapent, "distance" );
|
||||
if ( !distance ) {
|
||||
distance = 90;
|
||||
}
|
||||
|
||||
GetVectorForKey( mapent, "angles", angles );
|
||||
VectorCopy( angles, pos1 );
|
||||
VectorMA( angles, -distance, movedir, pos2 );
|
||||
// if it starts open, switch the positions
|
||||
if ( spawnflags & DOOR_START_OPEN ) {
|
||||
VectorCopy( pos2, angles );
|
||||
VectorCopy( pos1, pos2 );
|
||||
VectorCopy( angles, pos1 );
|
||||
VectorInverse( movedir );
|
||||
} //end if
|
||||
//
|
||||
for ( i = 0; i < brush->numsides; i++ )
|
||||
{
|
||||
s = &brush->original_sides[i];
|
||||
s->planenum = AAS_TransformPlane( s->planenum, mapent->origin, pos2 );
|
||||
} //end for
|
||||
//
|
||||
FreeBrushWindings( brush );
|
||||
AAS_MakeBrushWindings( brush );
|
||||
AddBrushBevels( brush );
|
||||
FreeBrushWindings( brush );
|
||||
} //end of the function AAS_PositionFuncRotatingBrush
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PositionBrush( entity_t *mapent, mapbrush_t *brush ) {
|
||||
side_t *s;
|
||||
float newdist;
|
||||
int i;
|
||||
char *model;
|
||||
|
||||
if ( !strcmp( ValueForKey( mapent, "classname" ), "func_door_rotating" ) ) {
|
||||
AAS_PositionFuncRotatingBrush( mapent, brush );
|
||||
} //end if
|
||||
else
|
||||
{
|
||||
if ( mapent->origin[0] || mapent->origin[1] || mapent->origin[2] ) {
|
||||
for ( i = 0; i < brush->numsides; i++ )
|
||||
{
|
||||
s = &brush->original_sides[i];
|
||||
newdist = mapplanes[s->planenum].dist +
|
||||
DotProduct( mapplanes[s->planenum].normal, mapent->origin );
|
||||
s->planenum = FindFloatPlane( mapplanes[s->planenum].normal, newdist );
|
||||
} //end for
|
||||
} //end if
|
||||
// RF, disabled for Wolf, we dont use trigger_hurt for lava
|
||||
//if it's a trigger hurt
|
||||
//if (!strcmp("trigger_hurt", ValueForKey(mapent, "classname")))
|
||||
//{
|
||||
// //set the lava contents
|
||||
// brush->contents |= CONTENTS_LAVA;
|
||||
// //Log_Print("found trigger_hurt brush\n");
|
||||
//} //end if
|
||||
//
|
||||
else if ( !strcmp( "trigger_push", ValueForKey( mapent, "classname" ) ) ) {
|
||||
//set the jumppad contents
|
||||
brush->contents = CONTENTS_JUMPPAD;
|
||||
//Log_Print("found trigger_push brush\n");
|
||||
} //end if
|
||||
//
|
||||
else if ( !strcmp( "trigger_multiple", ValueForKey( mapent, "classname" ) ) ) {
|
||||
//set teleporter contents
|
||||
brush->contents = CONTENTS_TELEPORTER;
|
||||
//Log_Print("found trigger_multiple teleporter brush\n");
|
||||
} //end if
|
||||
//
|
||||
else if ( !strcmp( "trigger_teleport", ValueForKey( mapent, "classname" ) ) ) {
|
||||
//set teleporter contents
|
||||
brush->contents = CONTENTS_TELEPORTER;
|
||||
//Log_Print("found trigger_teleport teleporter brush\n");
|
||||
} //end if
|
||||
else if ( !strcmp( "func_door", ValueForKey( mapent, "classname" ) ) ) {
|
||||
//set mover contents
|
||||
brush->contents = CONTENTS_MOVER;
|
||||
//get the model number
|
||||
model = ValueForKey( mapent, "model" );
|
||||
brush->modelnum = atoi( model + 1 );
|
||||
} //end if
|
||||
else if ( !strcmp( "func_invisible_user", ValueForKey( mapent, "classname" ) ) ) {
|
||||
//set mover contents
|
||||
brush->contents = CONTENTS_TRIGGER;
|
||||
} //end if
|
||||
|
||||
} //end else
|
||||
} //end of the function AAS_PositionBrush
|
||||
//===========================================================================
|
||||
// uses the global cfg_t cfg
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_CreateMapBrushes( mapbrush_t *brush, entity_t *mapent, int addbevels ) {
|
||||
int i;
|
||||
//side_t *s;
|
||||
mapbrush_t *bboxbrushes[16];
|
||||
|
||||
//if the brushes are not from an entity used for AAS
|
||||
if ( !AAS_ValidEntity( mapent ) ) {
|
||||
nummapbrushsides -= brush->numsides;
|
||||
brush->numsides = 0;
|
||||
return;
|
||||
} //end if
|
||||
//
|
||||
AAS_PositionBrush( mapent, brush );
|
||||
//from all normal solid brushes only the textured brush sides will
|
||||
//be used as bsp splitters, so set the right texinfo reference here
|
||||
AAS_SetTexinfo( brush );
|
||||
//remove contents detail flag, otherwise player clip contents won't be
|
||||
//bsped correctly for AAS!
|
||||
brush->contents &= ~CONTENTS_DETAIL;
|
||||
//if the brush has contents area portal it should be the only contents
|
||||
if ( brush->contents & ( CONTENTS_AREAPORTAL | CONTENTS_CLUSTERPORTAL ) ) {
|
||||
brush->contents = CONTENTS_CLUSTERPORTAL;
|
||||
brush->leafnum = -1;
|
||||
} //end if
|
||||
//window and playerclip are used for player clipping, make them solid
|
||||
if ( brush->contents & ( CONTENTS_WINDOW | CONTENTS_PLAYERCLIP ) ) {
|
||||
//
|
||||
brush->contents &= ~( CONTENTS_WINDOW | CONTENTS_PLAYERCLIP );
|
||||
brush->contents |= CONTENTS_SOLID;
|
||||
brush->leafnum = -1;
|
||||
} //end if
|
||||
//
|
||||
// Rafael TBD: no flag to support CONTENTS_BOTCLIP
|
||||
/*
|
||||
if (brush->contents & CONTENTS_BOTCLIP)
|
||||
{
|
||||
brush->contents = CONTENTS_SOLID;
|
||||
brush->leafnum = -1;
|
||||
} // end if
|
||||
*/
|
||||
//
|
||||
//Log_Write("brush %d contents = ", brush->brushnum);
|
||||
//PrintContents(brush->contents);
|
||||
//Log_Write("\r\n");
|
||||
//if not one of the following brushes then the brush is NOT used for AAS
|
||||
if ( !( brush->contents & ( CONTENTS_SOLID
|
||||
| CONTENTS_LADDER
|
||||
| CONTENTS_CLUSTERPORTAL
|
||||
| CONTENTS_DONOTENTER
|
||||
| CONTENTS_DONOTENTER_LARGE
|
||||
| CONTENTS_TELEPORTER
|
||||
| CONTENTS_JUMPPAD
|
||||
| CONTENTS_WATER
|
||||
| CONTENTS_LAVA
|
||||
| CONTENTS_SLIME
|
||||
| CONTENTS_MOVER
|
||||
) ) ) {
|
||||
nummapbrushsides -= brush->numsides;
|
||||
brush->numsides = 0;
|
||||
return;
|
||||
} //end if
|
||||
//fix the map brush
|
||||
//AAS_FixMapBrush(brush);
|
||||
//if brush bevels should be added (for real map brushes, not bsp map brushes)
|
||||
if ( addbevels ) {
|
||||
//NOTE: we first have to get the mins and maxs of the brush before
|
||||
// creating the brush bevels... the mins and maxs are used to
|
||||
// create them. so we call MakeBrushWindings to get the mins
|
||||
// and maxs and then after creating the bevels we free the
|
||||
// windings because they are created for all sides (including
|
||||
// bevels) a little later
|
||||
AAS_MakeBrushWindings( brush );
|
||||
AddBrushBevels( brush );
|
||||
FreeBrushWindings( brush );
|
||||
} //end if
|
||||
//NOTE: add the brush to the WORLD entity!!!
|
||||
mapent = &entities[0];
|
||||
//there's at least one new brush for now
|
||||
nummapbrushes++;
|
||||
mapent->numbrushes++;
|
||||
//liquid brushes are expanded for the maximum possible bounding box
|
||||
if ( brush->contents & ( CONTENTS_WATER
|
||||
| CONTENTS_LAVA
|
||||
| CONTENTS_SLIME
|
||||
| CONTENTS_TELEPORTER
|
||||
| CONTENTS_JUMPPAD
|
||||
| CONTENTS_DONOTENTER
|
||||
| CONTENTS_DONOTENTER_LARGE
|
||||
| CONTENTS_MOVER
|
||||
) ) {
|
||||
brush->expansionbbox = 0;
|
||||
//NOTE: the first bounding box is the max
|
||||
//FIXME: use max bounding box created from all bboxes
|
||||
AAS_ExpandMapBrush( brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs );
|
||||
AAS_MakeBrushWindings( brush );
|
||||
} //end if
|
||||
//area portal brushes are NOT expanded
|
||||
else if ( brush->contents & CONTENTS_CLUSTERPORTAL ) {
|
||||
brush->expansionbbox = 0;
|
||||
//NOTE: the first bounding box is the max
|
||||
//FIXME: use max bounding box created from all bboxes
|
||||
AAS_ExpandMapBrush( brush, cfg.bboxes[0].mins, cfg.bboxes[0].maxs );
|
||||
AAS_MakeBrushWindings( brush );
|
||||
} //end if
|
||||
//all solid brushes are expanded for all bounding boxes
|
||||
else if ( brush->contents & ( CONTENTS_SOLID
|
||||
| CONTENTS_LADDER
|
||||
) ) {
|
||||
//brush for the first bounding box
|
||||
bboxbrushes[0] = brush;
|
||||
//make a copy for the other bounding boxes
|
||||
for ( i = 1; i < cfg.numbboxes; i++ )
|
||||
{
|
||||
bboxbrushes[i] = AAS_CopyMapBrush( brush, mapent );
|
||||
} //end for
|
||||
//expand every brush for it's bounding box and create windings
|
||||
for ( i = 0; i < cfg.numbboxes; i++ )
|
||||
{
|
||||
AAS_ExpandMapBrush( bboxbrushes[i], cfg.bboxes[i].mins, cfg.bboxes[i].maxs );
|
||||
bboxbrushes[i]->expansionbbox = cfg.bboxes[i].presencetype;
|
||||
AAS_MakeBrushWindings( bboxbrushes[i] );
|
||||
} //end for
|
||||
} //end else
|
||||
} //end of the function AAS_CreateMapBrushes
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_map.h
|
||||
// Function:
|
||||
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
|
||||
// Last update: 1997-12-04
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
void AAS_CreateMapBrushes( mapbrush_t *brush, entity_t *mapent, int addbevels );
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_prunenodes.c
|
||||
// Function: Prune Nodes
|
||||
// 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"
|
||||
|
||||
int c_numprunes;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
tmp_node_t *AAS_PruneNodes_r( tmp_node_t *tmpnode ) {
|
||||
tmp_area_t *tmparea1, *tmparea2;
|
||||
|
||||
//if it is a solid leaf
|
||||
if ( !tmpnode ) {
|
||||
return NULL;
|
||||
}
|
||||
//
|
||||
if ( tmpnode->tmparea ) {
|
||||
return tmpnode;
|
||||
}
|
||||
//process the children first
|
||||
tmpnode->children[0] = AAS_PruneNodes_r( tmpnode->children[0] );
|
||||
tmpnode->children[1] = AAS_PruneNodes_r( tmpnode->children[1] );
|
||||
//if both children are areas
|
||||
if ( tmpnode->children[0] && tmpnode->children[1] &&
|
||||
tmpnode->children[0]->tmparea && tmpnode->children[1]->tmparea ) {
|
||||
tmparea1 = tmpnode->children[0]->tmparea;
|
||||
while ( tmparea1->mergedarea ) tmparea1 = tmparea1->mergedarea;
|
||||
|
||||
tmparea2 = tmpnode->children[1]->tmparea;
|
||||
while ( tmparea2->mergedarea ) tmparea2 = tmparea2->mergedarea;
|
||||
|
||||
if ( tmparea1 == tmparea2 ) {
|
||||
c_numprunes++;
|
||||
tmpnode->tmparea = tmparea1;
|
||||
tmpnode->planenum = 0;
|
||||
AAS_FreeTmpNode( tmpnode->children[0] );
|
||||
AAS_FreeTmpNode( tmpnode->children[1] );
|
||||
tmpnode->children[0] = NULL;
|
||||
tmpnode->children[1] = NULL;
|
||||
return tmpnode;
|
||||
} //end if
|
||||
} //end if
|
||||
//if both solid leafs
|
||||
if ( !tmpnode->children[0] && !tmpnode->children[1] ) {
|
||||
c_numprunes++;
|
||||
AAS_FreeTmpNode( tmpnode );
|
||||
return NULL;
|
||||
} //end if
|
||||
//
|
||||
return tmpnode;
|
||||
} //end of the function AAS_PruneNodes_r
|
||||
//===========================================================================
|
||||
//
|
||||
// Parameter: -
|
||||
// Returns: -
|
||||
// Changes Globals: -
|
||||
//===========================================================================
|
||||
void AAS_PruneNodes( void ) {
|
||||
Log_Write( "AAS_PruneNodes\r\n" );
|
||||
AAS_PruneNodes_r( tmpaasworld.nodes );
|
||||
Log_Print( "%6d nodes pruned\r\n", c_numprunes );
|
||||
} //end of the function AAS_PruneNodes
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_prunenodes.h
|
||||
// Function: Prune Nodes
|
||||
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
|
||||
// Last update: 1997-12-04
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
void AAS_PruneNodes( void );
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
===========================================================================
|
||||
|
||||
Return to Castle Wolfenstein single player GPL Source Code
|
||||
Copyright (C) 1999-2010 id Software LLC, a ZeniMax Media company.
|
||||
|
||||
This file is part of the Return to Castle Wolfenstein single player GPL Source Code (RTCW SP Source Code).
|
||||
|
||||
RTCW SP 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.
|
||||
|
||||
RTCW SP 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 RTCW SP Source Code. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
In addition, the RTCW SP 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 RTCW SP 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_store.h
|
||||
// Function:
|
||||
// Programmer: Mr Elusive (MrElusive@demigod.demon.nl)
|
||||
// Last update: 1997-12-04
|
||||
// Tab Size: 3
|
||||
//===========================================================================
|
||||
|
||||
#define AAS_MAX_BBOXES 5
|
||||
#define AAS_MAX_VERTEXES 512000
|
||||
#define AAS_MAX_PLANES 65536
|
||||
#define AAS_MAX_EDGES 512000
|
||||
#define AAS_MAX_EDGEINDEXSIZE 512000
|
||||
#define AAS_MAX_FACES 512000
|
||||
#define AAS_MAX_FACEINDEXSIZE 512000
|
||||
#define AAS_MAX_AREAS 65536
|
||||
#define AAS_MAX_AREASETTINGS 65536
|
||||
#define AAS_MAX_REACHABILITYSIZE 65536
|
||||
#define AAS_MAX_NODES 256000
|
||||
#define AAS_MAX_PORTALS 65536
|
||||
#define AAS_MAX_PORTALINDEXSIZE 65536
|
||||
#define AAS_MAX_CLUSTERS 65536
|
||||
|
||||
#define BSPCINCLUDE
|
||||
#include "../botlib/be_aas.h"
|
||||
#include "../botlib/be_aas_def.h"
|
||||
|
||||
/*
|
||||
typedef struct bspc_aas_s
|
||||
{
|
||||
int loaded;
|
||||
int initialized; //true when AAS has been initialized
|
||||
int savefile; //set true when file should be saved
|
||||
//bounding boxes
|
||||
int numbboxes;
|
||||
aas_bbox_t *bboxes;
|
||||
//vertexes
|
||||
int numvertexes;
|
||||
aas_vertex_t *vertexes;
|
||||
//planes
|
||||
int numplanes;
|
||||
aas_plane_t *planes;
|
||||
//edges
|
||||
int numedges;
|
||||
aas_edge_t *edges;
|
||||
//edge index
|
||||
int edgeindexsize;
|
||||
aas_edgeindex_t *edgeindex;
|
||||
//faces
|
||||
int numfaces;
|
||||
aas_face_t *faces;
|
||||
//face index
|
||||
int faceindexsize;
|
||||
aas_faceindex_t *faceindex;
|
||||
//convex areas
|
||||
int numareas;
|
||||
aas_area_t *areas;
|
||||
//convex area settings
|
||||
int numareasettings;
|
||||
aas_areasettings_t *areasettings;
|
||||
//reachablity list
|
||||
int reachabilitysize;
|
||||
aas_reachability_t *reachability;
|
||||
//nodes of the bsp tree
|
||||
int numnodes;
|
||||
aas_node_t *nodes;
|
||||
//cluster portals
|
||||
int numportals;
|
||||
aas_portal_t *portals;
|
||||
//cluster portal index
|
||||
int portalindexsize;
|
||||
aas_portalindex_t *portalindex;
|
||||
//clusters
|
||||
int numclusters;
|
||||
aas_cluster_t *clusters;
|
||||
//
|
||||
int numreachabilityareas;
|
||||
float reachabilitytime;
|
||||
} bspc_aas_t;
|
||||
|
||||
extern bspc_aas_t aasworld;
|
||||
//
|
||||
*/
|
||||
|
||||
// Ridah
|
||||
extern aas_t aasworlds[1];
|
||||
extern aas_t *aasworld;
|
||||
// done.
|
||||
|
||||
//stores the AAS file from the temporary AAS
|
||||
void AAS_StoreFile( char *filename );
|
||||
//returns a number of the given plane
|
||||
qboolean AAS_FindPlane( vec3_t normal, float dist, int *planenum );
|
||||
//allocates the maximum AAS memory for storage
|
||||
void AAS_AllocMaxAAS( void );
|
||||
//frees the maximum AAS memory for storage
|
||||
void AAS_FreeMaxAAS( void );
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue