From: maruhiro Date: Mon, 11 Feb 2013 11:47:51 +0000 (+0900) Subject: Nazghul-0.7.1 X-Git-Url: http://git.osdn.net/view?p=nazghul-jp%2Fnazghul-jp.git;a=commitdiff_plain;h=b7e0472e04898913774c2bd1e74589292933bdf8 Nazghul-0.7.1 --- b7e0472e04898913774c2bd1e74589292933bdf8 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..2a62756 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,119 @@ +To find out what should go in this file, see "Information For +Maintainers of GNU Software" (maintain.texi), the section called +"Recording Contributors". + +In alphabetical order by last name.... + +Amorim, Roberto: +scripts/nazghul.iss: + Adding the Inno Setup script file used to generate the Windows installer + +Bauer, Andreas: +In src/Makefile.in, worlds/Makefile.in, configure, configure.ac, configure.in, +depcomp, install-sh, ltmain.sh, missing, mkinstalldirs, src/Makefile.am, +Makefile.in, NEWS, RELEASE_NOTES, acinclude.m4, aclocal.m4, autogen.sh, +config.guess, config.sub, AUTHORS, ChangeLog, Makefile.am + Changed build system to GNU-compliant scheme + +Douglas, Tim: +In src/scheme.c: + Fixed compile error on Max OS X +In src/skill.c, src/skill_set.c, src/skill_set_entry.c, src/templ.c: + checks for malloc.h, to fix OsX Build + +Gabbert, Kevin: +In worlds/haxima-1.001/images/kgabbert + Created images in .png file(s) + +Garrison, Karl: +In src/cmd.c, src/cmd.h, src/ctrl.c, src/event.h: + Added command to dump terrain sprites as one BMP per frame + +Gervais, David: +In worlds/haxima-1.001/images/dgervais + Created images in .png file(s) + +Glasby, Sam: +(See user sglasby in the ChangeLog) +In src/combat.c, src/cursor.cpp, src/event.h, src/play.c, src/play.h: + Added an (X)amine command, which is an extended (L)ook. +In src/play.c, src/character.cpp, src/character.h, src/combat.c, src/status.c: + Added pmask to Ztats display + Added ammo display to Attack prompt + Require confirmation for attack self +In src/game.c, src/terrain.c, src/terrain.h, src/terrain_map.c + Lots of changes to terrain palettes. +In src/event.h, src/play.c, src/terrain.c, src/terrain.h: + Added and implemented (T)errain editing command +In worlds/haxima-1.001/images + Reorganized images throughout all +In worlds/haxima-1.001/images/sglasby + Created images in .png file(s) +In worlds/haxima-1.001 created: + P_terrain_test.scm, P_terrain_test.scm, scenery.scm +In worlds/haxima-1.001 made changes throughout: + session.scm, sprites.scm, sprite-sets.scm, palette.scm, objs.scm, + moongate-clearing.scm + +Johansson, Janne: +In src/terrain_map.c, fixes for compiler warnings. +In configure.ac, fix for SDL_image.h include path +In doc/GAME_RULES, doc/MAP_HACKERS_GUIDE, doc/USERS_GUIDE, doc/world_building/sound_sample_media.txt: + various nitpicks in docs and spelling fixes +In src/ascii.c, uninitialized nitpickings. shuts gcc4 up +In src/terrain_map.c, fixing compiler warnings + +Links, Bernhard: +In configure.ac, change for checking SDL install +In worlds/haxima-1.002/Makefile.am, added missing file(s) +In src/haxima.c, scheme.c, images.c, common.c, sound.c, session.c: added + commandline include dir and save dir + +McNutt, Gordon: +(See user gmcnutt in the ChangeLog) +In worlds/haxima-1.001: + First version of all files except images/* other than images/gmcnutt, + and P_terrain_test.scm, P_terrain_test.scm, scenery.scm +In worlds/haxima-1.002: + All files, some re-used from haxima-1.001 +Everywhere else: + Most changes except where otherwise noted. + +Parker, Kris: +(See user kaypy in the ChangeLog) +In worlds/haxima-1.002/shapes.png, provided human knight sprite based on + existing sprite and added transparency to some sprites +In worlds/haxima-1.002/food.png and addons.png, added transparency to some + sprites +Added worlds/haxima-1.002/newmonst.png, newfolks.png +In worlds/haxima-1.002/building.png, added the tower sprite +In worlds/haxima-1.002/sprite-sets.scm, sprites.scm and npc-types.scm, added + new goblin sprites +In worlds/haxima-1.002/mouse.scm, minor bugfix +Added nazghul.nsi, nazinst.ico +In src/factions.h, minor bugfix + +Patersen, Jim (http://www.mfiles.co.uk): +In worlds/haxima-1.002/music: + ballad.mid + dragon-slayer.mid + into-battle.mid + Minuet-like-Mozart.mid + bassoons-and-harpsichord.mid + fair-camelot.mid + Lute-and-recorder-ballad.mid + plainchant-recorder-trio.mid + double-trios.mid + game-music2.mid + medieval-quest.mid + wind-trio.mid + dragon-quest.mid + harpsichord-piece.mid + minstrel-dance.mid + +Riberdy, Steve: +In worlds/haxima-1.002/runestones.png, provided the images + +Steele, Joshua: +In worlds/haxima-1.001/images/jsteele + Created images in .png file(s) diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + 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 + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..fd87e1e --- /dev/null +++ b/ChangeLog @@ -0,0 +1,15259 @@ +2010-12-11 Gordon McNutt + + * scripts/nazghul.iss: + Updated version number and URL. Changed the program name to haxima. + +2010-08-27 Gordon McNutt + + * src/Party.cpp, src/cmd.c, src/node.c, src/node.h, src/place.c, src/player.cpp, src/session.c, src/status.c: + Fixed all the warnings related to strict aliasing and type punning. We now compile warning-free with gcc 4.4.4. + +2010-08-26 Gordon McNutt + + * src/map.h, src/menus.c, src/menus.h, src/nazghul.c, src/object.c, src/object.h, src/occ.c, src/occ.h, src/place.c, src/place.h, src/player.cpp, src/player.h, src/sched.c, src/sched.h, src/scheme.c, src/screen.c, src/screen.h, src/session.c, src/session.h, src/sky.c, src/sound.c, src/sound.h, src/species.c, src/species.h, src/sprite.c, src/sprite.h, src/status.c, src/status.h, src/terrain.c, src/terrain.h, src/terrain_editor.c, src/terrain_map.c, src/terrain_map.h, src/tree.c, src/tree.h, src/vehicle.cpp, src/vehicle.h, src/vmask.c, src/ztats_container_pane.c, src/ztats_container_pane.h, src/Arms.cpp, src/Arms.h, src/Being.cpp, src/Being.h, src/Field.cpp, src/Field.h, src/Missile.cpp, src/Missile.h, src/Party.cpp, src/ascii.c, src/astar.c, src/cfg.c, src/cfg.h, src/character.cpp, src/character.h, src/clock.c, src/clock.h, src/closure.c, src/closure.h, src/cmd.c, src/cmd.h, src/cmdwin.c, src/cmdwin.h, src/common.c, src/common.h, src/console.c, src/console.h, src/conv.c, src/ctrl.c, src/debug.c, src/debug.h, src/dice.c, src/dice.h, src/dimensions.c, src/dtable.c, src/dtable.h, src/effect.c, src/effect.h, src/factions.h, src/file.c, src/file.h, src/foogod.c, src/foogod.h, src/images.c, src/images.h, src/kern.c, src/kern_intvar.c, src/kern_intvar.h, src/log.c, src/log.h, src/los.c, src/los.h, src/magic.c, src/magic.h, src/map.c: + Fixed compiler warnings related to const vs non-const char pointers + +2010-03-08 Gordon McNutt + + * src/menus.c: + Don't load the demo if the player has a saved game. In this case he probably just wants to Journey Onward with minimal delay. + +2009-10-19 kaypy + + * worlds/haxima-1.002/start-new-game.scm: + game version number incremented + + * src/kern.c: + kern.c gets USE_QUESTS from ../config.h, the same way USE_SKILLS works + + * win32/config.h, win32/readme.txt: tweaks to win32 build + +2009-10-17 Gordon McNutt + + * src/Makefile.am, COPYING, NEWS, AUTHORS: Update for 0.7.0 release + +2009-10-10 Gordon McNutt + + * doc/USERS_GUIDE: + Added CTRL-E)val to the USERS_GUIDE with an example string for teleporting the player. + + * src/cmd.c: CTRL-E)val now gives a prompt. + + * worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/edward.scm, worlds/haxima-1.002/nate.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/tbl.scm: + Bandit quest log stuff now done. + + * src/cmd.c, src/cmd.h, src/ctrl.c, src/event.c, src/event.h, src/session.c, src/session.h: + Added CTRL-E to developer mode. This will let you enter a Scheme expression in the cmdwin and then the kernel will evaluate it. I will not be responsible for the results. + +2009-10-04 Gordon McNutt + + * doc/USERS_GUIDE: Corrected some spell listings + + * worlds/haxima-1.002/tools.scm: + Shortened the time it takes to pick locks + + * worlds/haxima-1.002/skills.scm: + Reshuffled skills so that wanderer will get pickpocket eventually; also removed butcher from the lists since there isn't a lot one can do with it yet. + + * worlds/haxima-1.002/naz.scm: + Made NPC's level depend on number of player party members + + * worlds/haxima-1.002/disarm-trap.scm: + Disarm skill depended on wrong ability + + * worlds/haxima-1.002/glasdrin.scm: + Made the Stewardess's chest invisible (to justify the MAN's hint about Wis Quas), and removed the magic lock and burn trap (I see no need to make it the most-protected chest in the game). + +2009-10-03 Gordon McNutt + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm: + Made the Disarm Traps spell fallible. Bonus is the average of magical and thiefly abilities. + +2009-10-02 Gordon McNutt + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm: + An Sanct (Unlock Mundane) can now fail. Caster's bonus is the average of white-magic and thief abilities + + * worlds/haxima-1.002/potions.scm: + Changed stats potions as per kaypy's suggestion. Chance and degree of working now drops as base stat increases. + +2009-10-01 kaypy + + * worlds/haxima-1.002/necromancer.scm: + necromancer conv changes with warritrix status + + * worlds/haxima-1.002/lost-halls-mech.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/quests-data.scm: + can no longer find warritrix before quest + + * worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/steward.scm: + a ream of quest debugging + + * worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/steward.scm: + convs tweaked to delay warritrix mission + +2009-09-29 Gordon McNutt + + * src/console.c, src/console.h, src/player.cpp: + Fixed a crasher that occurred when a console color push/pop crossed a newline boundary + + * worlds/haxima-1.002/species.scm: + Gave bats vision radius 19 since they may attack the player when he's in the voidship + + * worlds/haxima-1.002/runes.scm: + Fixed a crasher when getting the warritrix rune + +2009-09-29 kaypy + + * worlds/haxima-1.002/quests-data.scm: purged a duplicate entry + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/runes.scm, worlds/haxima-1.002/warritrix.scm: + using quest-data-complete preferentially + + * worlds/haxima-1.002/quests-mech.scm: A bunch more documentation + Added a quest-data-complete method + +2009-09-28 kaypy + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/jeffreys.scm: + A bunch more triggers for Warritrix info updates + + * worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm: + Some quest documentation + +2009-09-27 kaypy + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/warritrix.scm: + Wise quests pass 1- linked in results of find-in-files: wise + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm: + Placeholder quest entries for all of the wise + +2009-09-26 kaypy + + * worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/quests.png, worlds/haxima-1.002/sprites.scm: + Partial work toward tracking the players progress at finding the various wise + + * worlds/library/artwork/hirespeople/paladin.xcf, worlds/haxima-1.002/hirespeople.png, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/statue-of-justice.scm, worlds/haxima-1.002/valus.scm: + Added a bedraggled version of the paladin sprite for those in disgrace + + * worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/player.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/statue-of-justice.scm, worlds/haxima-1.002/warritrix.scm: + Convert and fix glasdrin convs + +2009-09-25 Gordon McNutt + + * worlds/haxima-1.002/skills.scm: Jump should span at least one tile + +2009-09-22 Gordon McNutt + + * src/character.cpp: X)amine was showing the names of un-met NPC's + + * worlds/haxima-1.002/runes.scm: Fixed a crasher when picking up runes + + * worlds/haxima-1.002/effects.scm: + Think I finally got the slimes tuned right. + + * worlds/haxima-1.002/sounds.scm: Fixed path to ballad.ogg + +2009-09-18 kaypy + + * win32/Makefile: added terrain editor to win32 + +2009-09-18 Gordon McNutt + + * src/session.c: Fix for problem starting new game on x86_64 + +2009-09-16 Gordon McNutt + + * worlds/haxima-1.002/effects.scm: Tuning slime split probability + + * worlds/haxima-1.002/spells.scm: + Added royal cape as an ingredient to all the ward spells + + * worlds/haxima-1.002/slywan.scm: + Change slywan's alignment directly to avoid 'Slyway is charmed' log message + + * worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/tooth.scm: + Added grease to merchandise of earl and tooth + + * worlds/haxima-1.002/books.scm: + Added royal cape to the books on ward spells + +2009-09-15 Gordon McNutt + + * src/Being.cpp: Fixed a hang on rendezvous + + * worlds/haxima-1.002/music/Makefile.am: Fixed music installation + +2009-09-13 Gordon McNutt + + * worlds/haxima-1.002/skills.scm: Tuning skills + + * worlds/haxima-1.002/quests-data-static.scm: + Fixed some typos in the quest text + + * worlds/haxima-1.002/potions.scm: + Decided that gain-stats potions are rare enough that they shouldn't fail + + * worlds/haxima-1.002/pitfalls.scm: + Fixed a cut-and-paste that prevents the Arm Trap skill from working + + * worlds/haxima-1.002/edward.scm: Fixed typo in conv + + * worlds/haxima-1.002/nate.scm: Nate responds to NAME keyword + + * worlds/haxima-1.002/lia.scm: Made some scrolls cheaper + + * worlds/haxima-1.002/shroom.scm: + Shroom responds to queries about royal cape + + * worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/tim.scm: + Some characters shouldn't respond to the 'common folk' keywords + + * worlds/haxima-1.002/ability.scm: Ratlings summon more critters + + * src/ztats.c, src/kern.c: + Fixed a crasher due to the quest pane not removing itself during session teardown + + * worlds/haxima-1.002/effects.scm: + Fixed a bug that prevented ensnare from being removed + + * src/map.c: Xray works in total darkness + +2009-09-12 Gordon McNutt + + * src/Party.cpp: + Fixed a crasher that occurred after talking to party members in wilderness mode + +2009-09-09 Gordon McNutt + + * worlds/haxima-1.002/start-new-game.scm: Removed reference to florinth + + * worlds/haxima-1.002/quests-data-static.scm: Grammatical error + + * worlds/haxima-1.002/shard.scm: Removed refs to florinth + + * worlds/haxima-1.002/gen.scm: Removed some spaces and uppercases words + +2009-08-30 kaypy + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/chanticleer.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/player.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/runes.scm, worlds/haxima-1.002/silas.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/steward.scm: + First pass at warritrix and absalot rune quest info + +2009-08-22 Gordon McNutt + + * configure.ac: Turned on skills and quests by default + +2009-08-21 Gordon McNutt + + * worlds/haxima-1.002/arms.scm: + Fix for 1843026: vial slimes set to user's faction + +2009-06-24 Gordon McNutt + + * src/ascii.c, src/common.h, src/dimensions.c, src/player.cpp, src/vehicle.cpp, src/wind.c, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/vehicles.scm: + Fix for 1900156: Has anyone seen East or South winds for a while? + + Haxima: + o In cast-wind-change don't allow HERE + o Alway ensure at least 10 turns on a wind change spell + o For ships switched tailwind to be better than crosswind + + Kernel: + o Log to the console whenever the wind shifts + o Change wind directions to be 8-way instead of 4-way (changed vehicle code to + accomodate) + o Make wind widget wide enough for longest string + o Log player party movement cost in developer mode + +2009-06-23 Gordon McNutt + + * src/cmd.c: + Fix for 1900157: kern_ui_select_party_member() unconditionally uses + cmdwin_pop() after calling select_party_member(), but in cases where there is + only one party member there was nothing to pop. Now there is. + + * worlds/haxima-1.002/runes.scm: + Fix for crasher when picking up certain runes + + * src/character.cpp, src/play.c: + Fix for 2129810: added some explanatory log messages + + * win32/Makefile, win32/config.h: Fix for 2360126: applied patch + +2009-06-21 Gordon McNutt + + * src/map.c: Fix for 2364311: avoid divide-by-zero error + + * worlds/haxima-1.002/npc-types.scm: + Fix for 2364368: added sleep immunity to demons (incl Nossifer) + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/effects.scm: + Fix for 2398446: added list of acid-immune weapon types + + * worlds/haxima-1.002/alchemist.scm: + Fix for 2404468: reworded 'search' to be 'probe' + + * worlds/haxima-1.002/alchemist.scm: + Fix for 2404478: reworded a statement + + * worlds/haxima-1.002/640x480_splash.png, worlds/haxima-1.002/splash.png: + Fix for 2466986: removed version number from splash images + + * worlds/haxima-1.002/gamestart-mech.scm: + Fix for 2467008: make the blue gate in the character creation map black + +2009-04-11 kaypy + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/ghertie.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/jewelry.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/runes.scm, worlds/haxima-1.002/the-man.scm: + pirate rune quest and subquests + I think I have tested most of the paths through this, but it gets a touch baroque and thus could use more playtesting + + * worlds/haxima-1.002/gamestart.scm, worlds/haxima-1.002/start-new-game.scm: + moved cheating tweaks into gamestart where they can tweak more + + * worlds/haxima-1.002/effects.scm: added a generalized on-death method + + * worlds/haxima-1.002/kobj.scm, worlds/haxima-1.002/powers.scm: + added an ifc for objects that need a callback when obtained via odd means such as pickpocketing (basically, anything that doesnt go via ifc-get ought to trigger ifc-receive instead) + +2009-04-09 kaypy + + * src/map.c: Rounding tweak for viewscreens with even numbers of tiles + + * src/closure.h: gcc didnt like repeated identifier + +2008-12-12 Gordon McNutt + + * worlds/haxima-1.002/newterrain.png, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Added another tombstone + +2008-12-11 Gordon McNutt + + * worlds/haxima-1.002/newterrain.png, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Added a tombstone + +2008-12-08 Gordon McNutt + + * src/event.c, src/terrain_editor.c: + Engine changes: + o The terrain editor UI now has two status panes: the terrain palette and a + list of commands. + +2008-12-04 Gordon McNutt + + * src/map.c: Fixed mouse-clicking on the map while zoomed out + +2008-12-01 Gordon McNutt + + * worlds/haxima-1.002/start-new-game.scm: + Accidentally committed my test version of this earlier, restoring it. + + * src/terrain_editor.c, src/terrain_map.c, src/terrain_map.h: + Added undo (ctrl-z) and redo (ctrl-r) commands to terrain editor + +2008-11-30 Gordon McNutt + + * src/terrain.c, src/terrain.h: Removed dead code + + * src/terrain.c, src/terrain.h: + Removed the current terrain index and quick entries from the palette struct and terrain code (moved to terrain editor on my last commit) + + * src/terrain_editor.c: + Part 1 of moving the current terrain and quick terrain settings from the palette struct to the terrain editor code + + * src/terrain_editor.c: + Terrain editor now correctly handles dragging the mouse to paint + + * worlds/haxima-1.002/florinth.scm: + The great and wicked city of Florinth. Now mostly blank. + + * src/cmd.c, src/cmd.h, src/map.c, src/status.c, src/terrain.c, src/terrain.h, src/terrain_editor.c: + Engine changes: + o Terrain editor now displays the terrain pallete in a scrolling status + window. Clicking on a terrain selects it for "painting". + + * src/Makefile.am, src/cmd.c, src/cmd.h, src/terrain_editor.c, src/terrain_editor.h: + Engine changes: + o Moved code for terrain editing from cmd.c to newly created terrain_editor.c. + + * src/status.c, src/status.h: + Changed a comment and removed some dead code + +2008-11-29 Gordon McNutt + + * src/terrain.h, src/terrain.c: + Engine changes: + o Terrain palette entries are now listed in two ways: by glyph lookup (the old + way, which helps load maps faster) and now by the order in which things are + added to the palette (the even older way, which allows the map editor to list + them in the same order as the script) + + * worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/start-new-game.scm: + Changes to haxima: + o (mk-dungeon-level ...) now binds rooms in diagonal directions. + + * src/character.cpp, src/common.c, src/place.c, src/place.h: + Engine changes: + o After exiting to wilderness, the party is positioned on the tile adjacent to + the town in the exit direction. We'll see how this goes. + +2008-11-28 Gordon McNutt + + * worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/start-new-game.scm: + Forgot the island on my last commit. + + * worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/start-new-game.scm: + Extended the Shard. Added new island. + +2008-11-25 Gordon McNutt + + * src/character.cpp, src/character.h: + Prompt the user to abort a task on damage. Allow them to ignore damage. + + * worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/skills.scm: + Another attempt to tune skill level requirements + + * worlds/haxima-1.002/effects.scm: Removed some debug + + * worlds/haxima-1.002/powers.scm: + Pickpocket rolls to succeed before showing target inventory + + * worlds/haxima-1.002/skills.scm: Made lockpicking a passive skill + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/pitfalls.scm, worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/tools.scm: + Changes to haxima: + o Arming traps now entails some risk + o Tweaked stealth mode rolls + + * scripts/dice_rolls.pl: + Perl script for computing dice roll probablities with 2 dice + +2008-11-24 kaypy + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/runes.scm: + void temple rune quest upgraded + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/runes.scm, worlds/haxima-1.002/warritrix.scm: + spider rune quest upgraded + angriss' lair location given by description + (sextant coords from goblins just seemed wierd) + + * worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/special.scm: + moving angriss' lair a little (to a more readily describably location) + +2008-11-23 Gordon McNutt + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + Changes to haxima: + o Added a "stuck" effect that works like ensnare but rolls against thiefly + ability + o Wriggle now has a very good chance of getting stuck. + +2008-11-23 kaypy + + * worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/runes.scm: + fire sea rune quest (such as it is) upgraded + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/runes.scm: + kurpolis rune quest upgraded + + * worlds/haxima-1.002/quest-sys.scm: quest-set-icon! fixed + +2008-11-23 Gordon McNutt + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/pitfalls.scm: + Changes to haxima: + o Using pitfalls entails some risk. Roll against thiefly ability. This is the + arm trap skill. + +2008-11-23 kaypy + + * worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/quests-mech.scm: + a batch of subquests (although they wont all be set at once for much longer) + + * worlds/haxima-1.002/conv.scm: typo + + * worlds/haxima-1.002/runestones.png, worlds/haxima-1.002/sprites.scm: + runestone group sprite + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm: + dragons blood quest upgraded + + * worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/ztats-quest-ui.scm: + tweaked quest-status callback. Also made the display routine actually invoke it + +2008-11-23 Gordon McNutt + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + Changes to haxima: + o Reduced fatigue time + o Added warrior skill sets + o Jump now causes fatigue and is blocked by it + o Tuned jump range + o Bugfix: can't sprint through people or impassable terrain + + * worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/disarm-trap.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/the-man.scm: + Changes to haxima: + o Removed mana cost for skills. + o Removed ap cost for some skills (replacing with multi-turn tasks) + o Removed the "detect trap" skill. Use existing s)earch command instead, + thiefly ability already used to roll for success. Magic detect trap left + as-is (no trip chance). + o Modified the "disarm trap" skill to be multi-turn + o When describing doors and chests, disarmed traps are annotated + + * worlds/haxima-1.002/game.scm: Revised canonical difficulty classes + +2008-11-22 kaypy + + * worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/ztats-quest-ui.scm: + support for subquests + + * worlds/haxima-1.002/gregor.scm: 'if' glitch + decapitalization + +2008-11-20 Gordon McNutt + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + Changes to haxima: + o Added simple fatigue effect + o Sprint causes fatigue + o Fatigue prevents sprint + + * src/cmd.c, src/result.h: Engine changes: + o New result code: not-now + + * worlds/haxima-1.002/skills.scm: + Fixing some errors; not sure what I was testing before my last commit + + * worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/scrolls.scm, worlds/haxima-1.002/skills.scm: + Changes to haxima: + o Added two new ability calculators for strength-based acrobatics and + dexterity-based acrobatics. + o The sprint skill now uses strength-based acrobatics to compute max range. + + * worlds/haxima-1.002/tools.scm: Time to pick a lock depends on dc + +2008-11-19 Gordon McNutt + + * src/character.cpp, src/ctrl.c, src/foogod.c, src/foogod.h, src/player.cpp: + Foogod title bar now shows party movement mode and active party member + + * worlds/haxima-1.002/conv.scm: No need to *lie* about the directions + + * worlds/haxima-1.002/tools.scm: + Using picklocks now takes multiple turns + + * worlds/haxima-1.002/conv.scm: + Made default directions somewhat helpful + + * worlds/library/artwork/creatures/chicken.xcf: Changes to chicken art + + * src/character.cpp: + Was passing the gob incorrectly to the task procedure + + * src/cmd.c, src/cmd.h: Can't quit while engaged in a task + +2008-11-18 Gordon McNutt + + * worlds/haxima-1.002/powers.scm: + Charm only hurts diplomacy on failure against a non-immune target + + * worlds/haxima-1.002/effects.scm: + Paralyzed party members cannot rendezvous in follow mode + +2008-11-17 Gordon McNutt + + * src/player.cpp: Can't rendezvous to exit if a party member is charmed + + * src/character.cpp: + o NPC's now (in addition to PC's) log messages when they start, end or abort a + task. + o setPlayerControlled(false) (ie, charm) cancels tasks + o Fixed an extra space char in describe(); made spacing consistent; changed "a + LX" to "an LX" + + * worlds/haxima-1.002/creatures.png, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/scrolls.png, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/trigrave.scm: + Chickens + + * worlds/library/artwork/creatures/chicken.xcf: Chicken + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/scrolls.png, worlds/haxima-1.002/scrolls.scm, worlds/haxima-1.002/spells.png, worlds/haxima-1.002/spells.scm: + Decided to go ahead and incorporate my test scroll as a new spell: Rel Xen Quas or Beastly Illusion will charm it's target with faction-monster, making decent folk attack them. Not sure if it's useful. Also tweaked some of the spell sprites to make party effect sprites more consistent with Vas An Nox. + + * worlds/haxima-1.002/scrolls.scm: + Added a scroll to test charm on oneself + + * worlds/haxima-1.002/effects.scm: + Modified the charm effect to use kern-char-set-player-controlled as well as changing the target's current faction + + * src/character.cpp, src/cmd.c: + Changed setPlayerControlled for charm; it tries to do the right thing for party control when in solo or follow mode + + * src/object.c: Removed some dead code + +2008-11-16 Gordon McNutt + + * src/character.cpp: Death and sleep cancel tasks + + * src/cmd.c: + Loitering disabled while any party member is engaged in a task + + * src/character.cpp: + Only save AP debt; a positive would be carried over as an unwarranted ap bonus when the game restarts + + * src/character.cpp: Removed some old debug + + * src/player.cpp: + Party cannot exit to wilderness while one or more is engaged in a task + +2008-11-16 kaypy + + * worlds/haxima-1.002/tbl.scm: added is-tbl? check + also, lisp if syntax is a cruel abuse upon generations of innocent coders + + * worlds/haxima-1.002/alchemist.scm: + "find out about runes" quest upgraded (missed a file) + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm: + "find out about runes" quest upgraded + + * worlds/haxima-1.002/naz.scm: removed some debugging messages + + * worlds/haxima-1.002/quests-mech.scm: + alter quest feedback to prevent colour glitches + +2008-11-16 Gordon McNutt + + * worlds/haxima-1.002/tools.scm: + Added a special object to test multi-turn tasks. + + * src/object.c, src/object.h, src/player.cpp, src/character.cpp, src/character.h, src/cmd.c, src/kern.c: + This set of changes is a second pass at implementing multi-turn tasks. It is + far from well-tested and I'm certain it breaks the charm effect. But the basics + of task starting, completing, aborting and saving/reloading are functional, and + the party control management that goes along with it. Tasks in wilderness are + not supported yet. Canceling tasks are accomplished by setting the PC to solo + mode (the player will be prompted to confirm). + + o Added kern-char-task-begin, -end, -continue and -abort. + o Added corresponding methods to the Character class + o Ripped a bunch of code out of setCurrentFaction that was used to implement + charm, but was munging things up now, and which probably never belonged there + in the first place. + o Similarly I tore out the code I recently put in setControlMode, for similar + reasons. + o Had to touch a few other places to prevent code from overriding the PC + control mode while it was engaged in the task. + +2008-11-16 kaypy + + * worlds/haxima-1.002/abe.scm: tweaks to Abe's conv + +2008-11-15 Gordon McNutt + + * src/escape.c, src/escape.h: + Might need these to build after my last commit. + + * src/Makefile.am, src/character.cpp, src/cmd.c, src/cmd.h, src/ctrl.c, src/kern.c, src/play.c, src/player.cpp: + Added an ESC interrupt menu. This allows the user to take some action when the active PC is stuck with a high AP debt. The intention is to use this for multi-turn tasks as well. + +2008-11-14 Gordon McNutt + + * src/conv.c: + Another bug fixed in keyword highlighting: fen comes before fens + +2008-11-13 Gordon McNutt + + * src/conv.c: + Short keywords that appeared with punctuation after them were not getting highlighted + + * src/kern.c: + Bug introduced on my last commit: don't register NIL conversations + + * src/conv.c, src/conv.h, src/kern.c, src/scheme-private.h, src/scheme.c: + Processing conversation keywords is now done lazily, when a conversation is entered the first time. This fixes a bug where in some save files the file containing a conversation is loaded after the character that uses it. + + * worlds/haxima-1.002/gregor.scm: + End conv if Gregor kills Nate when Nate is speaker + + * worlds/haxima-1.002/gregor.scm: Changed who shoots the deathball + +2008-11-13 kaypy + + * worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/gwen.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/runes.scm, worlds/haxima-1.002/thiefs_den.scm, worlds/haxima-1.002/traps_1.scm, worlds/haxima-1.002/traps_2.scm, worlds/haxima-1.002/traps_3.scm, worlds/haxima-1.002/traps_4.scm: + thief quest upgraded + + * worlds/haxima-1.002/hackle.scm: swapping allcaps for colour highlight + + * worlds/haxima-1.002/chanticleer.scm: typo + +2008-11-13 Gordon McNutt + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/tools.scm: + Reverted lockpicking and unlock spells; removed unlock as a skill + + * worlds/haxima-1.002/demo.scm: + Renamed the Gate Portal as Demo Scene to make the starting console message clear that the player is watching a demo + + * src/kern.c: + kern.c includes config.h so the quest status page will work when configured. + + * worlds/haxima-1.002/gregor.scm: + Gregor kills Nate. Cleaned up his conv a bit, too. + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/quest-talk-to.scm: + Getting rid of obsolete quest file + + * src/conv.c: Bugfix: short keywords not getting detected in some cases + + * worlds/haxima-1.002/ini.scm: + For Ini, 'deep' was a keyword but he gave the default reply unless he was flagged as ready to join the party. I added an alternate default reply so it doesn't look like a bug. + + * scripts/RELEASE_CHECKOFF: Some updated notes + +2008-11-12 Gordon McNutt + + * worlds/haxima-1.002/camping-map.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/npc-types.scm: + Changes to haxima: + o The camping ambush was still being added via the obsolete + kern-set-camping-proc. Fixed it to use kern-add-hook. + o Fixed the statue curse: same problem. Now uses kern-rm-hook as well. + o Reverted faction-glasdrin to be its own value so that the exile curse won't + affect the player in all cities. Fixed the glasdrin guard spawn pts to spawn + guards specific to glasdrin so they will enforce the exile curse. + + * src/kern.c, src/session.c, src/session.h: Engine: + o Session no longer saves its hooks. All session hooks are either being loaded + on startup via script files or via effects. Saving them was just causing them + to be added multiple times on reload. + o Added kern-rm-hook and session_rm_sym_hook. To be removed, a hook proc must + have been a symbol. + + * worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/tools.scm: + Changes to haxima: + o Picklocks are no longer u)sable, the player must y)use the picklock skill + o Breaking lockpicks is done in the skill based on critical failure + o First pass at level requirements for wrogue skills + + * src/cmd.c, src/ctrl.c, src/result.h: Engine: + o Added #include to enable skills if configured + o Added a new result code: critical failure + o Colorized reporting of result codes in the console + +2008-11-11 kaypy + + * worlds/haxima-1.002/sounds.scm, worlds/haxima-1.002/music/Lute-and-recorder-ballad.ogg, worlds/haxima-1.002/music/Minuet-like-Mozart.ogg, worlds/haxima-1.002/music/ballad.ogg, worlds/haxima-1.002/music/bassoons-and-harpsichord.ogg, worlds/haxima-1.002/music/double-trios.ogg, worlds/haxima-1.002/music/dragon-quest.ogg, worlds/haxima-1.002/music/dragon-slayer.ogg, worlds/haxima-1.002/music/fair-camelot.ogg, worlds/haxima-1.002/music/game-music2.ogg, worlds/haxima-1.002/music/harpsichord-piece.ogg, worlds/haxima-1.002/music/into-battle.ogg, worlds/haxima-1.002/music/medieval-quest.ogg, worlds/haxima-1.002/music/minstrel-dance.ogg, worlds/haxima-1.002/music/music.scm, worlds/haxima-1.002/music/plainchant-recorder-trio.ogg, worlds/haxima-1.002/music/wind-trio.ogg: + Lets try Ogg music + +2008-11-11 Gordon McNutt + + * worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/powers.scm: + Changes to haxima: + o Locked and magically locked doors and chests have a difficulty + class. Currently everything defaults to "normal". + o The lock and magic unlock powers roll to succeed. + + * worlds/haxima-1.002/statue-of-justice.scm: + Status of Justice's name is known to player + + * worlds/haxima-1.002/game.scm: + Removed some commented-out code; added some generic difficulty class values; changed glasdrin faction to match normal men (otherwise guards in glasdrin won't attack if you assault the populace or get exiled by the statue) + +2008-11-10 Gordon McNutt + + * src/conv.c: + Maybe I should at least *compile* my changes before checking them in. + + * src/conv.c: + Fixed crasher if unknown NPC initiaites conversation with player + + * worlds/haxima-1.002/gamestart.scm: + Statue names are automatically known to player + + * worlds/haxima-1.002/gamestart-statues.scm: + Gave the starting statues some personality. + +2008-11-09 Gordon McNutt + + * src/nazghul.c: Removed some dead code + + * COPYING, src/ascii.c, src/cmd.c, src/ctrl.c, src/images.c, src/images.h, src/map.c, src/menus.c, src/play.c, src/screen.h, src/screen_dims.h, src/sprite.c, worlds/haxima-1.002/kern-init.scm: + I did not get all of Eero's 16bpp patch applied. He sent me some new patches, which are applied now. + + * src/character.cpp, src/cmd.c, src/combat.c, src/conv.c, src/kern.c, src/log.c, src/log.h, src/nazghul.c, src/player.cpp: + Added log_banner(), which provides a consistent format for especially notable log messages. Converted some existing messages over to use it. + + * src/scheme.c: + Fixing a crash that may occur when a hook procedure loads a file. + + * configure.ac: Bumped version to 0.7.0 on trunk for next time + + * configure.ac: Bumped version to 0.6.2 for next time + + * NEWS: Updated NEWS + + * src/character.cpp, src/character.h, src/conv.c, src/kern.c: + In conversations, the NPC's name is not printed until the player queries NAME + + * NEWS: Added a few more changes to NEWS + + * src/Makefile.am: Removed bitfield.h from source list + + * NEWS: Updated NEWS for 0.6.1 release + + * worlds/haxima-1.002/bart.scm: Removed duplicate word in conv + +2008-11-09 kaypy + + * worlds/haxima-1.002/game.scm: + uses kern-set-start-proc to initiate hotfix + + * worlds/haxima-1.002/game.scm: + hotfix for saves with voidgap/deeps bug. + + still needs hook code in kern + +2008-11-08 kaypy + + * worlds/haxima-1.002/powers.scm: pullling in spell fixes + + * worlds/haxima-1.002/voidgap-passage.scm: pulling in fix from 1.4 + + * worlds/haxima-1.002/scrolls.scm: pull in scroll fixes + + * worlds/haxima-1.002/necromancer.scm: + pulled in conversation fix from 1.16 + + * worlds/haxima-1.002/naz.scm: + pulled in some fixes and stuff I will need for save update + + * worlds/haxima-1.002/mouse.scm: pulled in conversation fix from 1.19 + + * worlds/haxima-1.002/enchanter.scm: pulled in spelling fix from 1.25 + +2008-11-08 Gordon McNutt + + * worlds/haxima-1.002/fields.scm: + Ported over chance to avoid sleep fields so that permanent sleep fields are not unavoidably lethal to one-man parties + + * worlds/haxima-1.002/effects.scm: + Ported over fix for FR 2216959- prevent multiple protection spells on one character. + + * worlds/haxima-1.002/silas.scm: + Ported over fix for Silas not giving the player a clue about the final rune + +2008-11-08 kaypy + + * worlds/haxima-1.002/silas.scm: + silas is more forthcoming about the final rune + + * worlds/haxima-1.002/powers.scm: + undo cone tweak- had undesirable side effects + + * worlds/haxima-1.002/powers.scm: + fixed poison wind and sleep wind spells. tweaked cone display + + * worlds/haxima-1.002/fields.scm: + sleep fields have a slight avoidance chance, so a character stuck in a permanent sleep field will have a chance to get out eventually + + * src/kern.c: + (kern-script-version) with no arguments returns current version + +2008-11-08 Gordon McNutt + + * configure.ac: Bumped version to 0.6.1 in prep for next release + + * src/Makefile.am, src/nazghul.c, src/nazghul.h, src/screen.c: + Merged over Eero's 16bpp patch + +2008-11-07 kaypy + + * worlds/haxima-1.002/effects.scm: + quickfix for FR 2216959- prevent multiple protection spells on one character. + + * worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/quests-data-static.scm: + adding quest update notifications + tweaked order of quest completion + + * worlds/haxima-1.002/quests-mech.scm: bug fixing in quest callbacks + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/start-new-game.scm: + moved quest-ui flag to somewhere it doesnt break reloads + + * worlds/haxima-1.002/enchanter.scm: + use quest complete with notification + + * worlds/haxima-1.002/quests-mech.scm: quest notifications + used wrong loading type for refreshing questlist on save load + + * worlds/haxima-1.002/quests-data-static.scm: bugfix- unmatched quotes + + * worlds/haxima-1.002/ztats-quest-ui.scm: + disable quest ui based on script side tag + + * worlds/haxima-1.002/start-new-game.scm: + added script side quest interface disabling + + * worlds/haxima-1.002/quests-mech.scm: + added procedure to reload quests-data to refresh quest info + mechanisms to handle postponing experience granted for partial completion of unassigned quests + + * worlds/haxima-1.002/quests-data.scm: + quest data should now be created/expanded as necessary for out of date save games, provided they load quests-data.scm in the first place + +2008-10-29 kaypy + + * worlds/haxima-1.002/quests-data-static.scm: + Passing a function a bunch of arguments and passing it a list containing those arguments are not the same thing. It is important to remember this. + +2008-10-29 Gordon McNutt + + * src/cmd.c: + Bugfix: if you hit ESC when selecting a guard for camping it would deref a null pointer when checking if the guard was dead + +2008-10-26 kaypy + + * worlds/haxima-1.002/quests-data-static.scm, worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/start-new-game.scm: + Separated out static quest data from quest utilities + + * worlds/haxima-1.002/ztats-quest-ui.scm: + Second pass at fixing quest description listing- Scrolling now respects lower limit of description text + + * worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/ztats-quest-ui.scm: + First pass at fixing quest description listing- No longer draws over bottom of display when overlong + + * src/event.c, src/kern.c, src/ztats.c: Tweaks to menu controls + + * worlds/haxima-1.002/quests-data.scm: + Quests should now all use the kern-ui-paginate-text function to lay out text nicely + + * src/kern.c: + Added a kern function that takes a list of lines of text and returns them in a paginated format. + +2008-10-12 Gordon McNutt + + * configure.ac, src/kern.c: + Disabling the quest UI by default, since it's still half-baked. Developers may + enable it with a configure option: + + ./configure --with-quests + + Or by editing config.h: + + #define USE_QUESTS + + This does *not* effectively disable quests, however. Some conversation scripts + are broken, apparently because they can't get quest data. + + * src/ctrl.c, configure.ac, src/cmd.c: + Disabling the Y)use command (and hence skills) by default, in preparation for + the next release, since skills are still half-baked. For developers, there is + now a configure option to enable them: + + ./configure --with-skills + + Or, if you do not use configure, add this to config.h: + + #define USE_SKILLS 1 + +2008-10-06 kaypy + + * scripts/retab.html: + A javascript app that handles lining up those tables like in arms.scm nicely + + * worlds/library/artwork/terrain/city.xcf: Larger set of buildings + + * worlds/library/artwork/terrain/towns.xcf: + Some higher res collections of houses + +2008-10-05 kaypy + + * worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/sprites.scm: + Some towns use the new tower icons + + * worlds/haxima-1.002/bigobjects.png: + a bunch of stuff hadnt worked quite right with the towers + (mostly scaling had been set to nearest pixel, rather than antialiasing) + + * worlds/library/artwork/terrain/tower.xcf: + saved at right resolution this time. + + * worlds/haxima-1.002/bigobjects.png: big tower sprites + + * worlds/library/artwork/terrain/tower.xcf: + tower, intact or ruined, with optional town + +2008-09-27 kaypy + + * INSTALL: + Added a few of the more recent libraries to the requirements list + Some additional instructions for cvs builds and a pointer to the win32 + instructions + +2008-09-26 kaypy + + * worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/books.scm: + inital quest to go meet the enchanter + + * worlds/haxima-1.002/kobj.scm: + signal-kobj now safely ignores inputs to non-present ifcs + + * worlds/haxima-1.002/start-new-game.scm: start was a little off-center + + * worlds/haxima-1.002/tbl.scm: + tbls were not roundtripping to savefiles correctly + also tightened specifications of tbl-append + + * worlds/haxima-1.002/nossifer.scm, worlds/haxima-1.002/quests-mech.scm: + additional 'whereami' text after talking to N + + * worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/quests-mech.scm: + quests kept in order of in progress/complete/failed + fixed some bugs resulting from unexpected behaviour of pair? function + +2008-09-24 kaypy + + * worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/abe.scm: + removed now redundant quest update calls + + * worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/quests-data.scm: + updating prebuild quests can trigger status update hook + + * worlds/haxima-1.002/ztats-quest-ui.scm: + quest list ui colored based on completion state + + * worlds/haxima-1.002/quest-sys.scm: + quest completion includes failure option + + * worlds/haxima-1.002/tbl.scm: + mechanism to preload a tbl when building it + +2008-09-22 kaypy + + * worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/gamestart-mech.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/abe.scm: + Uses optional tags rather title for quest lookups + Reconciles active and pregenerated quests after reload + +2008-09-21 Gordon McNutt + + * worlds/haxima-1.002/quests-mech.scm: Spelling fix + +2008-09-15 kaypy + + * worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/abe.scm: + More detail on the 'Where am I?' quest + + * worlds/haxima-1.002/ztats-quest-ui.scm: + Cleaned out some superflouous debugging printlns + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/ztats-quest-ui.scm: + A few more quests started + Prev patches had broken zstats-quest-ui up/down controls + + * worlds/haxima-1.002/quests-mech.scm, worlds/haxima-1.002/quests.png, worlds/haxima-1.002/quests-data.scm, worlds/haxima-1.002/tbl.scm, worlds/haxima-1.002/ztats-quest-ui.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/quest-talk-to.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/gamestart-mech.scm: + quests reenabled + quests have icons + quests can be removed from the log entirely + quests can be retrieved by title (assuming uniqueness, otherwise will get the first one) + a databank of not-yet-assigned quests is available, but not mandatory- Im thinking this is useful for quests that may have changes before the player recieves them + added some initial cases + +2008-09-13 kaypy + + * worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/ztats-quest-ui.scm: + quests take a list of strings for description, to allow longer, wrapped descriptions. + + * src/sprite.h, src/sprite.c, src/kern.c: + Added a mechanism to directly paint a sprite in a sdl_rect. Intended for use with scripted UI panels + +2008-06-08 Gordon McNutt + + * src/conv.c, src/conv.h, src/menus.c, src/nazghul.c, src/sound.c, src/sound.h: + Added a menu option for keyword highlighting + + * worlds/haxima-1.002/start-new-game.scm: + Added version number to new game script + + * src/session.h, src/session.c, src/ascii.h, src/kern.c, src/play.c: + Added support for script version number. If a session fails to load, check the version number and report it to the player. + + * configure.ac: + Bumped the version number. Added min script version number. + + * src/screen.c: Moved the screen's temp buf off the stack + + * src/session.c: + Fixed some crashes that occur on a load error. session_del() should not assume + the player has been loaded, and session_load() was double-deallocating the + scheme instance. + + * src/play.c: On load error, print 'error' in red + + * src/scheme.c: + Reverting my last changes to this file; they caused a double-deallocation + +2008-06-07 Gordon McNutt + + * src/foogod.c: + bugfix: don't assume the cfg contains progress-bar-image-filename + + * src/menus.c: Bugfix: sometimes error popup was blank + + * src/nazghul.c: + Using the primitive error dialog window for library init errors early in startup. + + * src/terrain.c, src/scheme.c, src/sprite.c, src/Being.h, src/character.cpp, src/kern.c, src/Being.cpp: + Fixed some leaks; attempted to fix some other complaints from valgrind + + * worlds/haxima-1.002/ztats-quest-ui.scm: + Fixing a bug in my last commit + +2008-06-06 kaypy + + * win32/readme.txt: + Updated based on latest attempt to compile the system from scratch + +2008-06-06 Gordon McNutt + + * worlds/haxima-1.002/game.scm: Turning off the quest ui stuff for now + + * worlds/haxima-1.002/ztats-quest-ui.scm: + Changed quest ui to expect the player party gob to be a table + + * worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/quest-talk-to.scm: + Changed conv check hooks to expect the player party gob to be a table + + * src/conv.c, src/sprite.c: Checking in turned-off portrait test code. + + * src/status.c, src/applet.h: + Added optional get_desired_height call for applets + + * src/kern.c, src/object.c, src/object.h: Added kern-set-portrait + + * src/scheme.c: + Fixed a bug where a comment at the end of a loaded file could choke the interpreter + +2008-05-31 Gordon McNutt + + * src/Makefile.am, src/bitset.h, src/conv.c, src/conv.h, src/kern.c: + Kernel changes: + o Keywords which have already been used in a conversation are highlighted + gray. Unused keywords are highlighted magenta. The engine "remembers" used + keywords until the next time the game is loaded. In other words, it does not + save this info as part of the session save file. + + * worlds/haxima-1.002/gregor.scm: + Removed colorizing markup now that keywords can be automatically highlighted + + * src/kern.c, src/object.c, src/object.h, src/character.cpp, src/cmd.c, src/conv.c, src/conv.h: + Conversation keyword highlighting + + * src/log.c: Added some brackets to an if + +2008-05-30 Gordon McNutt + + * worlds/haxima-1.002/demo.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/minimal-game.scm, worlds/haxima-1.002/minimal-start.scm, worlds/haxima-1.002/monsters.png, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/tutorial.scm: + Fixed main game to work with my recent changes + +2008-05-27 Gordon McNutt + + * worlds/haxima-1.002/sounds.scm, src/scheme-private.h, src/session.c, src/session.h, worlds/haxima-1.002/camping-map.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/minimal-game.scm, worlds/haxima-1.002/minimal-start.scm, worlds/haxima-1.002/quest-talk-to.scm, src/closure.c, src/kern.c: + Kernel changes: + o Moved the scm macros from kern.c to scheme-private.h for everyone to enjoy + o Removed some duplicate macros from closure.c + o Changed kern-add-hook to expect a symbol for the handler + o Added session_hook_id_to_str and session_str_to_hook_id + o session now saves the registered hook handlers (except for + new_game_start_hook, which needs to be a special case for now at least) + + Haxima changes: + o Had to update all the kern-add-hook calls to match the kernel changes + o Finally got my prototype quest offer to be persistent across sessions, + remove itself when accepted, and in general work the way I want it to. + +2008-05-26 Gordon McNutt + + * worlds/haxima-1.002/minimal-start.scm: + Experimental end-of-conv hook that will run multiple handlers; prototyping quest offers to run as handlers and remove themselves when accepted + + * worlds/haxima-1.002/tbl.scm: Added tbl-rm! and tbl-for-each-val + + * src/kern.c: + Added kern-define, for preserving scheme variables across sessions + +2008-05-25 Gordon McNutt + + * src/kern.c: Fixed a crasher in the new unpack_rect fx + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/minimal-game.scm, worlds/haxima-1.002/minimal-start.scm, src/closure.c, src/closure.h, src/gob.c, src/kern.c, src/session.c, src/session.h, src/session_hooks.h, src/session_queries.h, worlds/haxima-1.002/demo.scm, src/Makefile.am, src/character.cpp: + Kernel changes: + o Split session hooks and queries up into separate tables. + o Hooks can have multiple handlers. Running the hooks does not return a value. + o Queries only have one handler and return an int. + + Haxima changes: + o Fixed the query registration as per the kernel changes. + o Random experimental stuff in minimal-*.scm + + * worlds/haxima-1.002/enchanter.scm: Spelling fix + +2008-05-23 Gordon McNutt + + * worlds/haxima-1.002/minimal-game.scm, worlds/haxima-1.002/minimal-start.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/quest-talk-to.scm, worlds/haxima-1.002/tbl.scm, worlds/haxima-1.002/ztats-quest-ui.scm, src/conv.c, src/session_hooks.h: + Kernel changes: + o Added conv_end_hook + + Haxima changes: + o Re-implemented player gob in minimal game as a table. + o Changed quest stuff accordingly + +2008-05-21 Gordon McNutt + + * worlds/haxima-1.002/quest-talk-to.scm, worlds/haxima-1.002/minimal-start.scm, worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/minimal-game.scm: + Haxima changes: + o Added a simplified talk-to quest which just awards xp when complete. + + * worlds/haxima-1.002/minimal-game.scm, worlds/haxima-1.002/minimal-start.scm, worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/quest-talk-to.scm: + Haxima changes: + o Had to change the quest ctor to require symbols instead of raw + procedures. This was necessary to support saving quests as part of the + object's gob (closures can't be saved). + o Added a proc for the conv_start_hook + o Talk-to quests can now be completed. + +2008-05-20 Gordon McNutt + + * worlds/haxima-1.002/ztats-quest-ui.scm, worlds/haxima-1.002/minimal-start.scm, worlds/haxima-1.002/sounds.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/tutorial.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/minimal-game.scm, worlds/haxima-1.002/camping-map.scm, worlds/haxima-1.002/demo.scm, src/session.h, src/session_hooks.h, src/menus.c, src/play.c, src/session.c, src/conv.c, src/kern.c, src/character.cpp, src/closure.c, src/closure.h, src/combat.c, src/Makefile.am: + Kernel changes: + o Consolidated all of our ad-hoc session hook procedures (camping, start game, + change music, query combat attributes, etc) into one table. This means they + can re-use the same code to load, run and clean them up, instead of having to + cut-and-paste them. There's also a new session_hooks.h file where all of the + hooks need only be declared once. After adding your hook there, you just need + to write the code to call it from someplace in the kernel source (a one-line + change). + o Added a conv_start_hook (for talk-to quests). + + Haxima changes: + o Replaced all the new-obsolete kern calls with kern-add-hook. + + Note: the changed kern calls are not ones needed by saved games, only by the + new game startup scripts, so this should not break save-game compatibility. + +2008-05-19 Gordon McNutt + + * worlds/haxima-1.002/minimal-game.scm, worlds/haxima-1.002/minimal-start.scm: + Adding a very simple but fast-loading game for development and test + +2008-05-18 Gordon McNutt + + * src/kern.c, worlds/haxima-1.002/ztats-quest-ui.scm: + Exported ASCII_H to the script as kern-ascii-h + + * src/quest.h, src/Makefile.am, src/quest.c: + Removed old prototype quest stuff + + * worlds/haxima-1.002/ztats-quest-ui.scm, src/applet.h, src/kern.c, src/ztats.c: + Kernel changes: + o Changed kern-event-push/pop-keyhandler to kern-event-run-keyhandler + o Removed the unused "stop" operation from the applet struct + o Added kern-screen-erase and kern-screen-update + + Haxima changes: + o Added quest viewer applet for individual quest details + + * src/ztats.h, worlds/haxima-1.002/ztats-quest-ui.scm, src/status.h, src/ztats.c, src/macros.h, src/status.c, src/cmd.c, src/kern.c, src/applet.h, src/Makefile.am: + Kernel changes: + o Added an applet struct + o Added statusRunApplet and statusGetCurrentApplet + o Added a "select" operation to the ztats panes + o Converted the ztats UI to run as an applet + + Haxima changes: + o Modified quest log ui to implement a nop "select" proc + +2008-05-17 Gordon McNutt + + * src/cmd.c, src/event.c, src/event.h, src/kern.c, src/status.c, src/ztats.c, src/ztats_pane.h: + Kernel changes: + o eventPopKeyHandler now returns the keyhandler that was popped + o added kern-event-push-keyhandler + o added kern-event-pop-keyhandler + o added a 'select' operation to the ztats_pane + o added eventRunKeyHandler to manage all the boilerplate of + pushing/running/popping key handlers + + * src/event.h, src/kern.c, src/event.c: + Fix for bug [ 1734069 ] pathfinder confused by diagonal gaps. The pathfinder + was written so that if the character could get one tile away from the + destination then this was good enough. This is ok for for combat pathfinding + and following the leader; but for commuting it's not ok when the last step is + impassable, because the character needs to actually get there or it will keep + trying to commute over and over. I added a new pathfinding flag to indicate + that "adjacent is NOT ok", and set this flag for commuting. + +2008-05-16 Gordon McNutt + + * worlds/haxima-1.002/ztats-quest-ui.scm: + Got the quest log listing pane to scroll properly + + * worlds/haxima-1.002/game.scm: Added scroll directions + + * worlds/haxima-1.002/naz.scm: Added some rect and incr/decr utilities + + * src/status.h: + Ensure enum (which must be in synch with script) starts at zero + +2008-05-15 Gordon McNutt + + * worlds/haxima-1.002/ztats-quest-ui.scm, src/kern.c: + kernel passes ztats ui dimension rect as a list back to scheme; added kern-screen-shade + + * worlds/haxima-1.002/quest-sys.scm, worlds/haxima-1.002/quest-talk-to.scm, worlds/haxima-1.002/ztats-quest-ui.scm, src/kern.c: + Kernel changes: + o kern-screen-print expects the rect arg to be a list now + + Script changes: + o ztats-quest-ui.scm was + ...updated to match kern-screen-print + ...modified to print all the quests attached to the party + o quest-sys.scm prints a console msg when a quest is assigned + + * worlds/haxima-1.002/naz.scm: + Added two new utilities: repeat and string-lower + + * worlds/haxima-1.002/game.scm: Load the quest files + + * src/kern.c: + kern-obj-get-place returns NIL if the object has a NULL place + + * worlds/haxima-1.002/ztats-quest-ui.scm: + Display a little bit about current quests + + * worlds/haxima-1.002/quest-talk-to.scm: Added basic talk-to quest type + + * worlds/haxima-1.002/quest-sys.scm: Added basic quest type + + * worlds/haxima-1.002/sounds.scm: + Changed music-on-combat-change to check for a null location (fixes a crashed when we start the game on the world map) + + * worlds/haxima-1.002/naz.scm: + Added some more utilities, and changed player-member-loc to check for a null location + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/ztats-quest-ui.scm: + Added ztats-quest-ui.scm, which implements a stub for a quest log ztats pane. + + * src/kern.c: + Added kern-ztats-add-pane, kern-ztats-set-title and kern-screen-print. + + * src/gob.c: Just a todo comment + +2008-05-14 Gordon McNutt + + * src/ztats_spells.h, src/ztats_reagents.c, src/ztats_reagents.h, src/ztats_spells.c, src/ztats_pm.h, src/ztats_pm.c, src/ztats_misc.h, src/ztats_pane.c, src/ztats_pane.h, src/ztats_items.c, src/ztats_items.h, src/ztats_misc.c, src/ztats_container_pane.h, src/ztats_container_pane.c, src/ztats_arms.c, src/ztats_arms.h, src/ztats.h, src/ztats.c, src/quest.h, src/status.c, src/status.h, src/player.h, src/quest.c, src/kern.c, src/player.cpp, src/Makefile.am, src/Party.cpp, src/Party.h: + Rewrote ztats UI. + + * src/sound.h: + Fixed a c++ name-mangling compile error that cropped up out of the blue + + * src/sound.c: Fixed what looks like an = vs == bug + + * src/combat.c: Removed some dead code + +2008-05-10 Gordon McNutt + + * configure.ac, worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/music/Makefile.am: + Andreas Bauer's fix for the music installation + +2008-04-06 kaypy + + * worlds/haxima-1.002/mouse.scm: + fix for 1934040- kat/thud will no longer talk after betraying you. + +2008-03-17 kaypy + + * worlds/haxima-1.002/voidgap-passage.scm: + fix for 1916322- the voidgap dungeon setup wrote some garbage over the endless deepness setup + +2008-03-02 kaypy + + * src/menus.c, src/nazghul.c, src/play.c, src/sound.c, src/sound.h: + music-volume setting (unfortunately doesnt work on midi!) + better handling of music loading errors + + * src/menus.c: Added music credits to title page + +2008-03-01 kaypy + + * worlds/haxima-1.002/void-temple.scm, worlds/haxima-1.002/voidgap-passage.scm, worlds/haxima-1.002/westpass.scm, worlds/haxima-1.002/abandoned-cellar.scm, worlds/haxima-1.002/abandoned-farm.scm, worlds/haxima-1.002/absalot.scm, worlds/haxima-1.002/altar-room.scm, worlds/haxima-1.002/ancient-derelict.scm, worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/ankh-shrine.scm, worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/combat-maps.scm, worlds/haxima-1.002/crypt.scm, worlds/haxima-1.002/dank-cave.scm, worlds/haxima-1.002/eastpass.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/forsaken-prison.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/kun.scm, worlds/haxima-1.002/lich-tomb.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/mans-hideout.scm, worlds/haxima-1.002/merciful-death.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/mushroom-cave.scm, worlds/haxima-1.002/necromancers-lair.scm, worlds/haxima-1.002/old-absalot.scm, worlds/haxima-1.002/old-mine.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/poor-house.scm, worlds/haxima-1.002/prison.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/thiefs_den.scm, worlds/haxima-1.002/traps_1.scm, worlds/haxima-1.002/traps_2.scm, worlds/haxima-1.002/traps_3.scm, worlds/haxima-1.002/traps_4.scm, worlds/haxima-1.002/treasury.scm, worlds/haxima-1.002/trigrave.scm: + Add music data to all the places + + * worlds/haxima-1.002/game.scm: Init music hooks + + * worlds/haxima-1.002/pseudorandom-map.scm: + Music compatible random maps content freezing + + * worlds/haxima-1.002/statue-of-justice.scm: Typo in text + + * worlds/haxima-1.002/gamestart-statues.scm: Fixed spelling + Statues respond to abbreviated stat names + + * worlds/haxima-1.002/naz.scm: + Method to retrieve location of player party members (which occasionally differs from the location of the player party) + + * worlds/haxima-1.002/sounds.scm: + Utility methods for tracking music in and out of combat (+ transitions) for different places + + * worlds/haxima-1.002/music/wind-trio.mid, worlds/haxima-1.002/music/Lute-and-recorder-ballad.mid, worlds/haxima-1.002/music/Minuet-like-Mozart.mid, worlds/haxima-1.002/music/ballad.mid, worlds/haxima-1.002/music/bassoons-and-harpsichord.mid, worlds/haxima-1.002/music/credits.txt, worlds/haxima-1.002/music/double-trios.mid, worlds/haxima-1.002/music/dragon-quest.mid, worlds/haxima-1.002/music/dragon-slayer.mid, worlds/haxima-1.002/music/fair-camelot.mid, worlds/haxima-1.002/music/game-music2.mid, worlds/haxima-1.002/music/harpsichord-piece.mid, worlds/haxima-1.002/music/into-battle.mid, worlds/haxima-1.002/music/medieval-quest.mid, worlds/haxima-1.002/music/minstrel-dance.mid, worlds/haxima-1.002/music/music.scm, worlds/haxima-1.002/music/plainchant-recorder-trio.mid: + Added Jim Paterson's midi music (the zip on the ftp site says we have permission) + + * src/kern.c, src/session.c, src/session.h: + Hooks for game start and for changes in combat state + + * src/combat.c: + Entering combat map sets combat state _after_ participants are positioned (helps with combat state change hook) + +2008-02-23 kaypy + + * src/character.cpp, src/combat.c, src/place.c: + Combat.state is more proactive abour tracking changes + + * src/sound.c: + accepts a full path, so you can point it at your local mp3s if you want + +2008-02-21 kaypy + + * worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/sounds.scm, src/sound.c, src/sound.h, src/kern.c, src/play.c, src/session.c, src/session.h: + First pass at shuffle play music + + * src/sound.c: + Music seems to work, for sufficiently hacky values of 'work' + +2008-02-04 kaypy + + * worlds/haxima-1.002/gamestart-mech.scm, worlds/haxima-1.002/gamestart-statues.scm, worlds/haxima-1.002/gamestart.scm: + working statue char creation + + * worlds/haxima-1.002/start-new-game.scm: initial stats tweaked + +2008-02-03 kaypy + + * worlds/haxima-1.002/bigobjects.png, worlds/haxima-1.002/gamestart-mech.scm, worlds/haxima-1.002/gamestart-statues.scm, worlds/haxima-1.002/gamestart.scm, worlds/haxima-1.002/sprites.scm: + First pass at statue/conversation based character generation + Not yet functional + + * worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/sfx.png: + Added acid fields (I just needed something yellow, really) + +2008-01-13 Gordon McNutt + + * src/session.c: Fixed a 3k leak that happened on quit + +2008-01-12 Gordon McNutt + + * src/play.c: + Bugfix: reloading a game with a start-proc would not run the start-proc, which might result in a crash + +2007-12-30 kaypy + + * src/sound.c: more paranoid memory handling + removed music for the moment + +2007-12-10 Gordon McNutt + + * src/cmd.c, src/status.c, src/status.h: + y)use ui now scrolls like everything else + +2007-12-09 sglasby + + * worlds/haxima-1.002/kern-init.scm: + Added a new config value for the progress bar image file. + + * src/foogod.c: Changed foogod_load_progress_bar_sprites() to load + a distinct file, rather than load the image from an + inline XPM. + + (A rather strange problem, perhaps associated with + an oddly-build RPM of SDL_image came up for OpenSUSE, + so it seems better to use a PNG.) + + * worlds/haxima-1.002/progress_bar_image.png: + The progress bar sprite pieces, as a PNG file. + (There was a problem under at least one compilation environment, + with loading this image as an inline XPM.) + + * worlds/haxima-1.002/tetzl.scm, worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/thorald.scm, worlds/haxima-1.002/thud.scm, worlds/haxima-1.002/tim.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/valus.scm, worlds/haxima-1.002/warritrix.scm, worlds/haxima-1.002/zane.scm: + Added various comments. + + * worlds/haxima-1.002/silas.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/steward.scm: + Added some comments. + +2007-12-08 Gordon McNutt + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/statue-of-justice.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/valus.scm: + Added asides for Ini + + * src/kern.c: Oops. status.c doesn't like NULL containers. + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + Pickpocket can fail (with consequences) + + * worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/statue-of-justice.scm, src/cmd.c, src/kern.c, src/status.c, src/status.h: + kern-ui-select-item now takes a kchar arg and browses *their* inventory, instead of being hardcoded to the player. The pickpocket skill exploits this. + + * src/terrain.c: Performance tweak for looking up terrains in palettes + + * configure.ac: Sam's changes to configure.ac for SDL_Mixer + +2007-12-07 Gordon McNutt + + * worlds/haxima-1.002/skills.scm: + Oops. Didn't see the multiplier on my last. Also added basic pickpocket skill. + + * worlds/haxima-1.002/skills.scm: Skills use the base-skill-ap variable + + * worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/tools.png: + Shiny new chest sprites + + * worlds/library/artwork/furniture/chest.xcf: Art for new chest sprites + + * worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/keys.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + Locked and magically locked chests with some ugly sprites for same. + +2007-12-06 Gordon McNutt + + * worlds/haxima-1.002/statue-of-justice.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/effects.png, worlds/haxima-1.002/effects.scm: + Finished the 'curse of unrest' effect. The SOJ in glasdrin uses it. + + * src/kern.c: NPC party ambush direction was not random + + * src/combat.c: + Introducing a party into combat that did not come from the world map (or someplace) caused a crash + + * src/Being.cpp: Turned off some debug + +2007-12-05 sglasby + + * worlds/haxima-1.002/selene.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/patch.scm: + Added some comments. + + * worlds/haxima-1.002/oscar.scm: Corrected some comments. + + * worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/may.scm: + Various comments regarding description and location, etc. + +2007-12-05 Gordon McNutt + + * src/ascii.c, src/images.c, src/images.h, src/screen.c, src/screen.h, src/sprite.c: + Eero's 16-bit patch + + * src/status.c: Tab cleanup and removed a dead function + + * src/Makefile.am, src/map.c, src/menus.c, src/play.c, src/cmd.c, src/ctrl.c, src/nazghul.c, src/nazghul.h: + Eero's cleanup patch + + * src/nazghul.h: + file nazghul.h was added on branch release_0_6_0_rc2_maint on 2008-11-08 04:30:15 +0000 + + * src/combat.c: Turned off some debug + + * src/screen_dims.h: + Eero's patch for n800 screen size (kern-init.scm already patched) + +2007-12-04 Gordon McNutt + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/statue-of-justice.scm: + A start on the statue curses + + * src/foogod.c: + Show extra effects on the party (currently unused, see Party::addEffect for why) + + * src/kern.c: kern-char-set-sched + +2007-12-03 kaypy + + * worlds/haxima-1.002/scrolls.scm: + feature 1843033 scrolls explicitly labelled + + * worlds/haxima-1.002/scrolls.scm: + fix for 1843001 scrolls fail in wilderness combat + +2007-12-03 Gordon McNutt + + * worlds/haxima-1.002/statue-of-justice.scm, worlds/haxima-1.002/valus.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/prison.scm: + Replacement for the Stewardess + + * worlds/haxima-1.002/shroom.scm: Minor conv fix + +2007-12-01 Gordon McNutt + + * worlds/haxima-1.002/zones.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/janice.scm, worlds/haxima-1.002/jeffreys.scm: + Replacement for Jeffries. + + * worlds/haxima-1.002/conv.scm: Tweaked generic glasdrin reply to JEFF + + * worlds/haxima-1.002/jeffreys.scm: + Jeffries becomes a vagabond in Kun after the trial + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/steward.scm: + Oops. Broke some things on my last commit. Also, updated generic glasdrin conv. + + * worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/player.scm, worlds/haxima-1.002/statue-of-justice.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/warritrix.scm: + Added another player flag for the trial of glasdrin being over. + +2007-11-29 Gordon McNutt + + * worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/species.scm: + Implemented butchering as an example crafting skill. You'll need a deer. Currently these aren't autogenerated anywhere. + + * src/ctrl.c: Turned on y)use + + * worlds/haxima-1.002/occs.scm: + Added preliminary crafting ability to occs + + * worlds/haxima-1.002/occs.scm: + Fixed what looks like a bug in dexterity defense + + * worlds/haxima-1.002/kern-init.scm: + Added 880x640 splash from Eero's 16bit patch + + * worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/player.scm: + Jeffreys and Stewardess act guilty after player finds Warritrix + + * worlds/haxima-1.002/zones.scm: Bug in holy grail table settings + +2007-11-28 Gordon McNutt + + * worlds/haxima-1.002/start-new-game.scm: + Removed redefinitions of stuff in player.scm + + * worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/warritrix.scm: + Added a gob for the player party. + + * src/player.cpp: Player party object now saves its gob + +2007-11-27 Gordon McNutt + + * src/foogod.c: Improved progress bar sprite + + * worlds/haxima-1.002/newterrain.png: Put the SOJ on a pedastal + + * src/object.c, src/status.c: + Fixing a bug I found by accidentally reloading a new game. Normally this is not possible, I had a weird case. It still doesn't work do to that, there are more bugs. + + * worlds/haxima-1.002/newterrain.png: + Should have checked in the new image with the new statue sprite + + * worlds/haxima-1.002/statue-of-justice.scm: Fixed a typo in the xamine + + * worlds/haxima-1.002/game.scm: + Fixed the dtable problem I created last time I committed this file + + * worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/statue-of-justice.scm: + Changed SOJ's sprite + + * worlds/library/artwork/terrain/headless_statue_with_sword.xcf: + New statue sprite + + * worlds/haxima-1.002/game.scm: + This should have gone in with my last batch of glasdrin changes + +2007-11-26 kaypy + + * worlds/haxima-1.002/luximene.scm: correction to schedule comment + + * worlds/haxima-1.002/naz.scm: + pick-loc checks for valid target locations + + * worlds/haxima-1.002/books.scm: some typos in journal + + * worlds/haxima-1.002/necromancer.scm: + fix for 1838195- necromancer now checks you have the skull + +2007-11-26 Gordon McNutt + + * worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/warritrix.scm: + Fixed up some conversation bits + + * worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/warritrix.scm: + Trading names between the MAN and the Warritrix. + + * worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/statue-of-justice.scm, worlds/haxima-1.002/steward.scm: + The SOJ now exiles the player if he accuses without evidence + +2007-11-25 Gordon McNutt + + * worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/statue-of-justice.scm: + Stewardess now punished when convicted. The townsfolk of glasdrin are now all armed. + + * worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/statue-of-justice.scm, worlds/haxima-1.002/steward.scm: + The status of justice in glasdrin will now hold a trial + + * src/cmd.c, src/cmd.h, src/kern.c: Added kern-ui-select-item + + * src/Being.cpp: + If an NPC is using a cached path, and the next step is occupied, it discards the cached path so it will recompute next time + + * src/status.c: Renamed a function + +2007-11-24 Gordon McNutt + + * worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/statue-of-justice.scm, worlds/haxima-1.002/terrains.scm: + Added statue of justice (doesn't do much yet) + +2007-11-23 Gordon McNutt + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/glasdrin.scm: + Added Stewardess's Journal + +2007-11-21 Gordon McNutt + + * src/foogod.c: Made the progress bar purty. + + * src/foogod.c, src/session.c: + The progress bar code generated in the save files is now a pretty good match to actual load times. Not perfect, but probably good enough. + + * worlds/haxima-1.002/tutorial.scm: Added progress bar to tutorial + +2007-11-20 Gordon McNutt + + * worlds/haxima-1.002/start-new-game.scm: + Progress bar now pretty good for start-new-game + + * worlds/haxima-1.002/game.scm: + Pulled progress bar stuff out of generic file + + * src/menus.c, src/play.c, src/session.c, src/session.h, src/kern.c, src/foogod.c: + Game-saving code generates (imperfect) progress bar info; delay switching foogod window back to normal so the complete progress bar is visible for a little bit of time + + * worlds/haxima-1.002/books.scm: Fixed mismatched parenthesis + +2007-11-20 kaypy + + * worlds/haxima-1.002/arms.scm: projectile weapons use missile sound + + * worlds/haxima-1.002/ifc.scm, src/object.h, src/object.c, src/ctrl.c: + callback on weapon just before attack + +2007-11-20 sglasby + + * worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/luximene.scm: + Checking references to places and such. + + Added notes on who and where the various characters are. + + * worlds/haxima-1.002/kalcifax.scm: + Added some notes on who and where Kalcifax is. + + * worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/gen.scm: + Added some notes to Kama on who and where he is. + + Added some detail to a cultural interest shared by Gen and Kama. + + * worlds/haxima-1.002/books.scm: + Added a book related to an interest of Gen's. + +2007-11-20 Gordon McNutt + + * worlds/haxima-1.002/demo.scm: progress bar for demo + + * worlds/haxima-1.002/game.scm: + Use progress bar (weakly; works ok for demo but not calibrated right for new or loaded games + + * src/status.c, src/nazghul.c, src/foogod.c, src/foogod.h, src/kern.c: + Progress bar + +2007-11-19 sglasby + + * worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/joel.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/jeffreys.scm: + Checking place references and such. + Added notes regarding the who and where NPCs are / are at. + + * worlds/haxima-1.002/ghertie.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/henry.scm: + Checking for consistency in place references and such. + Added some comments regarding the what and where that NPCs are / are at. + + * worlds/haxima-1.002/gen.scm: + Added some missing responses for Goblin root words. + Added a few composite words related to character types, + and to make the ability to get Gen to join less subtle. + Grouped/organized some keywords to keep the Goblin language responses together. + + Added notes regarding the type and location of Gen. + +2007-11-18 sglasby + + * worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/fing.scm: + Checking location references and such. + Removed some duplicate definitions of a constant + for Trigrave inn prices. + Added comments for NPCs type and location. + + * worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/dennis.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/edward.scm: + Checking references to places and such. + Adding suitable comments as to + what (species, gender, profession) an NPC is, + and where (what zone) they are at. + Removed some duplicate instances of a trigrave inn price constant. + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/abigail.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/anne.scm: + Double-checking place references and such, + added comments where needed in regards to + what (species, gender, profession) is + and where (what zone) the NPC may be found. + +2007-11-18 kaypy + + * worlds/haxima-1.002/ability.scm: npcs use same cone attack as PCs + + * worlds/haxima-1.002/powers.scm: + cleaned up, debugged and enhanced cone attacks + + * worlds/haxima-1.002/fireblast.wav, worlds/haxima-1.002/sounds.scm: + fireblast sound for cone spells + +2007-11-18 Gordon McNutt + + * worlds/haxima-1.002/demon-gate.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/talking-ankh.scm, worlds/haxima-1.002/ankh-shrine.scm: + Changed the end-game map to match the demo map + +2007-11-18 kaypy + + * worlds/haxima-1.002/demo.scm: one word: oops + + * worlds/haxima-1.002/demo.scm: passive-ai no longer includes std-ai: + the beggar was moving off when hit by stray fields + + * worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/ability.scm: + collateral check for lightning bolt + + * worlds/haxima-1.002/powers.scm: + various bugs in collateral damage routine fixed + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/powers.scm: + collateral check added to fireball + +2007-11-18 Gordon McNutt + + * worlds/haxima-1.002/demo.scm: + Final (famous last words) changes to the demo maps. Just undid Kris's blending, probably. + + * worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/terrains.scm: + Added a non-los blocking version of t_trees + +2007-11-18 kaypy + + * worlds/haxima-1.002/demo.scm: blended aging terrains + + * worlds/haxima-1.002/demo.scm: ai tweaks + deer in 'ages passed' + sound effect for closing gate + display refreshes & pauses when npcs are added + + * worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/sprite-sets.scm: + deer sprite + +2007-11-17 Gordon McNutt + + * worlds/haxima-1.002/demo.scm: More aging of the demo scene. + + * worlds/haxima-1.002/demo.scm: + Started the accelerated aging process on the demo scene + + * worlds/haxima-1.002/demo.scm: + Demo: sprites animate during pauses; player gets a chance to see that the altars are glowing, not the runes + + * worlds/haxima-1.002/ability.scm: + NPC wizards may now cast flame wind and lightning. Watch out. + + * worlds/haxima-1.002/powers.scm: + Renamed a parameter to make it clear that it is a LOCATION and not a kernel object + + * src/kern.c: Fixed a debug statement + + * worlds/haxima-1.002/demo.scm: + Added some special effects to the part where the wise close the gate + +2007-11-17 kaypy + + * worlds/haxima-1.002/creatures.png, worlds/library/artwork/creatures/deer.xcf: + first pass at a deer + +2007-11-17 Gordon McNutt + + * worlds/haxima-1.002/demo.scm: Changes to demo scene: + o The sprites of the wise are non-random + o Added random traveler sprites, depending on profession + o Sparsed the travelers even more + o Repaint the screen for each loot item the beggar picks up + +2007-11-17 kaypy + + * src/character.cpp, src/character.h: + character uses object sprites, rather than having a second local sprite + + * worlds/haxima-1.002/demo.scm: more line end problems + beggar is more indestructable + beggar cleans up loot and exits + + * worlds/haxima-1.002/demo.scm: + reinforcements wander around for a bit instead of immediately exitting + + * worlds/haxima-1.002/demo.scm: guards exit after the wise leave + + * worlds/haxima-1.002/demo.scm: tweaked traveler ratios + wise have variety of appearances + human reinforcements appear in more timely fashion + runes are collected asynchronously + map tweaked + + * worlds/haxima-1.002/demo.scm: fixeed line endings + +2007-11-17 Gordon McNutt + + * worlds/haxima-1.002/demo.scm: + Kris's improvements to the demo scene: another demon wave and reinforcements to repel them. + + * src/menus.c, worlds/haxima-1.002/demo.scm: + When the demo is done the main menu goes back to the splash screen. At that point the player can opt to show the demo again. + +2007-11-17 kaypy + + * worlds/haxima-1.002/powers.scm: clone spell more effective + sleep spell tweaked + +2007-11-17 Gordon McNutt + + * worlds/haxima-1.002/demon-gate.scm, src/kern.c: + Made kern-end-game more general by moving messages to the script + + * src/menus.c: + Demo only starts automatically the first time the main menu comes up after starting the program. After that the option to play it appears in the menu. + +2007-11-16 kaypy + + * worlds/haxima-1.002/lightning.wav, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/sounds.scm: + added lightning sound + fixed some bugs in field wall behaviour + + * worlds/haxima-1.002/demo.scm: uses altar-on-grass sprites + centers view nicely in reduced size mode + +2007-11-16 Gordon McNutt + + * scripts/blendmap.pl: Blender can handle 3-wide glyphs now + + * worlds/haxima-1.002/demo.scm: Blended the demo map. + + * src/kern.c, src/map.c, src/map.h: + Adding kern-map-blit-image, which isn't currently used anywhere, or planned to be used, but I already wrote and tested the code so might as well commit it. + + * worlds/haxima-1.002/demo.scm: More tweaks to the demo scene + + * worlds/haxima-1.002/effects.scm: + No more 'poison field immune to poison' messages + +2007-11-16 kaypy + + * src/ctrl.c, src/Being.cpp: + fix for 1822685- adds AP cost to handling mechs by bumping into them + +2007-11-16 Gordon McNutt + + * worlds/haxima-1.002/demo.scm, worlds/haxima-1.002/gold_frame.png, worlds/haxima-1.002/haximatext.png: + Added a frame around the demo scene + +2007-11-15 Gordon McNutt + + * worlds/haxima-1.002/demo.scm, worlds/haxima-1.002/haximatext.png: + Added the logo above the demo. Started tweaking the demo map. + +2007-11-15 kaypy + + * src/place.c: virtual cost of nasty tiles scaled to AP_per_turn + + * src/Being.cpp: + npcs reevaluate their options before crossing nasty tiles + + * worlds/haxima-1.002/sfx.png, worlds/haxima-1.002/sprites.scm: + transparent field sprites + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm: + remaining field spells use wall effect + + * worlds/haxima-1.002/moon.scm: + dimming the moons a trifle- night is awfully well lit + + * src/kern.c: mmode set if kern-mk-field-type + removed some debugging + +2007-11-14 kaypy + + * worlds/haxima-1.002/powers.scm: + field walls are 'solid', with extra diagonal blocking cells that cost 1/2 + + * worlds/library/artwork/logos/haximatext.svg: + vector form of the haxima text + + * worlds/library/artwork/logos/haximasplashbig.xcf, worlds/library/artwork/logos/haximasplashsmall.xcf: + layered versions of the splash screens + +2007-11-14 Gordon McNutt + + * worlds/haxima-1.002/demo.scm: + Demo scene script now runs to completion. + +2007-11-13 Gordon McNutt + + * worlds/haxima-1.002/demo.scm: + In the intro scene the wise now appear and walk to the altars + +2007-11-13 kaypy + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm: + in flam grav now uses first pass at wall style field spells + + * worlds/haxima-1.002/powers.scm: + most missile spells have sound applied + + * worlds/haxima-1.002/boom.wav, worlds/haxima-1.002/combat-maps.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/sounds.scm, worlds/haxima-1.002/swish.wav: + some more sound added: + swishes and bangs fo magical projectiles + a first pass at some changing music tracks (but I still dont have uploadable music tracks to change...) + +2007-11-13 Gordon McNutt + + * worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/demo.scm: + Pulled game.scm inline into demo.scm and trimmed it to speed up demo loading. + + * worlds/haxima-1.002/terrains.scm: + removed obsolete terrain-blender calls + + * src/kern.c: Added kern-log-flush + +2007-11-12 kaypy + + * win32/Makefile, win32/config.h, win32/configure, win32/haxima.ico, win32/readme.txt, win32/res.rc, win32/src_config.h: + First pass at including 'everything you need to make win32 builds go' + +2007-11-11 kaypy + + * src/sound.c: cleaning up old code + + * src/combat.c, src/combat.h, src/player.cpp, src/session.c: + fix for 1829927- reset combat state between games + + * worlds/haxima-1.002/sprites.scm: alters have cobblestone background + + * worlds/haxima-1.002/terrains.scm: altars have boulder passability + + * nazghul.nsi: 0.6.0 installer + + * worlds/haxima-1.002/sounds.scm, worlds/haxima-1.002/tools.scm, worlds/haxima-1.002/gong.wav: + clocks chime on the hour + + * src/kern.c, src/clock.c, src/clock.h: kern call to get clock ticks + +2007-11-10 Gordon McNutt + + * src/menus.c: Got rid of initial splash/demo flicker + + * worlds/haxima-1.002/kern-init.scm: + Turning on the demo scene. To turn off just comment out the relevant line in kern-init.scm. + + * worlds/haxima-1.002/demo.scm: Updated the demo scene a bit + + * src/menus.c, src/place.c: + Kernel support for running a demo in the map viewer while processing the main menu + + * src/session.h: Added a demo-mode flag to the session struct + + * src/map.c: Removed another old debug statement + + * src/kern.c: + Added kern-char-set-control-mode so that a player character may be forced into using an AI + + * src/common.c, src/character.cpp: Removing some old debug + +2007-11-10 kaypy + + * src/sound.c: Slight fade out when switching tracks + + * worlds/haxima-1.002/sounds.scm: + Will play background music if insertmusic.mid is added (or the file is tweaked to point elsewhere) + + * src/sound.h, src/kern.c, src/sound.c: First pass at music playing + + * src/place.c: Removed some debugging cruft + + * src/sound.c, src/sound.h: + Does most of the sound effects stuff again, but is rather buggy + +2007-11-09 kaypy + + * src/sound.c: Converting sound to SDL_Mixer + +2007-11-09 Gordon McNutt + + * worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/demo.scm: + Started on a demo scene for the main menu + + * worlds/haxima-1.002/silas.scm: Minor typographical change + +2007-11-08 kaypy + + * worlds/haxima-1.002/sounds.scm, worlds/haxima-1.002/tools.scm, worlds/haxima-1.002/enchanters-tower-mech.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/wind_1a.wav: + some tweaks to the sound + winds whistling through the brundegardt peaks + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/dog_9.wav: + tweaked ai to add sound effects as a 'free action'- + wolves will bark at random intervals + + * src/kern.c: kern api call for plaing a oneoff sound 'at a location' + + * src/sound.c: + minor tweak- maximum volume for oneoff sound completely separated from repeating volumes. + + * src/sound.c: + ambient sounds fade out nicely as the player moves away (it was a touch jerky previously) + + * worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/river.wav, worlds/haxima-1.002/sounds.scm: + general purpose "add some ambient noise here" object created + burbling river added to Gregors Hut as example + +2007-11-06 kaypy + + * worlds/haxima-1.002/ticktock.wav: a better clock sound + + * src/sound.c: + was not properly checking for repeated sounds- it only checked up to the first free slot. Now it checks all + + * worlds/haxima-1.002/sounds.scm, worlds/haxima-1.002/ticktock.wav, worlds/haxima-1.002/tools.scm: + first pass at a clock ticking. pity the wav sucks + + * src/kern.c, src/place.c, src/place.h, src/sound.c, src/sound.h: + first pass at ambient sound + + * src/sound.c: sound uses larger buffer to prevent glitches + +2007-11-04 kaypy + + * worlds/haxima-1.002/lost-halls.scm: Missing dungeon sprite + +2007-11-03 kaypy + + * AUTHORS: Update for 0.6.0 + + * ChangeLog: update for 0.6.0 + + * scripts/cvstochangelog.pl: + script to generate changelog from cvs log dump + +2007-11-02 Gordon McNutt + + * scripts/RELEASE_CHECKOFF: Added a few notes for clariication + +2007-11-02 kaypy + + * worlds/haxima-1.002/potions.scm: + some potions did not have right ap cost + + * NEWS: changes for 0.6.0 + +2007-11-02 Kris Parker + + * NEWS: + changes for 0.6.0 + + * worlds/haxima-1.002/potions.scm: + some potions did not have right ap cost + +2007-11-02 Gordon McNutt + + * scripts/RELEASE_CHECKOFF: + Added a few notes for clariication + +2007-11-01 Kris Parker + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/powers.scm: + a few area where treating an object as a character could cause crashes + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/start-new-game.scm: + added 'prisoner' faction, so that rolands captors dont try to kill him until he gets out + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/species.scm: + gints use their own mmode so that they are not considered to be flying + +2007-10-30 Kris Parker + + * worlds/haxima-1.002/demon-gate.scm: + demongate triggers off a slight delay rather than off the player's action + prevents the UI doing wackyness to Nos' conversation + + "You have opened the way, and served your purpose well. + Now, receive your reward... - ok!" + + * worlds/haxima-1.002/spells.png, worlds/haxima-1.002/spells.scm: + use smoke icon for bet ylem hur spell + +2007-10-30 Gordon McNutt + + * worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm: + Smoke bombs have their own sprite now + + * worlds/haxima-1.002/books.scm: + Added In Nox Por to the starter magic book. I don't see how one can make it through Brundegardt without it. + + * worlds/haxima-1.002/meaney.scm: + Meaney will heal any time (no shop hours) + + * worlds/haxima-1.002/moongate-clearing.scm: + Looks like t_spell_book_force_magick_123 doesn't exist anymore. + +2007-10-29 Kris Parker + + * src/combat.c: + previous patch had ... undesirable ... side effects + + * src/combat.c: + fix for 1821991: combat critters will be generated in substandard (eg hazardous) positions if nice positions are not available + + * src/magic.c: + adjusted magic objtype to spell routine to work with new spell names + +2007-10-29 Gordon McNutt + + * worlds/haxima-1.002/gregor.scm: + Removed a lot of the newlines from Gregor's conv. Sorry, but I have a very strong opinion about the way it looks. + +2007-10-28 Kris Parker + + * src/kern.c: + kern_place_is_visible was unreliable in temporary combat maps + + * worlds/haxima-1.002/moon.scm, worlds/haxima-1.002/start-new-game.scm: + moon positions reset, eclipse disabled + + * worlds/haxima-1.002/moons.png: + gave the moons a slight shadow, so you can see a difference between 'new moon' and 'moon is on the other side of the planet' + + * worlds/haxima-1.002/npc-types.scm: + fixed incorrect object type in accursed loot + + * worlds/haxima-1.002/powers.scm: + fix for 1815725: gem now centers view before scrying + + * worlds/haxima-1.002/shard.scm: + tweaked moongate destinations- the first gate you run across will take you to the enchanters tower + + * worlds/haxima-1.002/terrains.scm: + swamp terrain effect was broken + +2007-10-28 Gordon McNutt + + * worlds/haxima-1.002/kalcifax.scm: + Updated Kalcifax's conv to match the moongate change + +2007-10-27 Sam Glasby + + * worlds/haxima-1.002/abandoned-farm.scm: + Added a spellbook (curses), which belonged to Ilya's mother. + + * worlds/haxima-1.002/angriss-lair.scm: + Added two spellbooks to the meat locker + - Force magick (battle) + - White magick 2 + + * worlds/haxima-1.002/books.scm: + Added the rest of the currently-planned spellbooks. + Checked them in a saved game, may still need some + upcasing of spell runes and other minor tweaks. + + Next, it will be needful to place at least one copy of each + somewhere in the game. (And better yet, more than one + of at least the lesser / common ones.) + + * worlds/haxima-1.002/brundegardt.scm: + Added two of the new spellbooks in loot areas. + - The Divination spellbook, near the Eye + - The Deadly Winds spellbook, in the griffin nest. + + * worlds/haxima-1.002/enchanters-tower.scm: + Added various spellbooks to the treasuries and library. + The Enchanter has rather a lot of spellbooks, naturally. + + * worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/necromancers-lair.scm: + Missed arg 2 of some kern-mk-obj calls. + + * worlds/haxima-1.002/fire_sea.scm: + Added two spellbooks to the dragon hoard + - Misc enchantment + - Greater illusion + + Added a spellbook in the lava in the fire slime chamber + - Deadly Winds + + * worlds/haxima-1.002/game.scm: + Trivial formatting change, did not merge for some reason. + + * worlds/haxima-1.002/mans-hideout.scm: + Added two of the new spellbooks in the TOOLS room. + - The lesser illusions book + - The force magick / mechanisms book + + * worlds/haxima-1.002/necromancers-lair.scm: + Added various spellbooks to the library. + + * worlds/haxima-1.002/old-absalot.scm: + Added some suitable spellbooks to Silas's chest. + + * worlds/haxima-1.002/road_to_absalot.scm: + Added a spellbook in the Fire Bridge + - Force magick (matter) + + * worlds/haxima-1.002/thiefs_den.scm: + Added a few spellbooks (doubtless "collected") + to the thief's den. + - Lesser illusion + - Force magick (fields) + - Force magick (matter) + + * worlds/haxima-1.002/treasury.scm: + Added three spellbooks to the treasury. + - Force magick (high magick) + - Greater illusions + - Gates + +2007-10-27 Kris Parker + + * doc/users_guide.html: + updated spell list in manual + +2007-10-26 Sam Glasby + + * worlds/haxima-1.002/books.scm: + Added spellbooks for white magic, force magic, necromancy. + Various others planned, as per notes in: + ftp://ftp.haxima.org/other/dev_notes/spell_book_notes.txt + + These will need to be placed in the world in sensible places. + Note that the scheme for these books is such + that some books overlap, and contain some of the same spells, + this is purposeful, as they have themes. + + * worlds/haxima-1.002/spells.scm: + Spelling change for consistency. + +2007-10-26 Kris Parker + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + smoke spell + dispell magic spell + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + single target sleep spell + +2007-10-26 Gordon McNutt + + * src/ctrl.c: + Fixed a typo that caused some garbage in the cmdwin while attacking + + * worlds/haxima-1.002/arms.scm: + Smoke only drifts in wind on the surface combat maps + + * worlds/haxima-1.002/tim.scm: + Fixed grammar in Tim's conv + +2007-10-25 Sam Glasby + + * worlds/haxima-1.002/spells.scm: + The Vision spell was too high Circle + to be at all practical. + + The reagent costs (nightshade + mandrake) are 8..11 + 8..11 gold, + whereas you can buy a gem for 10..20 gold. + + It may be sensible to increase gem prices as well, + but lowering the Circle of this spell will at least + make this more accessible, and less costly in MP. + + * worlds/haxima-1.002/spells.scm: + Lined up the spell table again a bit, + and fixed a typo with Summon Slime. + + * worlds/haxima-1.002/spells.scm: + Changed spell names to include an English name, + as well as the spell runes. + (No point in being obscure, and many/most players + will not know the the entire list by heart, by runes alone.) + + Some formatting, lined up the spell table. + +2007-10-25 Gordon McNutt + + * src/character.cpp: + When party members in follow mode move, the map is marked dirty but not repainted. + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/powers.scm: + Fixed a bug in In Nox Por. Added some messages around poisoning. + +2007-10-24 Kris Parker + + * worlds/haxima-1.002/arms.scm: + reverting flaming oil to dropping fire field + + * worlds/haxima-1.002/powers.scm: + teleport range was borked by previous patch + +2007-10-24 Gordon McNutt + + * src/ctrl.c, src/event.c, src/skill.c, src/skill_set.c, src/skill_set_entry.c, src/templ.c: + Check config.h for HAVE_MALLOC_H + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/terrains.scm: + Reverted my forest visibility change (when Sam and Kris both agree I know I better listen). Added a forest terrain which is opaque, and fixed a couple of the town maps where I know opaque forest was presumed during the design. + +2007-10-23 Tim Douglas + + * src/skill.c, src/skill_set.c, src/skill_set_entry.c, src/templ.c: + check to see if malloc.h exists before including it -- fixes OSX build + +2007-10-23 Kris Parker + + * src/character.cpp: + save actual AP per turn rather than adjusted value + + * worlds/haxima-1.002/powers.scm: + telekinesis range was borked by previous patch + +2007-10-23 Gordon McNutt + + * worlds/haxima-1.002/game.scm: + Inflated the base AP values to reduce the armour penalty + + * worlds/haxima-1.002/start-new-game.scm: + Changed the moon starting positions and phases so that there is not an eclipse early in the first day and the player won't be given the opportunity to unwittingly teleport off to the Engineer's Hut on the first day. + + * worlds/haxima-1.002/terrains.scm: + Making the basic forest type opaque, because we still have some town-scale maps that rely on forest to conceal hidden things + +2007-10-22 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/lost-halls-mech.scm, worlds/haxima-1.002/voidgap-mech.scm: + commented out random dungeon checking feedback + + * worlds/haxima-1.002/powers.scm: + gave all powers a return code + +2007-10-22 Gordon McNutt + + * worlds/haxima-1.002/game.scm: + Reverted to one-move-per-turn (I think) + + * worlds/haxima-1.002/pseudorandom-map.scm: + Commented-out debug printlns + + * worlds/haxima-1.002/roland.scm: + Fixed Roland to work with pathfinding changes + +2007-10-21 Sam Glasby + + * src/cmd.c: + Improved cmd_save_current_place() + by using file_open_in_save_dir() rather than fopen(). + + * src/cmd.c, src/cmd.h, src/ctrl.c, src/event.h: + Added an edit-mode command CTRL-O which invokes + cmd_save_current_place(), terrain_map_save(). + + This is not finished yet, it lacks UI code to select a save file name. + (Currently saves to '_test_save_place' in the current directory.) + + * src/cmd.c: + Added some command help to the Terraform command. + + * src/cmd.c: + Changed the Terraform status text for the copy / set-pen command. + + Added a Terraform status text for the flood-fill command. + + * src/session.c, src/session.h: + Added a couple of prototypes to enable a save-single-thing + function to be defined elsewhere. + + Also, where does Session->indent get initialized? + It looks like we may be relying on the compiler initializing it to 0. + + * src/terrain_map.c: + Added some comments to the output of terrain_map_composite_save() + to aid manual editing of composite maps. + +2007-10-20 Sam Glasby + + * worlds/haxima-1.002/shard.scm: + Added some comments to aid manual editing of the shard map. + +2007-10-19 Kris Parker + + * worlds/haxima-1.002/conv.scm: + (aside) returns true if something is said, so you can stick a bunch of them in an (or) block + + * worlds/haxima-1.002/conv.scm: + (aside) was glitchy in the case of null or not present speakers + + * worlds/haxima-1.002/voidgap-mech.scm, worlds/haxima-1.002/voidgap-passage.scm: + fortified the dungeon entrance (its too close to town to be plausibly unguarded) + toned the dungeon down a fair bit + +2007-10-19 Gordon McNutt + + * src/character.cpp, src/kern.c, src/kern_intvar.c, src/object.c, src/object.h, src/place.c, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/tutorial.scm: + Improvements to kraken + + o Added a 'submerged' flag for objects + o Submerged object sprites are alpha-blended on the map + o Submerged objects get a bonus to defense (set by the script) + o Kraken submerge when coursing toward their target but surface to attack or + chomp + o Kraken will submerge and flee if they can't chomp their way to their target + +2007-10-18 Sam Glasby + + * worlds/haxima-1.002/luximene.scm: + Added responses for Luximene for the WISE and the ACCUrsed. + (The default responses presume a knowledge of + contemporary events, and did not fit.) + + * worlds/haxima-1.002/necromancer.scm: + Enhanced some of the Necromancer's responses + related to the main quest, including some synonyms. + + Added to the response for HEALTH. + +2007-10-18 Kris Parker + + * worlds/haxima-1.002/powers.scm: + blink range clamped + + * worlds/haxima-1.002/shard.scm: + world map rearranged to put void temple just out of teleport range of voidgap + + * worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/voidgap-mech.scm, worlds/haxima-1.002/voidgap-passage.scm: + added new random dungeon "Tunnels to Voidgap" + +2007-10-18 Gordon McNutt + + * src/character.cpp, src/cursor.cpp: + The camera follows the cursor or any player characters if they move off-screen + + * src/cmd.c: + The . key now means HERE when the player is prompted for a direction, like the 5 on the numeric keypad. + +2007-10-17 Sam Glasby + + * worlds/haxima-1.002/abe.scm: + Enhanced Abe's responses related to the RUNEs, + including a more explicit reference to RUNE + when speaking of the KEYs to the Demon Gate. + + * worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/mans-hideout.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/special.scm: + Updated all of the "hidden" places on the shard map + to match the angriss-lair implementation, + by which a step trigger is used to mark the location of + the once-hidden place when the player finds the exact location. + + * worlds/haxima-1.002/books.scm: + Minor formatting in the starting spellbooks. + Added some emphasis to the letter from the Enchanter. + + * worlds/haxima-1.002/gregor.scm: + Updated various responses. + Added some more synonyms. + Gregor gives clearer directions about how to reach the Enchanter. + Colorized many important keywords as RED, + and certain important non-keywords as GREEN. + + * worlds/haxima-1.002/the-man.scm: + Added a response about the Accursed. + Added a synonym for Rogue / Wrogue. + +2007-10-17 Gordon McNutt + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/game.scm: + Smoke now drifts in the wind + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/fields.scm: + Changes to smoke: + o Changed smoke from a field type to a regular object type + o Smoke now dissipates after a random interval + o Smoke is now at the projectile layer, so it is rendered over most other + objects (it is semi-transparent) + + * worlds/haxima-1.002/terrains.scm: + x)amine shows translation for runic signs (SF feature request) + +2007-10-16 Kris Parker + + * src/object.c: + disabling end of turn spam + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/powers.scm: + magic missile uses its own projectile rather than regular arrow + + * worlds/haxima-1.002/lost-halls-mech.scm: + Misplaced rock + + * worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/zane.scm: + typos + +2007-10-16 Gordon McNutt + + * src/Being.cpp, src/astar.c, src/astar.h, src/cmd.c, src/cmd.h, src/ctrl.c, src/event.c, src/event.h, src/kern.c, src/map.h, src/place.c, src/status.c, src/status.h, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/jim.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/moon.scm, worlds/haxima-1.002/moons.png, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/zane.scm: + Changes to the merchant system. + + o Saying 'buy' or 'sell' may jump directly to the buy and sell menus. + o Merchants now give a "sales pitch" on every item they sell. + o Merchants may give more feedback if the player does or does not buy anything. + + * src/kern.c: + Re-added kern-los-invalidate, but now it takes no args and just flushes all cached vmasks + + * src/object.c: + Fixed bug where LOS was still blocked when smoke evaporated + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/sprites.scm: + Added smoke bombs. + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + Changes to low and mid-level summoning spells + o Switched the order of In Bet Xen (now L2) and Kal Xen (now L5) + o In Bet Xen and Kal Xen each now summon different critters depending on the + caster's power + + * worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/tooth.scm: + A couple of merchants will trade in smoke bombs + + * worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/powers.scm: + We had two versions of terrain-ok-for-field. Removed one duplicate and fixed the remaining one to work if the location is off-map. + + * worlds/haxima-1.002/npc-types.scm: + Fixed a bug in loot drops (using var instead of tag) and added smoke bombs to wrogue loot. + +2007-10-13 Gordon McNutt + + * worlds/haxima-1.002/hackle.scm: + Tweaks to the Hackle/Mesmeme discussion + +2007-10-11 Kris Parker + + * src/kern.c: + added kern-missile-fire-to-max + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + lightning bolt spell added + + * worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/traps_4.scm: + slightly easier labyrinth of burning glass + + * worlds/haxima-1.002/spells.png, worlds/haxima-1.002/spells.scm: + lightning spell icon + +2007-10-11 Gordon McNutt + + * src/play.c: + Undoing a fix I did earlier. This supposed fix seems to cause a hang when the party exits from combat after a reload. I can't reproduce the original problem after undoing the fix. + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.png, worlds/haxima-1.002/spells.scm: + Implemented feature request 1622424, Vas An Nox + +2007-10-10 Gordon McNutt + + * src/map.c: + Lights outside the map view now cast light into the view. + + * src/scheme.c: + Bugfix: loaded files ending in a comment with no newline would cause the next valid line to be discarded + +2007-10-09 Kris Parker + + * src/object.c: + fading of movement sounds is linear rather than asymptotic + + * src/sound.c: + first step to better sound: sound does not replay if it is already being played + +2007-10-08 Sam Glasby + + * src/Arms.cpp, src/Arms.h, src/character.cpp, src/cmd.c, src/common.h, src/ctrl.c, src/kern.c, src/play.c, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/game.scm: + - There is some cleanup in game.scm (AP values not used and so forth) + which remains, some of these should be scrapped, and some will be useful as + guidelines for setting other values. + + + I rather imagine that further drafts will be needed + before the system is tuned in a satisfactory way. + + In the meantime, the AP-per-round and AP costs + in (game.scm arms.scm) should produce interesting results. + + I recommend experimentation with the AP values, + there are many possibilities... + + * src/status.c: + Various tweaks to status displays. + - Now shows range, AP cost, AP mod + - Ztats page contents reordered a bit. + +2007-10-08 Kris Parker + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/anne.scm, worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/edward.scm, worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/joel.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/trigrave.scm: + most npcs now have some sort of equipment + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/abigail.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/anne.scm, worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/dennis.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/edward.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/ghertie.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/joel.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/mesmeme.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/nate.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/nossifer.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/selene.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/silas.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/talking-ankh.scm, worlds/haxima-1.002/tetzl.scm, worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/thorald.scm, worlds/haxima-1.002/thud.scm, worlds/haxima-1.002/tim.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/tutorial.scm, worlds/haxima-1.002/warritrix.scm, worlds/haxima-1.002/zane.scm: + removed the 'armour based' speed values from individual characters, now that modifications based on actual armour can be used instead + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/game.scm: + centralized speed settings into 3 values in game.scm, with everything else normalized off those + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/spells.scm: + centralized speed settings into values in game.scm, with everything else normalized off those + +2007-10-07 Sam Glasby + + * src/Makefile.am, src/kern_intvar.c, src/kern_intvar.h: + Adding a facility for the script to store a hash of + "name" => integer + values, for the purpose of declaring policy via script + which otherwise might require hard-coded constants in common.h + or similar. + + The first use of this feature will be to replace the use of + the constant NAZGHUL_BASE_ACTION_POINTS, so that the Action Point + costs for various actions are entirely controlled by the script. + (Movement and attack AP costs are already in game.scm arms.scm, + but some half dozen actions require that the kernal know + some AP cost to use.) + + The API for kern_intvar is nearly identical to that + for cfg.c cfg.h, save that integers are stored. + + A seperate hash is used, as the data stored is of + a per-session nature, rather than a global-for-all-games config nature. + + This data is not currently saved, but a function + kern_intvar_save() is provided. + +2007-10-07 Kris Parker + + * src/combat.c, src/player.cpp, src/player.h: + party stops loitering when attacked in world map + + * src/player.cpp: + party loitering check moved after turn start. loitering in the wilderness was accumulating AP otherwise... + + * worlds/haxima-1.002/vehicles.scm: + onramps now cascade trigger to avoid appearance of 'half ramps' + +2007-10-07 Gordon McNutt + + * src/kern.c: + Workaround for bug 1808708: if the player is kamping on a ship, a pirate ambush will abort kamping and switch back to the wilderness view. + + * worlds/haxima-1.002/camping-map.scm, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/naz.scm: + Changed the script adjacency-checking to use diagonals. This fixes the problem I saw where pirates could not pathfind in the wilderness to ambush the player. That problem only occurred if the pirates ended up diagonal to the player. This would have affected other npc party types as well. + +2007-10-06 Kris Parker + + * src/Party.cpp, src/Party.h: + added command for a party to absorb its members ap debt + + * src/ctrl.c: + player party absorbs members ap debt as required + party AP is displayed in cmdwin prompt for now + + * src/ctrl.c, src/object.c, src/place.c: + moved bump ifc behaviour to ctrl, with the handle behaviour + fixed incorrect bump callback + + * src/player.cpp: + player gets diagonal movement costs + + * worlds/haxima-1.002/camping-map.scm: + camping checks for passability before allowing npc parties to attack + + * worlds/haxima-1.002/lost-halls-mech.scm, worlds/haxima-1.002/lost-halls.scm: + stairs portal based on bump rather than step + + * worlds/haxima-1.002/npc-types.scm: + quick'n'nasty 'add loot drops' by dint of tweaking the standard drops from stock npcs + + * worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/road_to_absalot.scm: + portal based on bump rather than step- can be used as virtual edge tile + + * worlds/haxima-1.002/tutorial_town.scm: + diagonal entrances + +2007-10-06 Gordon McNutt + + * src/combat.c: + Unlogged bugfix: pirate ship could end up on wrong side of map depending on whom was attacking whom + + * src/kern.c: + Fix for bug 1612006: pirates disembark before ambushing the campsite + + * src/macros.h: + Added normalize() macro + + * src/play.c: + Unlogged bugfix: assert in combat if you reload during combat and immediately camp. Needed to reset the combat state on reload. + + * worlds/haxima-1.002/camping-map.scm: + During camping, an ambushing npc party will now move toward the player. This way a pirate ambush will leave the ship next to the shore. + + * worlds/haxima-1.002/naz.scm: + can-pathfind? proc checks adjacency first; the kernel pathfinding code returns null in this case, which is not to be confused with being unable to produce a path + + * worlds/haxima-1.002/powers.scm: + Gate spell checks for passability + +2007-10-05 Kris Parker + + * src/player.cpp: + player party checks for diagonal movement between impassable terrains + + * src/player.cpp: + enable diagonal entrances to towns + + * worlds/haxima-1.002/absalot.scm, worlds/haxima-1.002/ancient-derelict.scm, worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/eastpass.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/kun.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/poor-house.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/tutorial_town.scm, worlds/haxima-1.002/void-temple.scm, worlds/haxima-1.002/westpass.scm: + diagonal entrances + + * worlds/haxima-1.002/arms.scm: + incorrect cannon projectile + + * worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + secret in natural rock + + * worlds/haxima-1.002/road_to_absalot.scm: + cleaned up natural rock walls + + * worlds/haxima-1.002/shard.scm: + deep water removed from near merciful death to prevent pirate ships from being spawned there + + * worlds/library/artwork/terrain/nrockwall.xcf: + hires natural rock wall terrains + +2007-10-04 Kris Parker + + * worlds/haxima-1.002/effects.scm: + fix for 1807516: logic error in conditional damage was only affecting non-beings + +2007-10-04 Gordon McNutt + + * src/Being.cpp, src/astar.c, src/character.cpp, src/place.c, src/place.h: + Fix for bug [ 1734069 ] pathfinder confused by diagonal gaps. The pathfinder + was written so that if the character could get one tile away from the + destination then this was good enough. This is ok for for combat pathfinding + and following the leader; but for commuting it's not ok when the last step is + impassable, because the character needs to actually get there or it will keep + trying to commute over and over. I added a new pathfinding flag to indicate + that "adjacent is NOT ok", and set this flag for commuting. + + * worlds/haxima-1.002/douglas.scm: + Douglas notices Mesmeme in the player's party + + * worlds/haxima-1.002/hackle.scm: + Hackle notices Mesmeme in the player party + + * worlds/haxima-1.002/kama.scm: + When kama joins it improves player relations with forest goblins + +2007-10-02 Kris Parker + + * worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/forsaken-prison.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/lost-halls-mech.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/mans-hideout.scm, worlds/haxima-1.002/mushroom-cave.scm, worlds/haxima-1.002/old-absalot.scm, worlds/haxima-1.002/old-mine.scm, worlds/haxima-1.002/prison.scm, worlds/haxima-1.002/road_to_absalot.scm: + natural rock + + * worlds/haxima-1.002/meaney.scm: + missing space in "come back during business hours" text + + * worlds/haxima-1.002/silas.scm: + fixed missing 'dennis' conversation element + +2007-10-02 Gordon McNutt + + * src/object.c, src/object.h, src/player.cpp, src/session.h, src/sprite.c, src/status.c: + Fix for bug 1632199 (An Tym animations). This breaks up the "synchronized + dancing" sprites and causes only player-controlled objects to be animated + during Time Stop. + +2007-09-22 Kris Parker + + * worlds/haxima-1.002/door.scm: + fix for 1800347 door LOS glitches + +2007-09-22 Gordon McNutt + + * src/kern.c, src/session.c, src/session.h, src/terrain.h: + Moved terrains to their own list on load; first step toward showing a terrain palette + +2007-09-20 Kris Parker + + * scripts/blenddat.txt, scripts/unblenddat.txt: + updated with newer terrains + + * scripts/mergemap.pl: + merge more resistant to formatting issues + + * scripts/palette.txt: + dense/light trees added + +2007-09-20 Gordon McNutt + + * worlds/haxima-1.002/necromancer.scm: + When meeting the Necromancer, if the Luximene quest has been offered but not + completed, then he checks if the player has the skull. + +2007-09-09 Kris Parker + + * worlds/haxima-1.002/ankh-shrine.scm, worlds/haxima-1.002/dank-cave.scm, worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm: + natural rock + + * worlds/haxima-1.002/newterrain.png: + some black areas added to natural rock terrain to make is not quite so jarring when it appears without proper edging + +2007-09-01 Kris Parker + + * worlds/haxima-1.002/brundegardt.scm: + natural rock + + * worlds/haxima-1.002/naz.scm: + misplaced bracket in evade was causing ai to jam + also re-allowed diagonal evasion + +2007-08-26 Kris Parker + + * worlds/haxima-1.002/ability.scm: + scale up ability ap costs + + * worlds/haxima-1.002/angriss-lair.scm: + natural rock in angriss' lair + + * worlds/haxima-1.002/arms.scm: + projectiles have at least obj-ifc. nil ifcs do bad stuff + + * worlds/haxima-1.002/powers.scm: + fix for 1781344 Crash on kill with VAS FLAM spell + +2007-08-19 Kris Parker + + * src/map.c: + support for weapons that always fire to max range + +2007-08-04 Kris Parker + + * worlds/template/kern-init.scm, worlds/template/start-new-game.scm, worlds/template/gfx/640x480_splash.png, worlds/template/gfx/addons.png, worlds/template/gfx/adornments.png, worlds/template/gfx/arms.png, worlds/template/gfx/bigobjects.png, worlds/template/gfx/bodies.png, worlds/template/gfx/books.png, worlds/template/gfx/cannon.wav, worlds/template/gfx/charset.png, worlds/template/gfx/clothes.png, worlds/template/gfx/cursor.png, worlds/template/gfx/damage.wav, worlds/template/gfx/effects.png, worlds/template/gfx/enter_moongate.wav, worlds/template/gfx/food.png, worlds/template/gfx/frame.png, worlds/template/gfx/hirespeople.png, worlds/template/gfx/horse.wav, worlds/template/gfx/humanoids.png, worlds/template/gfx/jewelry.png, worlds/template/gfx/map.png, worlds/template/gfx/money.png, worlds/template/gfx/monsters.png, worlds/template/gfx/moons.png, worlds/template/gfx/newfolkas.png, worlds/template/gfx/newfolks.png, worlds/template/gfx/newmonst.png, worlds/template/gfx/newterrain.png, worlds/template/gfx/occlogos.png, worlds/template/gfx/pitfalls.png, worlds/template/gfx/potions.png, worlds/template/gfx/reagents.png, worlds/template/gfx/rowing.wav, worlds/template/gfx/rune.png, worlds/template/gfx/runestones.png, worlds/template/gfx/scrolls.png, worlds/template/gfx/sfx.png, worlds/template/gfx/shapes.png, worlds/template/gfx/ship.png, worlds/template/gfx/signs.png, worlds/template/gfx/special.png, worlds/template/gfx/spells.png, worlds/template/gfx/splash.png, worlds/template/gfx/tools.png, worlds/template/gfx/tower.png, worlds/template/gfx/walk.wav, worlds/template/lib/ability.scm, worlds/template/lib/ai.scm, worlds/template/lib/arms.scm, worlds/template/lib/beds.scm, worlds/template/lib/bim.scm, worlds/template/lib/blendterrains.scm, worlds/template/lib/books.scm, worlds/template/lib/bridge.scm, worlds/template/lib/camping-map.scm, worlds/template/lib/cast-ui.scm, worlds/template/lib/combat-maps.scm, worlds/template/lib/containers.scm, worlds/template/lib/conv.scm, worlds/template/lib/door.scm, worlds/template/lib/drawbridge.scm, worlds/template/lib/edge-spawn.scm, worlds/template/lib/effects.scm, worlds/template/lib/fields.scm, worlds/template/lib/food.scm, worlds/template/lib/game.scm, worlds/template/lib/gate-guard.scm, worlds/template/lib/generic-mech.scm, worlds/template/lib/hidden.scm, worlds/template/lib/ifc.scm, worlds/template/lib/init.scm, worlds/template/lib/items.scm, worlds/template/lib/jewelry.scm, worlds/template/lib/keys.scm, worlds/template/lib/kobj.scm, worlds/template/lib/landslide.scm, worlds/template/lib/lever.scm, worlds/template/lib/loc.scm, worlds/template/lib/main-menu.scm, worlds/template/lib/mimic.scm, worlds/template/lib/money.scm, worlds/template/lib/monster-generator.scm, worlds/template/lib/moon.scm, worlds/template/lib/moongate.scm, worlds/template/lib/naz.scm, worlds/template/lib/npc-types.scm, worlds/template/lib/objs.scm, worlds/template/lib/occs.scm, worlds/template/lib/palette.scm, worlds/template/lib/parties.scm, worlds/template/lib/pitfalls.scm, worlds/template/lib/portals.scm, worlds/template/lib/portcullis.scm, worlds/template/lib/potions.scm, worlds/template/lib/powers.scm, worlds/template/lib/pre-entry-hooks.scm, worlds/template/lib/prices.scm, worlds/template/lib/pseudorandom-map.scm, worlds/template/lib/reagents.scm, worlds/template/lib/runes.scm, worlds/template/lib/scrolls.scm, worlds/template/lib/skills.scm, worlds/template/lib/sounds.scm, worlds/template/lib/special.scm, worlds/template/lib/species.scm, worlds/template/lib/spells.scm, worlds/template/lib/spider.scm, worlds/template/lib/sprite-sets.scm, worlds/template/lib/sprites.scm, worlds/template/lib/step.scm, worlds/template/lib/tblit.scm, worlds/template/lib/terrain-to-ptype.scm, worlds/template/lib/terrains.scm, worlds/template/lib/timer.scm, worlds/template/lib/tools.scm, worlds/template/lib/town-entry.scm, worlds/template/lib/traps.scm, worlds/template/lib/troll.scm, worlds/template/lib/vehicles.scm, worlds/template/lib/weather-vane.scm, worlds/template/lib/wind-bridge.scm, worlds/template/lib/yellow-slime.scm, worlds/template/people/sample-char.scm, worlds/template/places/sample.scm, worlds/template/places/world.scm, worlds/template/places/zones.scm: + First pass at a minimal template for new games + +2007-07-22 Kris Parker + + * src/Arms.cpp, src/Missile.cpp, src/Missile.h, src/kern.c, src/map.c, src/map.h: + Everything necessary for weapons that always fire to their maximum range, except for the map animation code, which is still disabled because it crashes if it goes off the map. + + * worlds/haxima-1.002/arms.scm: + compatibility with fixed range weapons option + +2007-07-16 Kris Parker + + * src/Arms.cpp, src/Arms.h, src/Missile.cpp, src/Missile.h, src/common.h, src/kern.c, worlds/haxima-1.002/arms.scm: + Separated out MissileType from ArmsType, since they have a close approximation of nothing in common. + + * src/Missile.cpp, src/Missile.h, src/map.c: + MissileTypes can now use the Enter ifc for custom handling of each tile they pass over + +2007-07-08 Kris Parker + + * src/status.c: + reformatted + + * src/status.c: + Reverting to a working version while I try to figure out a way to make it work AND do what we want + +2007-07-06 Kris Parker + + * src/Arms.cpp, src/Arms.h, src/kern.c, src/map.c: + support for beam projectiles + + * worlds/haxima-1.002/arms.scm: + stun wand uses beam attack + + * worlds/haxima-1.002/sfx.png, worlds/haxima-1.002/sprites.scm: + lightning bolt sprite + + * worlds/library/artwork/effects/heart.xcf, worlds/library/artwork/effects/lightning.xcf: + some sfx graphics + +2007-07-05 Kris Parker + + * src/kern.c: + new kern methods: + kern-place-is-combat-map + kern-obj-get-hp + + * worlds/haxima-1.002/ability.scm: + tweaked kraken deck chomp + + * worlds/haxima-1.002/sfx.png: + spikier hit sprites + +2007-07-03 Kris Parker + + * src/cmd.c, src/cmd.h, src/kern.c: + visibility based effects respect lighting levels + + * src/kern.c, src/map.c, src/map.h: + kern-map-flash-sprite: manually bring up a sprite flash (like the damage flash, but with an arbitary sprite) + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/powers.scm: + charm & turn undead spells use flash effect and visibility based reporting + + * worlds/haxima-1.002/powers.scm: + some glitches in turn undead fixed + + * worlds/haxima-1.002/sfx.png, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm: + a couple of sprites for flash sprite effects + + * worlds/haxima-1.002/species.scm: + ghosts are undead! + +2007-07-02 Kris Parker + + * src/kern.c: + kern-place-is-visible? checks for whether a location can be seen + + * worlds/haxima-1.002/naz.scm: + msg-log-visible displays a message if a given location is visible + +2007-07-01 Sam Glasby + + * src/status.c: + Fencepost error with tt not being refreshed after nn was updated, + could have led to painting one tile beyond the bottom bounds + of a Status window. + + * src/status.c: + Added support for Status entries with a height + other than 2 text lines (2 * ASCII_H). + + Reorganized the Arms stats (displayed in Ready, Ztats, etc) + and added information on Range and Action Points required. + + The new layout groups attack-related and defense-related + Arms stats together, and has more obvious labels. + (The new layout is also 3 lines high, hence the previous change.) + + Updated some other Status mode titles. + (The Ztats header for party member pages is still not + working quite right; the new title displays upon initial + Ztats display, but not after paging back and forth. + Presumably it is being re-initialized somewhere.) + + Some minor formatting, typos fixed in comments, + and notes on the units used for "line" (TILE_H vs ASCII_H units) + in various places. + +2007-07-01 Kris Parker + + * worlds/haxima-1.002/arms.scm: + arms action points now proportionally defined + + * worlds/haxima-1.002/blendterrains.scm, worlds/haxima-1.002/newterrain.png, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + slimy cavern uses natural stone walls (experimental) + + * worlds/haxima-1.002/hirespeople.png, worlds/haxima-1.002/sprites.scm, worlds/library/artwork/hirespeople/sleeper.xcf: + hires sleeping humanoid + +2007-06-30 Kris Parker + + * worlds/haxima-1.002/abandoned-farm.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/gregors-hut.scm: + doors and windows use correct wall type + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/shapes.png: + transparency effects for moongates + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + rejigged doors to use composite sprites rather than combinatorial door explosion + + * worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm: + animated slime potion + + * worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm: + animated prismatic bolt, oil potion + + * worlds/haxima-1.002/blendterrains.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/tools.scm: + separated off hills pclass from forest plass as they should affect missiles differently + changed vhard to v-hard for clarity + added s-hard difficulty + + * worlds/haxima-1.002/combat-maps.scm: + variable obacity forest terrains use forest combat map + + * worlds/haxima-1.002/door.scm, worlds/haxima-1.002/poor-house.scm: + added some new door types + + * worlds/haxima-1.002/game.scm: + reduced forest obstructivity to be more in line with its opacity + + * worlds/haxima-1.002/game.scm: + sfast changed to s-fast + + * worlds/haxima-1.002/gamestart-mech.scm: + one-off messages do not trigger for npcs + + * worlds/haxima-1.002/shard.scm: + added some irregularity to forrest visibility near green tower + +2007-06-29 Kris Parker + + * src/common.c, src/common.h, src/map.c, src/sprite.c, src/sprite.h: + Support for 8 way missile sprites + + * src/map.c, src/map.h: + Simplified and sped up missile animations + + * worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm: + separate arrow/bolt on ground sprites + directional spear sprite + + * worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm: + Added diagonal arrow and bolt sprites + + * worlds/haxima-1.002/arms.scm: + enabled magic sword animations + magic axe uses alternate return mmode + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/game.scm: + Returning animation for magic axe + Cannon has greater terrain penetration + + * worlds/haxima-1.002/palette.scm: + another &*%^$ forgotten checkin + +2007-06-28 Kris Parker + + * src/Being.cpp, src/Being.h, src/character.cpp, src/character.h: + NPCs kick player out of bed more sanely + + * src/map.c, src/map.h, src/sprite.c, src/sprite.h: + support for animated projectiles + + * worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm: + magic axe tumbles in flight + +2007-06-27 Kris Parker + + * worlds/haxima-1.002/sprites.scm: + Cannon Sprites + The obligatory "Kris was too dumb to check this in the first time" checkin + +2007-06-26 Kris Parker + + * src/Arms.cpp, src/kern.c: + kern-fire-missile had stopped triggering hit-loc events + added kern-armstype-fire-in-direction + + * worlds/haxima-1.002/ancient-derelict.scm, worlds/haxima-1.002/merciful-death.scm, worlds/haxima-1.002/terrains.scm: + upgraded ancient derelict and merciful death + + * worlds/haxima-1.002/arms.scm: + cannon object + + * worlds/haxima-1.002/arms.scm: + temp-ifc needed to be updated to reflect advanced hit-loc ifc + + * worlds/haxima-1.002/terrains.scm: + ship terrains in table + is-deck updated + + * worlds/haxima-1.002/vehicles.scm: + added working cannons to voidship combat map + + * worlds/haxima-1.002/vehicles.scm: + added working cannons to ship combat map + + * worlds/haxima-1.002/vehicles.scm: + cleaning up + +2007-06-25 Kris Parker + + * worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/zones.scm: + upgraded barts boat + +2007-06-24 Sam Glasby + + * src/character.cpp: + Repaint map after each (visible) NPC move. + + This improves the appearance when an NPC makes + multiple tiles of movement on one turn. + + (Before, such characters seemed to "blink" into the new position.) + + * worlds/haxima-1.002/effects.scm: + Added a message when a character fails to resist paralysis, + losing his turn. + + * worlds/haxima-1.002/terrains.scm: + Added a small glow to t_deep_lava, to improve the ambience + of the dragons lair entrance chamber. + +2007-06-24 Kris Parker + + * worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/ship.png, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/vehicles.scm: + support for objects in turnable vehicles combat maps + vehicle boarding ramps only available when terrain is suitable + vehicles have steering wheels again + + * worlds/haxima-1.002/ship.png, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/vehicles.scm: + improved voidship + forgotten checkin for enemy vehicle compatibility + +2007-06-23 Kris Parker + + * src/combat.c: + Enemy vehicles now use new combat map scheme + + * src/combat.c, src/combat.h, src/kern.c, src/vehicle.h, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/pseudorandom-map.scm, worlds/haxima-1.002/ship.png, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/vehicles.scm: + First pass at scheme based vehicle maps + +2007-06-21 Sam Glasby + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/jim.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/zane.scm: + - Added various items to merchants which seemed lacking. + + - Minor price tweaks on some items. + + - The Engineer now sells various devices (crossbows, sextans, chronometers) + + - The Alchemist now sells some additional potions, some at exorbitant rates. + + - Various types of bows and crossbows are available from merchants, + also spiked helm and shield. + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/moongate-clearing.scm: + Defined a couple of books with low-level spells, + added them to the start area. + + * worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/tooth.scm: + Tidied up indentation in shop inventories. + Made t_arrow and t_bolt more consistently available. + + * worlds/haxima-1.002/gamestart-mech.scm: + Added some feedback in the stats-setting mechanism. + + It would be nicer to print a message mentioning only the stat(s) + changed upon stepping on one of the special tiles, + but that would require restructuring how the mechanisms work. + + * worlds/haxima-1.002/gamestart.scm: + Added the full variety of melee / missile / thrown weapons + and armor / shield, to the quick-start equipment for test purposes. + + * worlds/haxima-1.002/moongate-clearing.scm: + Modest increase to the starting gear. + +2007-06-18 Kris Parker + + * src/combat.c, src/kern.c, src/terrain.h, worlds/haxima-1.002/combat-maps.scm: + first pass at scheme based combat maps + +2007-06-16 Kris Parker + + * src/player.cpp: + One of the new comments was causing the savegame to crash when reloading + (Dont ask me why comments in scheme can break things, but they seem to be able to...) + + * worlds/haxima-1.002/effects.scm: + fire/lightning do not effect regular objects for the moment (it wasnt having any in game effect, and the graphic effects were occuring in places they oughtnt) + +2007-06-13 Kris Parker + + * worlds/haxima-1.002/arms.scm: + getting the rest of the missile drops happening + some cleanups in the ifc routine + + * worlds/haxima-1.002/arms.scm: + ifc builder for missiles that should have a chance of being retrieved + +2007-06-10 Sam Glasby + + * src/kern.c: + Fixed a typo: obj_decc_ref vs obj_dec_ref. + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/species.scm: + Comprehensive review / changes to Action Point costs + for weapons and unarmed attacks. + + Added new types of bows and crossbows. + Added magic axe (returns when thrown) -- should perhaps print a message? + Added thrown rocks + (This is not quite perfect yet, + only one species-native weapon at a time is supported, + so how does a character get one? + Perhaps add 99 of them into party inventory in start-new-game.scm, + but that seems a bit inelegant.) + + Tweaked damage values for a few weapons to improve their usefullness, + such as 2H weapons, thrown spear, and axe. + + Secondary weapons (spiked helm and spiked shield) have very low AP cost + for their minor attacks. + AP costs for dual-weapon-wielding still needs review. + + Some changes to beast/monster native weapons + (small fast t_F_fangs and great toothy f_G_fangs, with various AP costs). + + * worlds/haxima-1.002/arms.scm: + Changed default AP cost for attacks to 75, + such that "speed-human" is sufficient for 2 attacks per round + (or 3 tiles of "norm" movement). + + Also, canonicalized the +to-hit for t_sling_4 + (missed it in the previous checkin). + +2007-06-10 Kris Parker + + * src/kern.c: + added an obj_inc_ref pair to kernel methods that can result in a move() (and hence to scheme callbacks with potentially destructive results) + +2007-06-09 Sam Glasby + + * src/place.c: + Minor formatting change when saving edge_entrance info. + + * worlds/haxima-1.002/arms.scm: + Untabified various tables for consistency in formatting. + Tidied some columns. + Canonicalized some values like "0" --> "+0" and "2" --> "+2". + +2007-06-09 Kris Parker + + * src/Being.cpp, src/ctrl.c: + Critters stop trying to keep wandering around if they are killed by an energy field + + * src/Party.cpp: + npc parties try to avoid harmful terrains when diagonally attacking + + * src/combat.c: + Combat maps grab tiles that are adjactent (based on dx/dy) instead of what the parties happen to be on. Means npc diagonal attacks dont give such wierd results + + * src/object.c: + fix for 1713270: objects now trigger sense updates on removal + + * worlds/haxima-1.002/powers.scm: + added a "put field here" generic command that applies procs as appropriate and allows field to momentarily be placed eg over water, but they will vanish immediately after + (somehow the first attempt only committed the stuff that *uses* the command...) + +2007-06-08 Kris Parker + + * src/kern.c: + fields use mmodes + + * worlds/haxima-1.002/species.scm: + species speeds now defined relative to nominal human speed + +2007-06-08 Gordon McNutt + + * src/Makefile.am: + Added missing objectfreezer files to build list + + * src/cmd.c: + Bugfix for [ 1632199 ] An Tym bugs + +2007-06-05 Kris Parker + + * src/character.cpp: + if custom speed is 0, default to species speed + + * src/object.c: + end of turn messages now check target is a being + + * worlds/haxima-1.002/kobj.scm, worlds/haxima-1.002/npc-types.scm: + generic npcs use species speed + moving "can drop" function to kobj.scm + + * worlds/haxima-1.002/powers.scm: + added a "put field here" generic command that applies procs as appropriate and allows field to momentarily be placed eg over water, but they will vanish immediately after + +2007-06-04 Sam Glasby + + * src/character.cpp, src/character.h, src/kern.c, src/object.c, src/species.c: + Added per-character Action Points per round, in addition + to the existing Species-specific AP/round which stock characters inherit. + + These changes require corresponding changes in the .scm, + specifically, a new parameter passed to kern-mk-char. + (AP_per_turn aka spd, after the mp arg and before the lvl arg) + + The corresponding changes in the .scm files are in the next checkin. + + * src/ctrl.c: + Removed the ESC-to-exit-combat keybinding. + + With ESC used for both exit-from-UI-things and exit-combat-map, + it was wasy to accidentally exit combat, leaving loot behind. + + Now, a message is printed in that case, mentioning both means + of exiting the combat map (the '<' command, and walking off the map edge). + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/abigail.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/anne.scm, worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/dennis.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/edward.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/ghertie.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/joel.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/mesmeme.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/nate.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/nossifer.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/selene.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/silas.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/talking-ankh.scm, worlds/haxima-1.002/tetzl.scm, worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/thorald.scm, worlds/haxima-1.002/thud.scm, worlds/haxima-1.002/tim.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/tutorial.scm, worlds/haxima-1.002/warritrix.scm, worlds/haxima-1.002/zane.scm: + Script changes to match engine changes which add + per-character Action Points per round (spd) to match + the per-Species value which stock characters inherit. + + The values defined (largely in game.scm and species.scm) + will need a lot of balancing. + + For the moment, values which result in multiple tiles of + movement per round are set, so that the feature can be seen and tuned. + +2007-06-04 Kris Parker + + * src/kern.c: + tweak to error messages + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/powers.scm: + prismatic gaze updated to use mostly powers based effects. This still doesnt solve the problem in bug 1687641, either its taken care of in the cast-ui phase, or the field spells can screw up too... + + * worlds/haxima-1.002/blendterrains.scm: + tree corners had wrong pclass + + * worlds/haxima-1.002/game.scm: + shoals were set to walking passable while I was testing drowning code and accidently got checked in + +2007-06-03 Sam Glasby + + * src/angband.c: + Trivial formatting change in OPAQUE and VISIBLE macros. + +2007-06-01 Kris Parker + + * worlds/haxima-1.002/blendterrains.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/wind-bridge.scm: + chasm effect moved to wind-bridge code rather than terrain + objects marked "do not drop" for water or space + + * worlds/haxima-1.002/npc-types.scm: + generic npcs will not drop objects on forbidden terrains + +2007-05-27 Sam Glasby + + * src/character.cpp, src/player.cpp, src/sprite.c: + Appended some text in saved games to label things. + +2007-05-26 Kris Parker + + * src/character.cpp: + fix for bug with npcs not using missile weapons + +2007-05-25 Kris Parker + + * worlds/haxima-1.002/arms.scm: + thrown weapons need a separate projectile type now. arms.scm wasnt giving them one, so it crashed whenever they were used... + +2007-05-24 Kris Parker + + * src/Arms.cpp, src/Arms.h, src/Missile.cpp, src/Missile.h, src/object.c, src/object.h: + ObjectType now has moment mode implemented + + * src/cmd.c, src/ptable.h: + drop checks object mmode + + * src/kern.c: + other object types use object mmode + + * src/kern.c: + added kern-obj-get-movecost method- gets movement cost for a given object:pclass + + * worlds/haxima-1.002/arms.scm: + projectiles and ammo separated in scm + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/ifc.scm: + mmodes for objects added + + * worlds/haxima-1.002/arms.scm: + Separating ammo (on the ground or in inventory) from missiles (projectile in flight) + + * worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/game.scm: + mmodes for fields added + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/terrains.scm: + added separate pclass for checking general canfly/canswim statuses + + * worlds/haxima-1.002/npc-types.scm: + can-fly check based on can-fly pclass + +2007-05-23 Kris Parker + + * src/Arms.cpp, src/Arms.h, src/character.cpp, src/kern.c: + Separating ammo (on the ground or in inventory) from missiles (projectile in flight) + +2007-05-22 Kris Parker + + * worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/runes.scm: + fix for bug 1720802: to make a one-off trigger on pickup, you can create a dummy object, and have its get-ifc swap in the real one (which doesnt have the pickup effect) + +2007-05-21 Kris Parker + + * worlds/haxima-1.002/blendterrains.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/terrains.scm: + you now only fall into chasms or void if you are actually on a square with the space pclass + hence if you bump into a chasm square you are just blocked, but if it opens up beneath you then you are gone + + * worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/terrains.scm: + fixed mountain terrains vs missile passibility in griffon peak + +2007-05-20 Kris Parker + + * src/cmd.c: + ap for readying weapons revised, ap debt limit for equipping in combat + + * src/cmd.c: + ap for getting objects revised, ap debt limit for getting large stacks in combat + + * worlds/haxima-1.002/arms.scm: + ap for readying weapons revised, ap debt limit for equipping in combat + improved shield defense somewhat + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/species.scm: + many 'fast' critters should have reduced movement cost rather than extra AP + + * worlds/haxima-1.002/naz.scm: + ap for getting objects revised + +2007-05-19 Kris Parker + + * src/ctrl.c: + switching from solo to roundrobin doesnt end your turn + + * src/ctrl.c, src/kern.c: + experimental dual-weapon ap mod. we may reverse it later, but I need to do more changes to those files, and this way its a separate cvs entry + + * worlds/haxima-1.002/arms.scm: + flaming sword ap fixed + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/enchanters-tower-mech.scm, worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/keys.scm, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/scrolls.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/tools.scm: + usable item ap fixes + + * worlds/haxima-1.002/pseudorandom-map.scm: + upgrades to random dungeons for lost halls. should have been checked in way back. oops + + * worlds/haxima-1.002/shard.scm: + link shard to new lost halls + +2007-05-18 Kris Parker + + * src/Missile.cpp: + missile obstruction probability changed to percentile rather than d20 + + * src/cmd.c: + mix now takes a long time. ideally, you wouldnt get the spell until afterwards, but that'd be more complex + + * src/cmd.c: + spells use ap as defined in spell list rather than hardcoded function + + * src/common.h: + base action points now 50 + + * src/kern.c: + allow kern-place-set-neighbor to remove neighbors using null argument + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/start-new-game.scm: + base action points now 50 + missile obstruction probability changed to percentile rather than d20 + + * worlds/haxima-1.002/ini.scm: + ini gives more information about the lost halls + + * worlds/haxima-1.002/lost-halls-mech.scm, worlds/haxima-1.002/lost-halls.scm: + pseudorandomificated version of the lost halls + + * worlds/haxima-1.002/spells.scm: + spell ap cost: 25+25/level + +2007-05-15 Kris Parker + + * src/Missile.cpp, src/Party.cpp, src/character.cpp, src/kern.c, src/place.c, src/place.h, src/player.cpp: + mechs now affect movement costs for their tiles. + this did terrible, terrible things to the AI, but it seems to work again now. + +2007-05-14 Sam Glasby + + * src/angband.c: + + + Added some commentary in check_ray_set() related to the + diagonal LOS artifact removal. + +2007-05-12 Kris Parker + + * src/Arms.cpp, src/Arms.h, src/Missile.cpp, src/Missile.h, src/kern.c, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/game.scm: + first pass at using terrain passibility for missile obstruction + + * worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/terrains.scm: + added some variable density forests/trees + +2007-05-10 Kris Parker + + * src/Arms.cpp, src/ctrl.c: + workaround for glitchyness with null objects in hooks + Better handling for obtructions when firing at empty tiles + + * src/Missile.cpp: + partially opaque terrain partially blocks missiles + + * src/dice.c, src/dice.h: + can access dice routines with numeric values instead of strings if needed + + * worlds/haxima-1.002/blendterrains.scm, worlds/haxima-1.002/terrains.scm: + partial opacity tweaked and extended + blended terrains match their base terrains opacities + +2007-05-08 Kris Parker + + * worlds/haxima-1.002/blendterrains.scm, worlds/haxima-1.002/terrains.scm: + swamp now allows double avoidance check + flyers can still get poisoned, but have better chances than walkers + swamp will only trigger when the target is about to get a turn- poison is otherwise too lethal on the worldmap + + * worlds/haxima-1.002/blendterrains.scm, worlds/haxima-1.002/terrains.scm: + blended lava terrain passability fixed + wall torches somewhat less lethal + wilderness scale lava terrain gives avoidance chance + + * worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/powers.scm: + mkdice routine made more generally available + + * worlds/haxima-1.002/terrains.scm: + cleaned out some debugging + +2007-05-07 Kris Parker + + * worlds/haxima-1.002/arms.scm: + flaming sword now does fire damage + + * worlds/haxima-1.002/arms.scm: + doom staff fireballs slowly use mana, plus some other extra effects + +2007-05-06 Kris Parker + + * src/Arms.cpp, src/Arms.h, src/Missile.cpp, src/Missile.h, src/ctrl.c, src/kern.c, src/object.c, src/object.h: + More detail available for weapon callbacks- now has user, target, whether it hit, and whether it did damage. + Callbacks on melee weapons should hopefully work, too, although I havent tested it. + + * worlds/haxima-1.002/arms.scm: + More detail available for weapon callbacks + +2007-05-03 Kris Parker + + * src/character.cpp: + bug 1710622 added guard clauses to prevent dead people from getting synchronized or introduced + + * worlds/haxima-1.002/scrolls.scm: + bug 1666217 scrolls now use their own context checking (for the important ones anyway, Ill deal with the rest some other time) + +2007-05-01 Kris Parker + + * src/Being.cpp: + fix for 1700846: + check for zero length paths even in impassable path regeneration + + * worlds/haxima-1.002/arms.scm: + slime potion was using directional sprite type without having directional sprite images. + +2007-04-29 Kris Parker + + * worlds/haxima-1.002/newterrain.png, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + hiresed rock wall, rock secret + added rock window + + * worlds/library/artwork/terrain/rockwall.xcf: + hires rock wall and associated terrains + +2007-03-29 Kris Parker + + * src/objectfreezer.c: + a few checks for null before doing stuff on potentially empty trees + + * src/objectfreezer.c, src/objectfreezer.h, src/session.c: + objects in the freezer need to be manually start() ed since they arent in the regular Session->data_objects list + +2007-03-27 Kris Parker + + * src/objectfreezer.c: + copy lookup keys to prevent them being eaten by the garbage collector + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + pseudorandom maps now use objectfreezer to remember room contents + +2007-03-25 Kris Parker + + * src/kern.c, src/objectfreezer.c, src/objectfreezer.h, src/session.c, src/session.h: + renamed objectfreezer methods to match rest of codebase + objectfreezer should no longer leak like a ruptured colander + + * src/kern.c: + kern-obj-thaw-at handles locating object correctly + + * src/objectfreezer.c, src/objectfreezer.h, src/session.c, src/session.h: + object freezer now works across save files + +2007-03-24 Kris Parker + + * src/kern.c, src/objectfreezer.c, src/objectfreezer.h, src/session.h: + first pass at object freezer + at this stage can store objects for current session only (no save/load) + +2007-03-18 Kris Parker + + * worlds/haxima-1.002/portcullis.scm, worlds/haxima-1.002/traps_3_mechs.scm: + Fix for 1682961: gave portcullises a separate handler for remote open/close events. It looks like they are only used by traps_3. + +2007-03-14 Gordon McNutt + + * src/Missile.cpp, src/angband.c: + Kernel changes: + o Bugfix: bushes were blocking missiles, because their transparency was + recently changed to be somewhere between transparent and opaque. The missile + code was interpreting anything non-transparent as opaque. Come to think of + it, this might not be quite what is wanted yet, because missiles (which use + bresenham) will fly further than los (which uses highly optimized + ray-casting) through semi-opaque terrain. + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/powers.scm: + Haxima changes: + o powers-resurrect checks if target is really dead + o cast-ui-dospell-nolos lets effect determine result code + o cleaned up some debug printlns + +2007-03-13 Gordon McNutt + + * src/cmd.c, src/result.h, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/start-new-game.scm: + Kernel changes: + o Added new result codes to kernel + o Result evaluation uses a lookup table now instead of a switch statement + + Haxima changes: + o Fixed a couple of potion result codes + o Fixed the heal power result codes + + * worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/runes.scm: + Haxima changes: + o Fixed result codes for using runes. + +2007-03-12 Gordon McNutt + + * src/cmd.c, src/screen.c, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/items.scm, worlds/haxima-1.002/keys.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/scrolls.scm, worlds/haxima-1.002/tools.scm: + Kernel changes: + o 'use' now checks the return value of closure calls and log the results to the + console (exactly like 'yuse') + + Haxima changes: + o All the item procedures now return one of the standard result-* codes. + +2007-03-11 Gordon McNutt + + * src/cmd.c, src/object.c, src/object.h, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + Kernel changes: + o All the ObjectType methods that invoke closure_exec() now pass the result + back to their caller. + + Haxima changes: + o Added new tool: rope & hook + o Added passive Reach skill for wrogues, which employs the rope & hook + +2007-03-10 Gordon McNutt + + * src/screen.c: + Added debug routines to dump some SDL types + +2007-03-08 Gordon McNutt + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/occs.scm: + Haxima changes: + o As the wrogue advances he can do more challenging things while in stealth + mode. + + * worlds/haxima-1.002/effects.scm: + Haxima changes: + o The torch effect removes the stealth effect. + +2007-03-07 Gordon McNutt + + * src/cmd.c, src/ctrl.c, src/kern.c, src/object.h, worlds/haxima-1.002/effects.scm: + Kernel changes: + o Added a bunch of foo-done hooks, where 'foo' is a character action that + should probably kick the character out of stealth mode. + + Haxima changes: + o Stealth effect removed when character attacks, gets, drops, uses, yuses, + opens, handles, mixes or casts. + + * src/effect.c, src/effect.h, src/kern.c, src/object.c, src/session.c: + Undoing the multi-hook effect stuff. Not necessary, cumbersome, and doesn't + even work. + +2007-03-06 Gordon McNutt + + * src/character.cpp, src/closure.c, src/closure.h, src/effect.h, src/kern.c, src/object.c, src/object.h, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/skills.scm: + First part of Stealth skill: character is invisible until mana runs out or it + moves. + +2007-03-02 Gordon McNutt + + * src/Makefile.am, src/angband.c, src/character.cpp, src/character.h, src/effect.c, src/effect.h, src/kern.c, src/object.c, src/object.h, worlds/haxima-1.002/effects.scm: + Changed hook id's from strings to bits. This is to allow an effects to run on + multiple hooks, a prerequisite of the rogue's Hide skill and its advanced forms + (Sneak and Invisibility). These changes are lightly tested so far (I tried a + torch). + +2007-02-25 Gordon McNutt + + * src/cmd.c, src/cmd.h: + Consolidated some more of the targeting functions + +2007-02-22 Gordon McNutt + + * src/angband.c, src/place.c, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/terrains.scm: + Added variable-depth LOS. + +2007-02-20 Gordon McNutt + + * worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + Haxima changes: + o Added wrogue skill: Disarm Trap. Works on chests and doors. + +2007-02-19 Gordon McNutt + + * src/cmd.c: + Fixed new h)andle crash + + * src/kern.c, src/scheme-private.h, src/scheme.c, src/scheme.h, src/session.c, worlds/haxima-1.002/mouse.scm: + Fixing last currently known memory leak. This also ensures that if a Scheme + variable refers to a destructible kernel object then the variable continues to + refer to a valid memory location in the kernel, even if the world object is + killed or "destroyed" (destroyed in a game sense, not a memory management + sense). Caveat: this protection only applies to Scheme variables created via + tagging an object (ie, kern-mk-char and kern-tag). + + Kernel changes: + o Scheme interpreter now supports a "custom finalizer" provided by the + kernel. Scheme cells may be flagged to invoke this when they are gc'd. + o The kern_mk_char and kern_tag -- which define Scheme variables to refer to + destructible kernel objects -- flag the reference and add an incremental ref + count to the referred object. + o The custom finalizer decrements the extra refcount. + o To prevent reference cycles (which do exist) between the kernel and + interpreter from causing a leak on session teardown, the scheme cleanup + function unprotects all cells before running the final gc. + + Haxima changes: + o Removed the hack in mouse.scm which manually added an extra refcount to Thud + and Kathryn. This hack caused these objects to leak. The above changes render + this unnecessary. + + * src/scheme.c, src/session.c: + Replaced the big memory leak with a small one + +2007-02-18 Gordon McNutt + + * src/cmd.c, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + Kernel changes: + o Yuse checks for tools and materials + o Yuse consumes materials + o Yuse UI shows material available + o Yuse UI show lack of tools or material in red; avail in green + + Haxima changes: + o Added grease + o Wriggle skill requires 1 grease + + * worlds/haxima-1.002/skills.scm: + Sprint adds yusers current ap to extend range + +2007-02-16 Gordon McNutt + + * src/cmd.c, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/portcullis.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm, worlds/haxima-1.002/terrains.scm: + Added Wriggle skill. + + Kernel changes: + o Removed obsolete comment + + Haxima changes: + o Added new movement mode: "wriggle" + o Added new passability class: "bars" + o Changed portculli and windows to have pclass "bars" + + * src/kern.c, src/place.c, src/place.h, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + At long, long, last... + + SPRINT IS FINISHED!!! + + Kernel changes: + o Added kern-place-apply-tile-effects + + Haxima changes: + o Sprint now moves the yuser and applies tile effects along the way + +2007-02-14 Gordon McNutt + + * src/kern.c, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/skills.scm: + Kernel changes: + o Added kern-place-get-movement-cost + + Haxima changes: + o Added (line x1 y1 x2 y2); returns a line as a list of (x.y) pairs + o Sprint destination targeting now accounts for movement cost + +2007-02-07 Gordon McNutt + + * scripts/ANNOUNCEMENT, scripts/RELEASE_CHECKOFF, src/kern.c, src/templ.c, src/templ.h, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + Some progress on Sprint: UI now builds a template of tiles for radius and LOS. + +2007-02-04 Kris Parker + + * src/character.cpp, src/place.h: + direction when moving of edge of map is determined by location relative to map rather than direction of last move + + * src/place.c: + removed a bunch of debugging output from the previous fix (oops) + + * src/place.c: + fix for 1634496: diagonal movement now only checks neighbors for passability, rather than actually attempting to move onto them. + +2007-02-04 Gordon McNutt + + * src/Makefile.am, src/cmd.c, src/cmd.h, src/cursor.cpp, src/cursor.h, src/list.h, src/templ.c, src/templ.h: + Step 1 of a new targeting ui function. This will replace the existing + select_target and its kin when I'm completely done. The new function will allow + spells to auto-target friends, foes, or whatever; it will also enable some of + the UI enhancements I want for the Sprint skill. + +2007-02-03 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm: + tweaked random paramters- dungeon was not being very connected. + also centred checked area properly + + * worlds/haxima-1.002/endless-deeps.scm: + special rooms are marked as not connecting to the dungeon + + * worlds/haxima-1.002/pseudorandom-map.scm: + fixed problem with checking algorithm + a lot of cleaning up + +2007-01-30 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm: + endless deeps are checked for cohesion on first entry only + + * worlds/haxima-1.002/pseudorandom-map.scm: + cohesion checking now creates new links based on an input factory function + +2007-01-30 Gordon McNutt + + * src/object.c, src/status.c: + Adding action points to status display. Kind of useless right now. + +2007-01-29 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/pseudorandom-map.scm: + cleaned out cohesion debugging output. set up checking in endless deeps + +2007-01-29 Gordon McNutt + + * src/cmd.c, src/kern.c, src/skill.h, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/pitfalls.scm, worlds/haxima-1.002/skills.scm: + Added support for "passive skills". Y)use does not apply to passive + skills. They are meant to be used by other parts of the script to check if a + character has a certain skill. For example, the 'use handler in the pitfall + objects (beartrap and caltrops) now checks if a character has the passive "arm + trap" skill. + + * src/object.c: + Merged over set-ttl 0 bugfix + + * src/object.c: + Should have tested that last fix. NOW the set-ttl 0 bug is fixed. + + * src/object.c: + Fixed a (kern-obj-set-ttl kobj 0) crasher + +2007-01-28 Kris Parker + + * worlds/haxima-1.002/humanoids.png, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/sprites.scm, worlds/library/artwork/humanoids/nixiesword.xcf: + nixie with sword + + * worlds/haxima-1.002/pseudorandom-map.scm: + works once somewhere prototype of random map linking + + * worlds/library/artwork/humanoids/nixiespear.xcf: + one spear nixie water subsprite was backwards + +2007-01-28 Gordon McNutt + + * src/kern.c, worlds/haxima-1.002/powers.scm: + Jumping now checks for blocking corner terrain at distance 1. + +2007-01-27 Kris Parker + + * worlds/haxima-1.002/humanoids.png, worlds/library/artwork/humanoids/nixiespear.xcf: + nixie with spear + + * worlds/haxima-1.002/humanoids.png, worlds/library/artwork/humanoids/nixieciv.xcf: + tweaked nixie + + * worlds/haxima-1.002/pseudorandom-map.scm: + "ugly but it works" prototype of random dungeon continuity testing. (doesnt yet fix unlinked areas) + +2007-01-27 Gordon McNutt + + * src/cmd.c, src/kern.c, src/skill.h, worlds/haxima-1.002/skills.scm: + Skills now have a "wilderness ok" flag. If the flag is not set the skill can't + be used in the wilderness. + +2007-01-26 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + random map links now contain passability data (for continuity testing) + + * worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/humanoids.png, worlds/haxima-1.002/sprites.scm, worlds/library/artwork/humanoids/nixieciv.xcf: + first pass at hires nixies + +2007-01-26 Gordon McNutt + + * ChangeLog, Makefile.am, NEWS, haxima.desktop, worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/steward.scm: + Merging over icons, desktop and typo fixes from 0.5.6-rc2 + + * doc/USERS_GUIDE, doc/users_guide.html, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/reagents.scm: + Merging over 2nd typo fix from 0.5.6-rc2 + + * doc/USERS_GUIDE, doc/users_guide.html, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/reagents.scm, worlds/haxima-1.002/shroom.scm: + Applied mwinterrowd's 2nd typos patch + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/steward.scm: + Applying mwinterrowd's first typos patch + +2007-01-25 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + improvements to random dungeon hardlink storage + + * worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + hooks in hardlinks reenabled + +2007-01-23 Janne Johansson + + * doc/GAME_RULES, doc/MAP_HACKERS_GUIDE, doc/USERS_GUIDE, doc/world_building/sound_sample_media.txt: + various nitpicks in docs and spelling fixes + +2007-01-22 Gordon McNutt + + * Makefile.am: + Added icons and .desktop to distro list + + * haxima.desktop: + file haxima.desktop was initially added on branch release_0_5_5_maint. + + * haxima.desktop: + Added icons and .desktop file + + * worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + Added Detect Trap as a skill + +2007-01-21 Kris Parker + + * src/scheme.c: + save file support for vectors + +2007-01-21 Gordon McNutt + + * src/character.cpp, src/character.h, src/kern.c, src/object.c, src/object.h, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + Added Jump skill + +2007-01-20 Gordon McNutt + + * src/ascii.c, src/ascii.h, src/cmd.c, src/screen.c: + screenPrint now ignores the special control characters when figuring out how big strings are + + * src/cmd.c, src/kern.c, src/status.c: + Kernel changes: + o kern_mk_skill_set checks for null skill + o Y)use skill listings now show required tools and material + o scrolling skills was not advancing selection + o Tweaked color format in skill listing + +2007-01-19 Gordon McNutt + + * ChangeLog, NEWS, configure.ac: + Final update for 0.5.6-rc1 + +2007-01-16 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm: + endless deeps uses random prng seeds to vary from game to game. Unfortunately, this can result in them not being particularly endless, or even being particularly not endless + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + z coordinate added to random dungeons. + +2007-01-16 Gordon McNutt + + * src/Container.cpp, src/Container.h, src/cmd.c, src/object.h, src/scheme.c, src/status.c, src/status.h: + Some minor code cleanup and yet another experimental status browser function. + +2007-01-15 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/pseudorandom-map.scm: + slightly simpler syntax for random dungeon hardlink hooks + + * worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + store customisable hardlink function, and actual hardlink data + +2007-01-13 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/pseudorandom-map.scm: + hooks added to allow random map templates to add objects as well as terrain + +2007-01-13 Gordon McNutt + + * src/cmd.c, src/skill.h, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/skills.scm: + Y)using the unlock skill now works. + +2007-01-12 Gordon McNutt + + * configure.ac, src/cmd.c, src/cmd.h, src/ctrl.c, src/kern.c, src/node.c, src/node.h, src/occ.c, src/occ.h, src/scheme.c, src/scheme.h, src/session.c, src/skill.c, src/skill.h, src/skill_set.c, src/skill_set_entry.c, src/skill_set_entry.h, src/species.h, src/status.c, src/status.h, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/skills.scm: + y)use now shows occupation skills in the status browser + +2007-01-10 Gordon McNutt + + * src/Makefile.am, src/cfg.c, src/kern.c, src/repstr.c, src/repstr.h, src/session.h, src/skill.c, src/skill.h, src/skill_set.c, src/skill_set.h, src/skill_set_entry.c, src/skill_set_entry.h: + More skill groundwork + +2007-01-09 Gordon McNutt + + * src/cmd.c: + Updated built-in help with k)amp and l)oiter + + * src/kern.c, src/place.c, src/play.c, src/session.c, src/skill.h: + More bugfixes from 0.5.5 maintenance branch; mixed in with some skill stuff unfortunately + + * src/kern.c: + One last tweak to get that time accel thing re-loading properly + + * src/kern.c, src/session.c: + Bugfix for [ 1629974 ] loitering in wilderness uses too much food. + + Addendum to the previous fix. Saving/loading the floating-point time + acceleration value was not done properly, causing it to be zero on reload and + wreaking havoc. + + * src/nazghul.c, src/play.c: + Moved the 'welcome to' with the version info to the initial startup (not the game load) + + * src/object.c, src/player.cpp, src/session.h: + Merged bugfix from 0.5.5 maintenance branch + + * src/object.c, src/player.cpp, src/session.h: + Bugfix for [ 1629974 ] loitering in wilderness uses too much food. + + Loitering for 1 hour was actually using up almost 32 hours. Time acceleration + was set to a value appropriate for one hour at town scale, not wilderness + scale. To make the values work out for wilderness scale I had to change time + acceleration to be a floating point and fix a few type casts. + + * src/place.c, src/play.c: + Bugfix for [ 1624247 ] Delayed victory messages + + Combat status is now checked after every object executes. Seems inefficient but + I'm not noticing any performance hit. + +2007-01-06 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + prng parameters now in random map parameter object + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + terrain templates now in random map parameter object + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/pseudorandom-map.scm: + blitstats construction formalized + +2007-01-06 Gordon McNutt + + * scripts/RELEASE_CHECKOFF: + Updated some notes on post-release maintenance + + * src/kern.c, src/object.c, src/object.h, src/place.c, worlds/haxima-1.002/demon-gate.scm, worlds/haxima-1.002/powers.scm: + Merged bugfix from 0.5.5 maintenance branch + + * src/kern.c, src/object.c, src/object.h, src/place.c, worlds/haxima-1.002/demon-gate.scm: + Bugfix for [ 1622833 ] Killing Nossifer with time stopped. Added a new object + attribute: ignoreTimeStop. The object which checks for end-of-game has this + attribute set. + + * worlds/haxima-1.002/powers.scm: + Fix for [ 1629421 ] unusual fireball behavior vs. lich. Fixed a parenthesis + error in power.scm. + +2007-01-05 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + blitstats stored in map params + + * worlds/haxima-1.002/npc-types.scm: + minor glitch- wrong sprite for deeps troll geomancer + +2007-01-05 Gordon McNutt + + * src/place.c: + Merging bugfix from 0.5.5. maintenance branch + + * src/place.c: + Bugfix for [ 1627495 ] crash when dying in tutorial cave + + There was a case where place_exec() would return w/o decrementing a refcount on + the player party, triggering an assert in session_del(). + +2007-01-04 Kris Parker + + * worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/pseudorandom-map.scm: + beginning to shift random map data into structures suitable for runtime storage + +2007-01-04 Gordon McNutt + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/moongate.scm: + Merging bug fixes from 0.5.5 maintenance branch + + * worlds/haxima-1.002/alchemist.scm: + Fix for [ 1626202 ] Alchemist and the passage into Absalot. Fixed some logic + bugs in the Alkie's conversation. + + * worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/kama.scm: + Fix for [ 1626207 ] Releasing Kama from prison. Instead of pathfinding, Kama's + jail door is now tagged and stored in Kama's gob so he can check its state + directly. + + * worlds/haxima-1.002/moongate.scm: + Fix for [ 1622837 ] Loopback moongate doesn't stay. Iff the source and + destination gates are the same don't set the destination gate sprite to + "closed" after showing the animation. + +2007-01-03 Gordon McNutt + + * src/character.cpp: + Merging in NPC inventory count fix from 0.5.5 maintenance branch + + * src/character.cpp: + Bugfix for [ 1623756 ] Jorn has too many magical items + + The code which arms NPC's was putting on and taking off different pieces of + equipment to try them out. Every time it took it off it incremented the + inventory counter, but it wasn't decrementing it when it put things on, so the + counts were messed up on all NPC's who arm themselves. + +2007-01-02 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/pseudorandom-map.scm: + changed namespace for generic random dungeon code + + * worlds/haxima-1.002/pseudorandom-map.scm: + notes of room linkages added + +2007-01-01 Kris Parker + + * worlds/haxima-1.002/bigobjects.png, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm, worlds/library/artwork/monsters/dragonsleep.xcf: + sprite for sleeping dragon + + * worlds/haxima-1.002/bigobjects.png, worlds/haxima-1.002/monsters.png, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/sprites.scm: + dragon sprites used + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/pseudorandom-map.scm, worlds/haxima-1.002/start-new-game.scm: + refactored generic random map code from the endless deeps to pseudorandom-map.scm + + * worlds/library/artwork/monsters/dragon.xcf: + new attempt at dragon sprite + +2007-01-01 Gordon McNutt + + * scripts/RELEASE_CHECKOFF, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/portcullis.scm: + Merging bugfixes from maintenance branch to main trunk + + * worlds/haxima-1.002/Makefile.am: + Fixing the missing-distro-files problem once and for all. + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/fields.scm: + Fix for 1622430: "Undead beings aren't immune to sleep fields". Field immunity + was just messed up in general. + + Also fixed 1623757: "Items can get poisoned". Poison wasn't checking that it + was being applied to a character. + +2006-12-31 Gordon McNutt + + * configure.ac: + Added the png link fix on the 0.5.6 branch + + * src/Party.cpp: + If an NPC party tries to make a diagonal attack it selects a passable adjacent square to attack from instead. + + * src/astar.c, src/astar.h, src/place.c: + Turned on diagonal movement for NPC pathfinding + + * src/astar.c, src/character.cpp, src/common.c, src/ctrl.c, src/place.c, src/place.h: + Turning on diagonal movement for player characters only. Can't move through pinched corners. + + * src/character.cpp, src/effect.c, src/kern.c, src/map.c, src/occ.c, src/session.c: + Fixed some memory leaks reported by a profiler. Thanks to Eero for giving me a report. + + * src/cmd.c, src/kern.c, src/object.c, src/object.h, worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/jewelry.scm, worlds/haxima-1.002/runes.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/start-new-game.scm: + Quest items can be tagged special, so they won't get dropped in temporary combat maps and lost forever. + + * src/cmd.c: + Added direction prompt to d)rop + + * src/cmd.c: + Added a quantity prompt to d)rop + + * src/cmd.c, src/status.c: + Drop now respects readied arms + + * src/cmd.c, src/cmd.h, src/ctrl.c, src/menus.c, src/status.c, src/status.h, worlds/haxima-1.002/spells.scm: + Initial cut at a D)rop command + + * worlds/haxima-1.002/Makefile.am: + Added the 640x480 splash fix on the 0.5.6 branch + + * worlds/haxima-1.002/portcullis.scm: + Bugfix 1622407: o)pen works on portcullises + +2006-12-30 Gordon McNutt + + * src/Makefile.am, src/kern.c, src/session.c, src/session.h, src/skill.c, src/skill.h, worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/skills.scm: + Started adding code to support skills + + * src/cmd.c: + Bugfix: clicking on close window multiple times caused an endless loop + +2006-12-23 Gordon McNutt + + * worlds/haxima-1.002/Makefile.am: + Missing small-screen splash in distro + +2006-12-20 Gordon McNutt + + * scripts/RELEASE_CHECKOFF: + Added instructions for uploading releases for release maintainers + +2006-12-17 Gordon McNutt + + * configure.ac: + Added check for libpng + +2006-12-15 Gordon McNutt + + * AUTHORS, ChangeLog, NEWS, configure.ac, doc/USERS_GUIDE: + Final changes before release + + * scripts/ANNOUNCEMENT: + Adding a file for boilerplate release announcements + + * scripts/RELEASE_CHECKOFF: + Some tweaks to the release checkoff list + + * worlds/haxima-1.002/Makefile.am: + The spell image file needs to be in the install + + * worlds/haxima-1.002/spells.png, worlds/haxima-1.002/spells.scm: + Added all the spell sprites + + * worlds/haxima-1.002/start-new-game.scm: + Fixing the start file + +2006-12-14 Gordon McNutt + + * src/cmd.c, src/kern.c, src/magic.c, src/magic.h, src/status.c, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/start-new-game.scm: + Spells ready to show sprites in status browser; other spell stats now shown + +2006-12-13 Gordon McNutt + + * src/cmd.c: + C)ast now shows how many mixtures are remaining + + * src/cmd.c: + M)ix command now shows how many of that spell are already mixed before the player begins reagent selection + + * src/cmd.c: + G)et and S)earch now use up standard AP + + * src/cmd.c: + Disable '>' when standing over a town to prevent abuse + + * src/map.c: + Bugfix: with fast critters sometimes the damage flash on their victim would appear to happen before they moved + + * src/vmask.c: + Bugfix: one more time for that pernicious LOS bug; using the place pointer instead of it's name in the hash key + +2006-12-12 Kris Parker + + * worlds/haxima-1.002/humanoids.png: + lich sprite added + + * worlds/haxima-1.002/monsters.png, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm: + gazer sprites used + + * worlds/haxima-1.002/sprites.scm: + lich sprite used + + * worlds/library/spritenotes.txt: + old sprite notes I never got around to cvsing in + + * worlds/library/artwork/humanoids/lich.xcf: + lich sprite + + * worlds/library/artwork/monsters/gazer.xcf, worlds/library/artwork/monsters/gazersleep.xcf: + gazer sprites + +2006-12-11 Kris Parker + + * worlds/haxima-1.002/humanoids.png, worlds/library/artwork/humanoids/skeletonarcher.xcf, worlds/library/artwork/humanoids/spearskeleton.xcf: + skeleton spearthrower and skeleton archer icons + + * worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/sprites.scm: + skeleton sprites upgraded + +2006-12-10 Kris Parker + + * doc/users_guide.html: + Graphical foogod symbols added + + * worlds/haxima-1.002/humanoids.png: + warrior skeleton sprite + + * worlds/haxima-1.002/humanoids.png, worlds/library/artwork/humanoids/deadarcher.xcf: + deadarcher- floating armour, with bow + + * worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/sprites.scm: + craven archers use new icon + + * worlds/library/artwork/humanoids/skeleton.xcf, worlds/library/artwork/humanoids/swordskeleton.xcf: + generic and warrior skeletons + + * worlds/library/artwork/monsters/dragon.xcf: + Attempt at a dragon. + +2006-12-10 Gordon McNutt + + * ChangeLog: + Updated + + * doc/USERS_GUIDE: + Updated text USERS_GUIDE to reflect changes in foogod window icons + + * src/combat.c, src/ctrl.c, src/pinfo.h, src/player.h: + Attempting to fix the sporadic camping-on-fireplace bug. Looks like it was caused by an unitialized and obsolete flag. Removing the flag + + * src/ctrl.c: + Re-initialize the list of suggested targets for every attack cycle; should fix rare assert on line 663 + + * src/foogod.c, src/foogod.h, src/kern.c, src/object.c, src/session.c, src/session.h, worlds/haxima-1.002/effects.png, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/sprites.scm: + Replaced cryptic letters with cryptic icons to show global effects in the foogod window + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/npc-types.scm: + Nixies shouldn't have torches + + * worlds/haxima-1.002/arms.scm: + Reducing the range of the doom staff by 1 + + * worlds/haxima-1.002/arms.scm: + Extending range of prismatic gaze by 1; Mesmeme a bit too underpowered in the late game + + * worlds/haxima-1.002/conv.scm: + People in Oparine ought to know where it is + + * worlds/haxima-1.002/dennis.scm: + Dennis replies to keyword Selene + + * worlds/haxima-1.002/effects.scm: + Removed fizzle from prismatic attack; there are enough failure cases already + + * worlds/haxima-1.002/engineer.scm: + Grammatical tweak to conv + + * worlds/haxima-1.002/naz.scm: + Added make-allies + + * worlds/haxima-1.002/road_to_absalot.scm: + What we need are a few more zorns + + * worlds/haxima-1.002/silas.scm: + A few more tweaks to Silas + + * worlds/haxima-1.002/silas.scm: + Improvements to Silas's conversation + + * worlds/haxima-1.002/tblit.scm: + Annoying debug removed + + * worlds/haxima-1.002/the-man.scm: + Spell recipe was wrong + + * worlds/haxima-1.002/void-temple.scm: + Wisps were not appearing + +2006-12-09 Kris Parker + + * src/Party.cpp, src/Party.h, src/object.c, src/place.c: + fix for examine crashing on parties + linebreaks in examine + + * src/cmd.c, src/cmd.h: + added cardinal direction keyhandler for attack command + + * worlds/haxima-1.002/ai.scm: + wisps use light + + * worlds/haxima-1.002/ancient-derelict.scm: + loot on anchient derelict + + * worlds/haxima-1.002/bigobjects.png, worlds/haxima-1.002/sprites.scm, worlds/library/artwork/humanoids/balron.xcf: + bigger balron icon + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/npc-types.scm: + moved alternate alignment critters to npc-types + + * worlds/haxima-1.002/road_to_absalot.scm: + tweaks to absalot: + alignment fixes + lava edging + removed too easy way through fort + +2006-12-09 Gordon McNutt + + * src/Party.cpp: + On detailed x)amine a party describes its members + + * worlds/haxima-1.002/anaxes.scm: + Forgot to add Lich's blood to Anaxes's drops + + * worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/silas.scm: + Fixed loot and lich effects for Anaxes + + * worlds/haxima-1.002/parties.scm: + More corrections to plural party names + + * worlds/haxima-1.002/parties.scm: + Fixed some plural party names + +2006-12-08 Kris Parker + + * src/map.c: + missile fire should now have less wierdness with obstructions + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/enchanters-tower.scm: + added bet flam hur spellbook + + * worlds/haxima-1.002/enchanters-tower-mech.scm: + fix for mirror based crash + + * worlds/haxima-1.002/endless-deeps.scm: + corpse loot fixed + + * worlds/haxima-1.002/luximene.scm: + added lichs blood to luxs inventory + +2006-12-07 Kris Parker + + * worlds/haxima-1.002/enchanters-tower-mech.scm: + enchanters' oddly reflecting mirrors activate in timely fashion + +2006-12-07 Gordon McNutt + + * src/character.cpp: + Bugfix: dead characters could give a 'wakes up' message when camping + + * src/cmd.c: + Print a snarky message if the player selects a dead character to guard the camp + + * src/effect.h, src/status.c: + Converted some magic numbers to named constants; fixed a ztats bug which caused multiple effects to be listed offset from column 0 + + * src/kern.c: + Added (kern-ticks-per-turn) + + * src/player.cpp: + Bugfix: dead party members starving + + * worlds/haxima-1.002/effects.scm: + Poison now permanent, so it doesn't wear off with 2 hours of camping. Poison and disease both apply more damage per turn in the wilderness than at town scale. + + * worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/treasury.scm: + Bugfix: bad chest list + +2006-12-06 Gordon McNutt + + * src/cmd.c: + Bugfix: when mixing, the number mixed flashes without a - separator; annoying + + * src/player.cpp, src/session.c: + Bugfix: assert when quitting while aboard a vehicle + +2006-12-04 Gordon McNutt + + * src/ctrl.c: + Adjusted console printout for attack verbage + + * worlds/haxima-1.002/chanticleer.scm: + Fixed the hint about where to find the Lost Halls + + * worlds/haxima-1.002/effects.scm: + Fixed typo in generic-burn + + * worlds/haxima-1.002/effects.scm: + Removed superfluous console message for paralysis + + * worlds/haxima-1.002/enchanters-tower-mech.scm: + Protect against evaluating tags on startup before they are declared + + * worlds/haxima-1.002/spells.scm: + Tweak to format, moved Kal Xen Nox down with the other L8 spells + +2006-12-03 Kris Parker + + * worlds/haxima-1.002/640x480_splash.png, worlds/haxima-1.002/splash.png: + Updated splash screens (now use a more up to date version of the logo, doesnt scale screenshot part of smaller splash) + +2006-12-03 Gordon McNutt + + * src/Container.cpp, src/Container.h, src/character.cpp, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/traps_1.scm, worlds/haxima-1.002/traps_2.scm, worlds/haxima-1.002/traps_3.scm, worlds/haxima-1.002/traps_4.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Increased time that Thief's Door in Bole is open + o Added (floor ...) to a few more spots in powers.scm + + Kernel changes: + o When an NPC unreadies arms they are put back into personal inventory (fixes + acid on NPC's) + o Bugfix: NPC's with their "force drop" flag set would drop their inventories, + which are now abstract containers and don't function well as physical + objects. They now drop their contents directly instead. + + * worlds/haxima-1.002/alchemist.scm: + Raised price of invisibility potion back up again + + * worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/species.scm: + Haxima changes: + o Raised back up the price of precision instruments. + o Added prismatic_gaze as a natural weapon for gazers. + + * worlds/haxima-1.002/conv.scm: + Grammar fix + + * worlds/haxima-1.002/effects.scm: + Tweaks to console messages for burn and lightning effects + + * worlds/haxima-1.002/game.scm: + Raising scroll prices back up a bit more + +2006-12-02 Gordon McNutt + + * src/menus.c: + Tweaked credits + + * src/nazghul.c, worlds/haxima-1.002/kern-init.scm: + Haxima changes: + o Updated kern-init.scm to reflect kernel changes. + + Kernel changes: + o Support a different splash screen for each supported screen dimension. + + * src/nazghul.c: + Splash screen width computed wrong + + * src/player.cpp, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/zane.scm: + Haxima changes: + o Shroom opens shop earlier + o Price deflation on potions, scrolls and misc items. + o Added an in-game spell book for reference + + Kernel changes: + o Time accelerated faster now while sleeping in town or k)amping + + * worlds/haxima-1.002/640x480_splash.png, worlds/haxima-1.002/kern-init.scm: + Added the small splash image file + + * worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/edward.scm: + Haxima changes: + o Tweaks to Edward to handle cases where the Wanderer is dead or not the party + leader. + o If player took Nate straight to jail Deric would not re-assign ranger. + + * worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/gamestart.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/necromancers-lair.scm, worlds/haxima-1.002/old-absalot.scm, worlds/haxima-1.002/prison.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/tutorial_town.scm: + Haxima changes: + o Shroom opens shop earlier + o Price deflation on potions, scrolls and misc items. + o Added an in-game spell book for reference + o Converted some more chests from (list (list ...) ...) to '(( ...) ...) + format. + o Tweaked Zane's schedule zones + + Kernel changes: + o Time accelerated faster now while sleeping in town or k)amping + +2006-12-01 Kris Parker + + * doc/users_guide.html: + tweaked html manual + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/npc-types.scm: + removed light from several non tool using or dark appreciating critters + + * worlds/haxima-1.002/cast-ui.scm: + fix for resurect spell in town + +2006-12-01 Gordon McNutt + + * src/character.cpp, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/edward.scm, worlds/haxima-1.002/naz.scm: + Haxima changes: + o Edward won't take Nate out of the party if he's the only living member. + o If the only living party member talks to his/her/itself, and asks + his/her/itself to leave, it will give itself some excuse not to. + + Kernel changes: + o Bugfix: if the current party leader was removed while in follow mode, the new + leader was not re-evaluated, and the kernel continued to try and use the + ex-member as the leader, causing a crash. + o When a party member leaves he/she/it unreadies all weapons instead of + removing them from party inventory. + + * worlds/haxima-1.002/ancient-derelict.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/edward.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/gate-guard.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/merciful-death.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/nate.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/poor-house.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/zane.scm: + Haxima changes: + o Fixed the broken chests that used mk-content and add-content. At least, I + fixed the one or two I've tested thus far. + + * worlds/haxima-1.002/brundegardt.scm: + Haxima changes: + o Removed door left stranded after my last map tweaks to Brundegardt. + + * worlds/haxima-1.002/brundegardt.scm: + Weather vane was falling into the chasm... + +2006-11-30 Gordon McNutt + + * src/Missile.cpp, src/ctrl.c, src/ctrl.h, src/foogod.c, src/kern.c, src/player.cpp, src/player.h, src/session.c, src/session.h, src/vehicle.cpp, worlds/haxima-1.002/thorald.scm, worlds/haxima-1.002/tutorial.scm: + Haxima changes: + o Bugfix: tutorial crashed on load because of my changes last night to the + kernel. NPC party creation using (mk-npc-party ...) must be held off until + after (kern-mk-player ...). + o Thorald in the tutorial responds to 'mixi' as well as 'mix' with instruction + on mixing spells. + + Kernel changes: + o Bugfix: vehicle save code was incorrect; resulted in a null object. + o Bugfix: last night's kernel changes broke reload. Fixed this by moving the + global player_party variable into a field of the global session struct (down + to one global variable now, yee-haa!). Added a player_party macro which + references this field for backwards-compatibility. + + * worlds/haxima-1.002/brundegardt.scm: + Tweaked the brundegardt fortress map again + + * worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/camping-map.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Haxima changes: + o Removed some debug spew. + o Tweaked brundegardt fortress map + + * worlds/haxima-1.002/gregor.scm: + Tweaked Gregor's conv + +2006-11-29 Gordon McNutt + + * src/character.cpp, src/foogod.c, src/nazghul.c, src/object.c, src/place.c, src/play.c, src/player.cpp, src/player.h, src/session.c, src/status.c, src/vmask.c: + Risky kernel change that should fix the LOS bug for real. It also partially + cleans up a big memory leak I've been ignoring since I added the main menu + loop. The gist of it is I know destroy the current session before falling back + to the main loop. This fixes the LOS bug by removing all the player-controlled + beings, and hence their map views. The LOS bug was caused by a leftover map + view from the previous session remaining active. I expect to find a few more + (maybe a lot more) bugs after this change that are related to improper + cleanup. Stand bye for asserts and seg faults. If it's too bad I'll back this + out and workaround the LOS bug with an evil hack instead. + + * worlds/haxima-1.002/Makefile.am: + Forgot to add a file to the distro list + + * worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/landslide.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm: + Added landslide to slope of Griffin Peak + + * worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Added griffin parties to wilderness encounters + + * worlds/haxima-1.002/wind-bridge.scm: + Wind bridge now delays two turns before rotating + +2006-11-28 Gordon McNutt + + * worlds/haxima-1.002/door.scm, worlds/haxima-1.002/traps.scm: + Haxima changes: + o S)earching doors now has some chance of detecting or tripping traps. + o Tweaked the difficulty stats on detecting/fumbling traps + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/npc-types.scm: + Haxima changes: + o Organized the effects a bit. + o When a sludge kraken dies it takes all its tentacles with it. + + * worlds/haxima-1.002/splash.png: + Changed splash screen + +2006-11-27 Gordon McNutt + + * src/character.cpp, src/cmd.c, src/cmd.h, src/ctrl.c, src/kern.c, src/object.c, src/object.h, src/place.c, src/player.cpp, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/hidden.scm, worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/rune.png, worlds/haxima-1.002/traps.scm: + S)earch now detects traps on chests, with a chance of setting them off. Doors + do NOT support this yet. + + Haxima changes: + o Containers implement the search ifc and roll to detect or trigger traps + o Traps triggered by a s)earch are removed + o Containers implement the describe ifc and list their detected traps + + Kernel changes: + o Reworked code for describing objects to support a hook for custom + descriptions + o Added kern-log-begin/continue/end + +2006-11-26 Kris Parker + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/mans-hideout.scm, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/thiefs_den.scm: + standardising on unabbreviated t_invisibility_potion. Mixing t_invisibility_potion and t_inv_potion was causing reusable chests + + * worlds/haxima-1.002/bandit-hideout.scm: + bandit stockade blended + + * worlds/haxima-1.002/brundegardt.scm: + blended new areas. Added some minor encounters to empty areas + + * worlds/haxima-1.002/brundegardt.scm: + 2 chests failing due to contents typos + + * worlds/haxima-1.002/combat-maps.scm: + combat maps blended + + * worlds/haxima-1.002/food.scm: + typo: s/wind/wine + + * worlds/haxima-1.002/mans-hideout.scm: + I think this fixes the man's chests + + * worlds/haxima-1.002/potions.scm: + removed total stats message on stat potions + +2006-11-26 Gordon McNutt + + * src/ctrl.c: + Kernel changes: + o Auto-targeting now respects LOS. + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/pitfalls.scm: + Haxima changes: + o Some files missing from Makefile.am + o Fixed typo in Gregor's conv + o Only pitfalls (eg caltrops) planted by player will affect NPC's + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Improvements to one of the brundegardt dungeon rooms: + o Sludge kraken tentacles chomp deck into sludge shallows + o Added sludge shallows (passable to most things) + o Sludge krakens summon a few more tentacles + + * worlds/haxima-1.002/bandit-hideout.scm: + Removing some caltrops + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/wind-bridge.scm: + Haxima changes: + o Chasms are now *very* unsafe for non-flying, non-abstract objects + + * worlds/haxima-1.002/npc-types.scm: + Rangers now use the ranger occupation + +2006-11-25 Kris Parker + + * src/map.c: + Removed clock from map (these days its possible to get the time in-game) + + * worlds/haxima-1.002/enchanters-tower.scm: + fixed script error after reload: mk-hidden must use 'object not object + + * worlds/haxima-1.002/gamestart.scm: + Reverting to diagonal pillars in startup room + + * worlds/haxima-1.002/kalcifax.scm: + Revert kalcifax to regular wizard sprite due to that bug with the mirrors and composite sprites + + * worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/silas.scm: + Some other sprites I'd missed earlier + +2006-11-25 Gordon McNutt + + * src/cmd.c: + When camping underground resting until sunrise is no longer an option + + * src/cmd.c, src/conv.c, src/conv.h, src/kern.c: + Minor feature enhancement: player and npc names highlighted in conversation + + * src/menus.c: + Changed localtime_r to localtime for Mingw portability + + * src/nazghul.c: + Flushing the vmask cache before starting a game to fix LOS bugs + + * src/nazghul.c, src/play.c: + Closing the window now exits the program instead of dropping back to the main menu + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/edward.scm, worlds/haxima-1.002/gamestart.scm, worlds/haxima-1.002/map.png, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/nate.scm: + Misc tweaks and fixes + + * worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/treasury.scm: + Bugfix: mk-treasure-chest needed to use a quoted list + + * worlds/haxima-1.002/kathryn.scm: + Permanent fix for Kathryn's response to 'scroll' + + * worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/tools.scm: + Sextant and In Wis both report location as [x= y=] + +2006-11-24 Gordon McNutt + + * src/astar.c, src/ctrl.c: + Disabling diagonal movement + + * src/character.cpp, src/character.h, src/ctrl.c: + Seems like every year I have to fix this bug again: Bill and Sue have both + readied flaming oil. There are two in party inventory. Bill throws, leaving + only one, but ostensibly he and Sue both still have the weapon readied. This is + a crash waiting to happen. This time I fixed it by forcing Bill to unready, but + allowing Sue to remain readied. + + * src/character.cpp: + Fixed another annoying must-be-in-follow-mode message when player is alone + + * src/cmd.c: + Bugfix: opening doors was not decrementing action points + + * src/kern.c: + Bugfix: kern-obj-get-name would (sometimes?) crash if the object had a null name + + * src/kern.c, src/map.c, worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/eye-of-brune.scm, worlds/haxima-1.002/sprites.scm: + kernel: + o Added kern-image-load + o Added kern-image-free + o Moved kern-map-set-image + + haxima: + o Added Eye of Brune to Brundegardt tower + + * src/menus.c: + Disabling the L)oad Game menu option. J)ourney Onward now works like L)oad + Game, with the most recently saved game always highlighted at the top by + default for quick access. If there is only one saved game then it just launches + it without showing the menu. + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/tim.scm, worlds/haxima-1.002/troll.scm: + Haxima changes: + o Trolls now hostile to generic monsters but less hostile to forest goblins. + o Finished adding NPC's to Griffin peaks and Brundegardt tower. + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm: + Started adding Griffins to the peak + + * worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/nate.scm, worlds/haxima-1.002/start-new-game.scm: + Tweaks to brundegardt + + * worlds/haxima-1.002/arms.scm: + Buffed slings a bit + +2006-11-23 Kris Parker + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/thorald.scm, worlds/haxima-1.002/warritrix.scm: + typo fixes for bug 1591311 + + * worlds/haxima-1.002/bole.scm: + bole grove reblended + + * worlds/haxima-1.002/bole.scm: + lake at bole reblended + + * worlds/haxima-1.002/kathryn.scm: + quick fix for bug 1601241: + kathryn automatically goes to "dont have one". Otherwise it pulls the scroll from *your* inventory + + * worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/sprites.scm: + some sprite tweaks + +2006-11-23 Gordon McNutt + + * src/kern.c, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/tools.scm: + kernel: + o Added kern-get-wind + o Added kern-place-add-on-entry-hook + o Moved facing support from Vehicle subclass up to base Object class + + haxima: + o Added a weather vane + o Added a wind bridge + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/items.scm, worlds/haxima-1.002/keys.scm: + Added doors-with-unique-keys + + * worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/start-new-game.scm: + Haxima changes: + o Filled out Brundegardt tower levels 1, 2 and 3. + +2006-11-22 Kris Parker + + * scripts/palette.txt: + tweaks to maptoxpm palette + + * worlds/haxima-1.002/monsters.png: + quick n dirty griffon cub + + * worlds/library/artwork/monsters/egg.xcf: + egg sprite + + * worlds/library/artwork/monsters/griffoncub.xcf: + old griffon sprite on bigger template to scale down by 0.66 + +2006-11-22 Gordon McNutt + + * src/kern.c, src/object.c, src/object.h, src/sprite.c, src/sprite.h, src/vehicle.cpp, src/vehicle.h, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/portcullis.scm, worlds/haxima-1.002/sprites.scm, worlds/library/artwork/monsters/kraken.xcf: + kernel: + o Added kern-get-wind + o Added kern-place-add-on-entry-hook + o Moved facing support from Vehicle subclass up to base Object class + + haxima: + o Added a weather vane + o Added a wind bridge + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/weather-vane.scm, worlds/haxima-1.002/wind-bridge.scm: + Adding files + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/monsters.png, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/start-new-game.scm: + Sprites for ratling NPC's + +2006-11-20 Gordon McNutt + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm: + Added Great Kraken + +2006-11-18 Gordon McNutt + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm: + Haxima changes: + o New npc: carabids (stone-munching beetles) + o Added objects to a few more brundegardt rooms + + * worlds/library/artwork/monsters/kraken.xcf: + Added new kraken image + +2006-11-17 Gordon McNutt + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/start-new-game.scm: + Haxima changes: + o Ratlings fear snakes + o Snakes eat rats and ratlings + +2006-11-16 Gordon McNutt + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/mimic.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/species.scm: + Haxima changes: + o Added mimic npc type + o Added objects to Brundegardt Keep + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/species.scm: + Haxima changes: + o Added ratling npc types (currently borrowing the forest goblin sprites) + o Added objects to Ratling Warren + +2006-11-15 Kris Parker + + * worlds/haxima-1.002/monsters.png, worlds/library/artwork/monsters/griffon.xcf: + griffon sprite + +2006-11-15 Gordon McNutt + + * worlds/haxima-1.002/brundegardt.scm: + Tweaks to dungeon rooms + + * worlds/haxima-1.002/brundegardt.scm: + Added a bunch of rooms to Brundegardt + +2006-11-14 Gordon McNutt + + * src/character.cpp, src/kern.c, src/species.c, src/species.h, worlds/haxima-1.002/species.scm: + kernel: + o Added an armor dice bonus to the species struct, for scaly and chitinous + critters. + + haxima: + o Updated to match kernel change. + + * worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/nate.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm: + Haxima changes: + o Started on another room for Brundegardt + o Started adding the Carabid NPC type + o Tweaked some conversations related to the Brundegardt quest + +2006-11-13 Kris Parker + + * worlds/haxima-1.002/humanoids.png, worlds/library/artwork/humanoids/ratling.xcf: + draft ratling + + * worlds/haxima-1.002/monsters.png, worlds/library/artwork/monsters/beetle.xcf: + an attempt at a beetle + + * worlds/library/artwork/monsters/beetle.xcf: + minor update + +2006-11-13 Gordon McNutt + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/anaxes.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/conv.scm: + Haxima changes: + o Added a procedure for interjecting party member comments in a conversation + o Added Anaxes + o Made the Cave Shrine map + + * worlds/haxima-1.002/brundegardt.scm: + Expanding Brundegardt + +2006-11-12 Gordon McNutt + + * worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/traps_1.scm: + Haxima changes: + o Made riddles slightly more general + o First pass at Entrance to Brundegart + +2006-11-11 Kris Parker + + * worlds/haxima-1.002/hirespeople.png, worlds/haxima-1.002/hirespeople.png, worlds/library/artwork/hirespeople/generic.xcf, worlds/library/artwork/hirespeople/old_ranger.xcf, worlds/library/artwork/hirespeople/ranger_captain.xcf: + Minor consistency tweaks + +2006-11-11 Gordon McNutt + + * worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/start-new-game.scm: + Haxima changes: + o Doubled starting reagents + o Restored start-of-game to release state + +2006-11-10 Gordon McNutt + + * src/object.c: + Fixed a recently-introduced bug in Object::setOnMap() that caused an assert in + combat_exit(). + + * src/scheme.c: + Hubert Maier's patch for Amiga OS + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/edward.scm: + Expanded Edward's conversation + + * worlds/haxima-1.002/edward.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/hirespeople.png, worlds/haxima-1.002/sprites.scm, worlds/library/artwork/hirespeople/generic.xcf: + artwork: + o Added some layers to the generic sprite + + haxima: + o Added an old townsman sprite, changed Gregor and Edward to use it + +2006-11-09 Gordon McNutt + + * worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/hirespeople.png, worlds/haxima-1.002/nate.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/start-new-game.scm, worlds/library/artwork/hirespeople/ranger_captain.xcf: + Added a sprite for Ranger Captain. Deric now uses it. + + * worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/hirespeople.png, worlds/haxima-1.002/sprites.scm, worlds/library/artwork/hirespeople/old_ranger.xcf: + Added an old ranger sprite. Gen uses it now. + +2006-11-06 Gordon McNutt + + * src/character.h, src/object.c, worlds/haxima-1.002/abigail.scm, worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/brundegardt.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/edward.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/nate.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/step.scm, worlds/haxima-1.002/traps.scm, worlds/haxima-1.002/zones.scm: + The Bandit quest (new quest for L1 players) is now pretty much done. + +2006-11-04 Gordon McNutt + + * worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/nate.scm, worlds/haxima-1.002/naz.scm: + Haxima changes: + o Deric gives player the bandit quest + o Added some generic ranger guards to Green Tower + o Player can recruit a generic ranger for the bandit quest + o Added Nate, the bandit leader + +2006-11-03 Gordon McNutt + + * src/character.cpp, src/cursor.cpp, src/kern.c, src/object.c, src/object.h: + Fixed Object::relocate() to distinguish between avoiding step triggers, sense + triggers, and both. + +2006-11-02 Kris Parker + + * src/object.c: + sense/step mechanisms need to be double checked after hooks are called since they may be destroyed in the process + + * worlds/library/artwork/humanoids/demon.xcf: + v2 demon + +2006-11-02 Gordon McNutt + + * src/Container.cpp, src/cmd.c, src/object.c, src/object.h, src/place.c, src/place.h, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/pitfalls.png, worlds/haxima-1.002/pitfalls.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/traps.scm: + Kernel changes: + o Fixed inventory saving/loading (recently broken) + o Fixed a bug that applied effects multiple time on startup (broken for a while + but I didn't know it) + + Haxima changes: + o Fixed saving from new game (recently broken) + o Fixed saving traps (recently broken) + o Fixed invisibility on pitfalls + o Pitfalls (caltrops and beartraps) can now be picked up and re-used + + * worlds/haxima-1.002/pitfalls.png: + Slightly better sprites for the caltrops and beartrap + +2006-11-01 Kris Parker + + * worlds/library/artwork/humanoids/demon.xcf: + Demon icon: first attempt + +2006-11-01 Gordon McNutt + + * worlds/haxima-1.002/Makefile.am: + Adding pitfalls.scm/png to the install list + +2006-10-31 Kris Parker + + * worlds/haxima-1.002/humanoids.png, worlds/library/artwork/humanoids/headless.xcf: + headless icon + +2006-10-31 Gordon McNutt + + * src/Attic/tile.c, src/Attic/tile.h: + Removing unused files + + * worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/pitfalls.png, worlds/haxima-1.002/pitfalls.scm, worlds/haxima-1.002/traps.scm: + Added caltrops and a beartrap + +2006-10-30 Kris Parker + + * worlds/haxima-1.002/humanoids.png: + troll geomancer icon + + * worlds/haxima-1.002/humanoids.png, worlds/library/artwork/humanoids/trollfighter.xcf, worlds/library/artwork/humanoids/trollmage.xcf: + troll icon + +2006-10-30 Gordon McNutt + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/traps.scm: + Haxima changes: + o Wis Sanct now lists the type of trap(s) attached to a chest or mechanism. + o An Sancy Ylem lists the type of trap(s) being disarmed. + o After a trap is detected with Wis Sanct, the chance of disarming it is + greatly improved. + +2006-10-29 Kris Parker + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm: + sprite updates + + * worlds/haxima-1.002/bigobjects.png, worlds/haxima-1.002/humanoids.png: + giants updated + + * worlds/library/artwork/humanoids/giant.xcf: + hairier giant + + * worlds/library/artwork/humanoids/giantmage.xcf: + giant mage + +2006-10-29 Gordon McNutt + + * src/Container.cpp, src/Container.h, src/cmd.c, src/kern.c, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/tutorial.scm: + THIS WILL BREAK ALL SAVED GAMES! + + Kernel changes: + o Stripped trap support from the Container class. Containers should only be + used for abstract inventory "objects" now. + o Removed kern-obj-is-trapped? and kern-obj-rm-trap. These are done in the + script now. + o Changed kern-mk-container to kern-mk-inventory and removed the type and trap + parms. + + Haxima changes: + o Modified code as necessary to deal with the above. + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/gamestart.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/Attic/player.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/traps.scm: + Haxima changes: + o Moved trap routines to their own file in traps.scm + o Removed the obsolete player.scm file + o Modified the character creation place: now that diagonal movement works the + player could miss the name prompt + o Changed all the places that refer directly to kern-mk-container to use one of + the wrapper functions in container.scm + + * worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/gate-guard.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/zane.scm: + Haxima changes: + o Changed everything to use the new-style containers. Character inventories + should be the only things that use the kernel Container class now. + + * worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/traps.scm: + Traps now implemented via a script object, instead of just a closure, so they can keep some state + +2006-10-28 Gordon McNutt + + * src/menus.c, src/menus.h, src/nazghul.c: + The function which displays the error message when the kernel can't find the + config files no longer uses sleep(); instead it lets the user close the window + normally. + +2006-10-27 Kris Parker + + * worlds/haxima-1.002/bigobjects.png: + area for 40x40 icons + + * worlds/haxima-1.002/humanoids.png, worlds/library/artwork/humanoids/cgoblinfighter.xcf, worlds/library/artwork/humanoids/cgoblinmage.xcf, worlds/library/artwork/humanoids/cgoblinslinger.xcf, worlds/library/artwork/humanoids/fgoblinarcher.xcf, worlds/library/artwork/humanoids/fgoblinfighter.xcf, worlds/library/artwork/humanoids/fgoblinmage.xcf: + lots of goblins + + * worlds/library/artwork/humanoids/cgoblinciv.xcf: + cave goblin paler + + * worlds/library/artwork/humanoids/giant.xcf: + meaner, hairier giant. Think it still needs more hair tho + +2006-10-27 Gordon McNutt + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/powers.scm: + Traps on doors now removable via An Sanct Ylem. + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/powers.scm: + Traps on doors now detectable via Wis Sanct. + +2006-10-25 Gordon McNutt + + * worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/start-new-game.scm: + Traps can now be added to chests or doors. + + * worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/containers.scm: + Added ability to attach traps to the new container implementation. An unlimited + number of traps is supported. Removing, detecting and disarming traps is not + yet supported. + + * worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/start-new-game.scm: + ;;---------------------------------------------------------------------------- + ;; Containers - objects that contain stuff + ;;---------------------------------------------------------------------------- + ;;---------------------------------------------------------------------------- + ;; Local Procedures + ;;---------------------------------------------------------------------------- + (define (add-content quantity type) + (list quantity type)) + + (define (mk-contents . contents) + (filter notnull? contents)) + + (define (roll-100 prob) + (>= prob (modulo (random-next) 100))) + + (define (roll-q dice type) + (add-content (kern-dice-roll dice) type)) + + (define (roll-to-add prob dice type) + (if (roll-100 prob) + (roll-q dice type) + nil)) + + ;;---------------------------------------------------------------------------- + ;; Container Types + ;;---------------------------------------------------------------------------- + (mk-obj-type 't_chest + "chest" s_chest + layer-container nil) + + ;;---------------------------------------------------------------------------- + ;; Container Constructors + ;;---------------------------------------------------------------------------- + (define (mk-chest trap contents) + ;;(println "mk-chest: " trap contents) + (kern-mk-container t_chest trap contents)) + + ;; mk-treasure-chest -- returns a chest with 1-10 random object types + (define (mk-treasure-chest) + (kern-mk-container t_chest + nil + (mk-treasure-list (+ 1 + (modulo (random-next) + 9))))) + + + ;;---------------------------------------------------------------------------- + ;; Corpse -- not really a container, if you search it then it sort of acts like + ;; opening a container + ;;---------------------------------------------------------------------------- + (define (corpse-mk loot) + (list loot)) + (define (corpse-loot corpse) (car corpse)) + (define (corpse-set-loot! corpse val) (set-car! corpse val)) + (define (corpse-loot-entry-q loot) (car loot)) + (define (corpse-loot-entry-type loot) (eval (cadr loot))) + + (define (corpse-search kobj) + (let* ((corpse (kobj-gob-data kobj)) + (loot (corpse-loot corpse))) + (if (not (null? loot)) + (let ((loc (kern-obj-get-location kobj))) + (map (lambda (entry) + (kern-obj-put-at (kern-mk-obj (corpse-loot-entry-type entry) + (corpse-loot-entry-q entry)) + loc)) + loot) + (corpse-set-loot! corpse nil))))) + + (define corpse-ifc + (ifc nil + (method 'search corpse-search))) + + (mk-obj-type 't_corpse "corpse" s_corpse layer-item corpse-ifc) + + (define (mk-corpse) + (bind (kern-mk-obj t_corpse 1) + (corpse-mk nil))) + + ;; mk-corpse2 -- loot: a list of (quantity type) lists + (define (mk-corpse2 loot) + (bind (kern-mk-obj t_corpse 1) + (corpse-mk loot))) + + (define (mk-corpse-with-loot) + (mk-corpse2 (mk-quoted-treasure-list (+ 1(modulo (random-next) + 3))))) + + ;;---------------------------------------------------------------------------- + ;; This next section is an experimental new container type. It attempts to + ;; bypass the kernel's built-in Container class and implement everything in the + ;; script as a normal kernel Object that responds to the 'open signal the same + ;; way a kernel Container would respond to the open command. + ;; + ;; This currently works. The next step is to implement the ability to add (and + ;; remove or disable) traps on a container. The means of doing so will be + ;; implemented here in the script, so the kernel won't need to know about + ;; trapped containers when this all works, and the kernel's Container class can + ;; be stripped back to a basic Inventory class. + + ;; Define the gob structure and procedures. The contents should be a single + ;; quoted list, for example: + ;; + ;; '((t_sword 1) + ;; (t_arrow 5) + ;; (t_torch 2))) + ;; + ;; Using the quotes is not only cleaner in the declarations, it automatically + ;; ensures that the contents are safe to save and reload as part of the gob + ;; because they are stored in the gob merely as symbols. + ;; + ;; Each container has a (often empty) list of traps, where each trap is the + ;; symbol for a procedure of the form (foo ). The symbol is + ;; used instead of the actual procedure so that the list of traps can be saved + ;; and re-loaded. + ;; + (define (mk-container contents) (list 'container contents nil)) + (define (is-container? gob) (eq? (car gob) 'container)) + (define (container-contents gob) (car (cdr gob))) + (define (container-traps gob) (car (cdr (cdr gob)))) + (define (container-set-traps! gob traps) (set-car! (cdr (cdr gob)) traps)) + (define (content-type content) (car content)) + (define (content-quantity content) (cadr content)) + (define (container-add-trap! gob trap) + (container-set-traps! gob + (cons trap + (container-traps gob)))) + + ;; This is the heart of the implementation. This procedure runs when the + ;; container object gets the 'open signal, which is sent by the kernel in + ;; response to the player's o)pen command followed by selection of this + ;; object. It expects kobj to be a kernel object which is bound to a container + ;; gob following the above format (the constructors further down illustrate how + ;; to create such an object). + ;; + ;; Opening the container creates objects based on the types and quantities + ;; listed in the container's content list and deposits these objects on the + ;; ground where the container is. Then it removes the container, which likely + ;; results in its destruction. + ;; + ;; Before opening this applies all the traps attached to the container. Note + ;; that the self-destruct trap, as currently implemented, does not work as + ;; expected, because it relies on the removal of the container from the map as + ;; a means of destroying it; and that is not sufficient here. + (define (kcontainer-open kobj kchar) + (let ((container (kobj-gob-data kobj)) + (loc (kern-obj-get-location kobj)) + (thief-dice (string-append "1d" (number->string (occ-ability-thief kchar)))) + ) + (println container) + + ;; Applying traps can destroy both kobj and kchar + (kern-obj-inc-ref kobj) + (kern-obj-inc-ref kchar) + + ;; Apply traps + (map (lambda (trap) + (let ((roll (kern-dice-roll "1d20")) + (bonus (kern-dice-roll thief-dice))) + (println trap " roll:" roll "+" bonus) + (cond ((or (= roll 20) + (> (+ roll bonus) 20)) + (kern-log-msg (kern-obj-get-name kchar) " avoids a trap!")) + (else + (kern-log-msg (kern-obj-get-name kchar) " trips a trap!") + (apply (eval trap) (list kchar kobj)))))) + (container-traps container)) + + ;; Spill contents + (map (lambda (content) + (println content) + (let ((newobj (kern-mk-obj (eval (content-type content)) + (content-quantity content)))) + (kern-obj-put-at newobj loc))) + (container-contents container)) + + ;; Remove the container from the map + (kern-obj-remove kobj) + + ;; Done with references + (kern-obj-dec-ref kobj) + (kern-obj-dec-ref kchar) + )) + + ;; This interface binds the 'open signal to our open procedure above. + (define container-ifc + (ifc '() + (method 'open kcontainer-open))) + + ;; This constructor makes new types of objects that conform to the container + ;; interface above. An example of usage is below, where I make a new chest + ;; type. + (define (mk-container-type tag name sprite) + (mk-obj-type tag name sprite layer-mechanism container-ifc)) + + + ;; Test it out. First, make a new chest type. + (mk-container-type 't_chest2 "chest" s_chest) + + ;; Define a constructor for an object of the new chest type. Example usage: + ;; + ;; (put (mk-chest2 '((t_sword 1) + ;; (t_arrow 5) + ;; (t_torch 2))) + ;; 5 8) + ;; + ;; * Note the use of a quoted list. + ;; + (define (mk-chest2 ktype-q-pairs) + (bind (kern-mk-obj t_chest2 1) + (mk-container ktype-q-pairs))) + + (define (chest2-add-trap kobj trap) + (container-add-trap! (kobj-gob-data kobj) trap)) + +2006-10-24 Gordon McNutt + + * worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/containers.scm: + Started a new implementation of container objects (like chests) that will be + done entirely in the script. This is a preliminary step to adding traps on + doors and other non-container mechanisms. + +2006-10-23 Gordon McNutt + + * src/object.c, worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/bandit-hideout.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/step.scm: + Kernel changes: + o Bugfix: the crosshair object was triggering sense mechanisms + + Haxima changes: + o Started a new entry-level quest dungeon for L1 players + +2006-10-21 Gordon McNutt + + * src/ascii.c, src/status.c: + Fixed some compiler errors and warnings that occur with newer versions of g++ + + * worlds/haxima-1.002/start-new-game.scm: + I keep forgetting to undo my test changes to start-new-game.scm... + +2006-10-20 Gordon McNutt + + * src/cmd.c, src/cmdwin.c: + Fixed some command error messages that were only being printed to the cmdwin, where they were promptly erased before the player could read them + +2006-10-15 Kris Parker + + * worlds/library/artwork/humanoids/cgoblinciv.xcf: + basic cave goblin + + * worlds/library/artwork/humanoids/deadknight.xcf: + Deathknight glow effects tweaked + + * worlds/library/artwork/humanoids/fgoblinciv.xcf: + smaller goblin + + * worlds/library/artwork/humanoids/giant.xcf: + draft giant/ettin + +2006-10-14 Kris Parker + + * worlds/library/artwork/humanoids/fgoblinciv.xcf: + first attempt at forest goblins + +2006-10-14 Gordon McNutt + + * src/map.c, src/sprite.c: + Added initial support for giant sprites. + +2006-10-13 Kris Parker + + * worlds/haxima-1.002/hirespeople.png: + tonights icons in 32x32 + + * worlds/library/artwork/hirespeople/beggar.xcf: + beggar icon + + * worlds/library/artwork/hirespeople/child.xcf, worlds/library/artwork/hirespeople/generic.xcf: + child icon added. generic townsman cleaned up + + * worlds/library/artwork/hirespeople/fencer.xcf: + the companion_bard icon isnt used anywhere according to grep. (probably too generic looking). Anyway, Ive put together this 2 weapon fencer to get rid of the gaping hole in my icons page + + * worlds/library/artwork/hirespeople/fighter.xcf, worlds/library/artwork/hirespeople/paladin.xcf: + fighter/paladin given shoulderguards + + * worlds/library/artwork/hirespeople/jester.xcf: + jester icon + + * worlds/library/artwork/hirespeople/knight.xcf: + knight icon + + * worlds/library/artwork/hirespeople/minstrel.xcf: + minstrel icon + + * worlds/library/artwork/humanoids/deadknight.xcf: + animated armour icon + +2006-10-12 Kris Parker + + * worlds/haxima-1.002/hirespeople.png, worlds/library/artwork/hirespeople/fatwoman.xcf: + fat woman sprite + + * worlds/haxima-1.002/hirespeople.png, worlds/library/artwork/hirespeople/lady.xcf: + lady sprite + + * worlds/haxima-1.002/hirespeople.png, worlds/library/artwork/hirespeople/cloackedf.xcf, worlds/library/artwork/hirespeople/rmage.xcf, worlds/library/artwork/hirespeople/rogue.xcf, worlds/library/artwork/hirespeople/roguef.xcf, worlds/library/artwork/hirespeople/xbowman.xcf: + more sprites + +2006-10-11 Kris Parker + + * worlds/haxima-1.002/hirespeople.png, worlds/library/artwork/hirespeople/avatar.xcf, worlds/library/artwork/hirespeople/shopkeep.xcf, worlds/library/artwork/hirespeople/shopkeepf.xcf: + new: female shopkeeper, avatar + shopkeeper now uses mages body weight, instead of fighters + +2006-10-10 Kris Parker + + * worlds/haxima-1.002/hirespeople.png, worlds/library/artwork/hirespeople/druid.xcf: + new druid icon + + * worlds/haxima-1.002/hirespeople.png: + shepherd icon replaced + + * worlds/haxima-1.002/hirespeople.png: + initial batch of highres people icons + + * worlds/library/artwork/hirespeople/enchanter.xcf, worlds/library/artwork/hirespeople/fighter.xcf, worlds/library/artwork/hirespeople/generic.xcf, worlds/library/artwork/hirespeople/mage.xcf, worlds/library/artwork/hirespeople/necromancer.xcf, worlds/library/artwork/hirespeople/paladin.xcf, worlds/library/artwork/hirespeople/pikeman.xcf, worlds/library/artwork/hirespeople/ranger.xcf, worlds/library/artwork/hirespeople/shopkeep.xcf, worlds/library/artwork/hirespeople/silas.xcf, worlds/library/artwork/hirespeople/tinker.xcf, worlds/library/artwork/hirespeople/wanderer.xcf: + initial batch of highres icon working files + + * worlds/library/artwork/hirespeople/shepherd.xcf: + shepherd icon + +2006-10-06 Gordon McNutt + + * src/ascii.c, src/images.c, src/nazghul.c, src/screen.c: + Added a C source code XPM to provide a set of "emergency" ASII images. These + are used to display a crude error message in a window if nazghul encounters an + error during or before it can load the basic init script. + +2006-10-04 Gordon McNutt + + * src/cmd.c, src/cmd.h, src/conv.c, src/conv.h, src/menus.c, src/sched.c, src/sched.h: + o Bugfix: the filename prompt from the Save Game menu allowed invalid and + undesirable characters for filenames + o Bugfix: t)alking to an NPC when hostiles present caused assert + o Bugfix: deleting a saved game with a non-existent save file caused assert + o Bugfix: entering '%' during conversation caused a crash + o Bugfix: entering '^' during conversation caused error messages and problems + with text colors + +2006-10-03 Gordon McNutt + + * src/character.cpp, src/character.h, src/ctrl.c: + Improved fleeing by another notch. Fleeing NPC's in town or wilderness combat + now attempt to pathfind to the nearest edge. Failing that, they fall back on + evasion. Failing that, they fall back on fighting. + +2006-10-02 Gordon McNutt + + * src/astar.h, src/character.cpp, src/character.h, src/ctrl.c: + o Improved the algorithm used by NPCs to flee. It now uses the basic adaptvie + evasion algorithm where it tries to run away from current hostile + positions. If a fleeing NPC gets stuck it doesn't just sit there helplessly, + but will turn and fight. More improvements are planned. + +2006-10-01 Gordon McNutt + + * src/character.cpp, src/sched.h: + o Bugfix: "angry townfolk wont move or attack past their assigned + locations, making them pretty much sitting ducks". If hostiles are present, + the schedule is ignored and the AI run instead. + + * src/cmd.c, src/result.h, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/powers.scm: + o Added a new result code from spells: result-no-hostiles + o The area effect sleep spell now returns result-no-hostiles if there are none, + so the console can tell the player why his sleep spell has no effect in town. + +2006-09-30 Gordon McNutt + + * doc/USERS_GUIDE, src/astar.c, src/cmd.c: + o Pathfinding code now uses diagonals + o Made the '5' key on the keypad mean "select" in the movecursor function + o When buying/selling, reverted foogod window to show party gold instead of UI + hints + + * src/character.cpp: + o Bugfix: t)alk auto-targeting broken. I don't think it was actually + broken. Anyway, I can't reproduce it now. But I did fix something similar: + when reloading a saved game NPC's are no longer teleported to the upper left + corner of their appointment rectangle if they are already in the + rectangle. Without this NPC's could get stacked on the same tile on reload, + making the auto-targeting appear to "stick" on a character when it was + actually cycling over the characters hidden below it. + + * src/cmd.c: + Tying to cast non-existend spells results in a None Mixed! error, so player cannot guess at spells without mixing them + + * src/cmd.c, worlds/haxima-1.002/scrolls.png, worlds/haxima-1.002/scrolls.scm: + Kernel changes: + o Bugfix: x)amine with x-ray no longer says "Can't see!" + + Haxima changes: + o Added a Wis An Ylem (x-ray) scroll and sprite. + + * src/cmd.c, src/combat.c, src/menus.c: + o Bugfix: NPC's attacking on diagonal hit assert + o When showing saved game screen screen shots, moved the "SCREEN SHOT" text + higher so the center is visible. + + * src/cmd.c, src/ctrl.c, src/menus.c: + o Added diagonal movement using number keypad. + o Made the '5' key on the keypad mean "select" in most menus. + o Bugfix: cmdwin prompts had extra '-' in camping command + + * src/object.c: + o Workaround: for [SF 1564243], crash on reload. The root cause is improper + order of destruction of objects. A good fix would use reference counts to + control that, but implementing it would probably add lots of new bugs, so I'm + too chicken to do it right now. I've logged a feature request to address this + when I'm feeling more courageous (or when this workaround proves to be + insufficient). + + * worlds/haxima-1.002/goblin-kingdoms.scm: + Added some corpses to troll's den + +2006-09-29 Gordon McNutt + + * src/menus.c, src/status.c, src/status.h: + Page up/down and Home/end now work with the saved game menus and other string or generic lists + + * src/nazghul.c: + When the game ends it falls back to the main menu. + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/goblin-kingdoms.scm: + o Bugfix: fireball spell was being cast on the caster, not the target + o Added more combatants to the Goblin Crossroads dungeon room battle + o Added loot chests to the Shamans Grove dungeon room + + * worlds/haxima-1.002/ai.scm: + Removing some debug + + * worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/start-new-game.scm: + Added more loot to Roland's cave + +2006-09-28 Gordon McNutt + + * src/menus.c, src/status.c, src/status.h: + Added a delete command to the load/save menus so players can delete saved games they don't want anymore. + + * src/menus.c: + N)ew Game is now always top on the Save Game menu, and current saved game is always next + +2006-09-27 Gordon McNutt + + * src/menus.c, src/status.c, src/status.h: + Hacked-in hotkeys for the main menus + +2006-09-26 Kris Parker + + * worlds/haxima-1.002/Makefile.am: + updated makefile + +2006-09-26 Gordon McNutt + + * src/ascii.c, src/cmd.c, src/cmd.h, src/foogod.c, src/foogod.h, src/kern.c, src/menus.c: + The foogod window now has a hint mode, where it can show UI hints + + * src/cmd.c: + Only one AP taken per mix command + + * worlds/haxima-1.002/charset.png: + Added symbols for sideways arrows + +2006-09-25 Gordon McNutt + + * src/map.c, src/map.h, src/menus.c, src/nazghul.c, src/play.c: + Saved-game screenshots implemented, not fully tested yet + +2006-09-24 Kris Parker + + * worlds/haxima-1.002/enchanters-tower-mech.scm, worlds/haxima-1.002/enchanters-tower.scm: + more wierdness for enchy's new lab + + * worlds/haxima-1.002/enchanters-tower-mech.scm, worlds/haxima-1.002/enchanters-tower.scm: + Enchanters tower expanded + + * worlds/haxima-1.002/tools.scm: + clocks are impassable + + * worlds/haxima-1.002/tools.scm: + gems work with new spell system + added invisible object based wall + +2006-09-24 Gordon McNutt + + * src/map.c, src/map.h, src/menus.c, src/screen.c, src/screen.h: + o Added screenCapture(), which will save some or all of the current screen to a + PNG file. + o Saved-game screenshots partially implemented. Saving a game creates a + screenshot of the map named after the save file. The screenshots aren't yet + shown in the load/save menus. + +2006-09-23 Gordon McNutt + + * src/list.h, src/menus.c: + o Re-organized the code that handles saved games to use a struct. + o The saved games are now presented in order sorted by save time, youngest + first. + + * src/menus.c, src/menus.h: + o Menus now cache the saved game list instead of re-evaluating the script every + time for the save/load menus. + o When a game is saved, the saved name becomes the new "current" game. + o The current game is always listed at the top of the load/save list and is + highlighted by default for quick access. Other saves continue to be listed in + timestamp order, oldest last. + +2006-09-22 Kris Parker + + * worlds/haxima-1.002/powers.scm: + field spells have variable duration + +2006-09-22 Gordon McNutt + + * src/Party.cpp, src/cmd.c, src/kern.c, src/menus.c, src/status.c, src/status.h: + Generic and string lists now specify titles in the status UI + + * src/menus.c: + The filename for the currently loaded game is marked with an '*' in the load and save menus. + +2006-09-21 Kris Parker + + * src/object.c: + fixed crash due to my last "fix" using obj_dec_ref too often + +2006-09-21 Gordon McNutt + + * doc/MAP_HACKERS_GUIDE: + Added some basic map-editing instructions + + * src/cmd.c, src/menus.c, src/nazghul.c: + Dates now added to save game menu + + * src/dimensions.c, src/dimensions.h: + Bugfix: STAT_W was counting the frame boundaries + + * src/menus.c: + Bugfix: after choosing from the Load Saved Game menu, it would repaint but your selection would have not data + + * src/menus.c: + Added dates to the Load Saved Game menu options + + * worlds/haxima-1.002/Makefile.am: + Bugfix: some new files missing in the install list + + * worlds/haxima-1.002/scrolls.scm: + Temp hack to keep saved games working with old scroll names + +2006-09-20 Kris Parker + + * src/clock.c, src/clock.h, src/status.c: + effects display allows remaining duration and unknown duration + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + spell cleanups + + * worlds/haxima-1.002/effects.scm: + another attempt at a light spell + +2006-09-20 Gordon McNutt + + * src/menus.c, src/menus.h, src/scheme.c: + Journey Onward now loads most recently saved game. Load Game lets the player pick from available saved games. + +2006-09-19 Kris Parker + + * src/object.c: + fixed crash in ifc sense handling when cutscene deleted mech + + * worlds/haxima-1.002/cast-ui.scm: + vas rel por reinstated + +2006-09-18 Kris Parker + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/mans-hideout.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/scrolls.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/thiefs_den.scm, worlds/haxima-1.002/tooth.scm: + most spells debugged + +2006-09-18 Gordon McNutt + + * worlds/haxima-1.002/adornments.png, worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/sprites.scm: + o Moved paper-doll staff (and glow) to arms.png + o Added paper-doll halberd + +2006-09-17 Kris Parker + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + new spell- web + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/enchanters-tower.scm: + a spellbook for one of the new spells + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm: + spell bug fixes + + * worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + book shelf object + +2006-09-16 Kris Parker + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + more spell updating ... level 8! + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + more spell updating 7 + +2006-09-16 Gordon McNutt + + * doc/MAP_HACKERS_GUIDE, src/kern.c, src/object.c, src/sprite.c, src/sprite.h, worlds/haxima-1.002/arms.scm: + Kernel changes: + o Added kern-sprite-blit-over to allow layered non-composite sprites. + 0 Bugfix when reloading a game that involves type gobs. + + Haxima changes: + o Made the staff "ready" sprite be blitted instead of composite. This preserves + its glow effect across a ready/unready cycle. + + * src/kern.c, src/sprite.c, src/sprite.h, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/species.scm: + Kernel changes: + o Added kern-sprite-strip-decorations to facilitate rebuilding decorated + sprites + + Haxima changes: + o Changed the slot ordering for species to follow the rendering order for paper + dolls. + o Fixed the ready/unready effect hooks to rebuild the character's sprite if it + supports a paper-doll. + o Modified the staff arms type to store the paper-doll staff sprite in the type + gob. + + * src/kern.c, src/sprite.c, src/sprite.h: + Got rid of kern-sprite-tint; apply-matrix is better + + * worlds/haxima-1.002/naz.scm: + Made a version of mk-composite-sprite which doesn't clone the base sprite + +2006-09-15 Kris Parker + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + more spell updating + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + more spell updating 6 + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + more spell updating 5 + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + more spell updating 4 + +2006-09-14 Kris Parker + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + more spell updating + + * worlds/haxima-1.002/sprites.scm: + fixed sprites off by one + +2006-09-13 Gordon McNutt + + * doc/MAP_HACKERS_GUIDE: + Cleaned up the introduction + + * doc/MAP_HACKERS_GUIDE: + Added docs for kern-type-set/get-gob and comments about object types and gobs + + * src/Party.cpp, src/character.cpp, src/closure.c, src/closure.h, src/ctrl.c, src/object.c, src/object.h, src/place.c: + o Object hooks now run with variable argument lists. + + * src/character.cpp, src/kern.c, src/object.c, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/start-new-game.scm: + Kernel changes: + o Changed kern-obj-type-set/get-gob to kern-type-set/get-gob + o Added Scheme-to-kernel conversions for the ready/unready hook names + o Bugfix: character was using a bad format arg for runHook() call + + Haxima changes: + o Added a placeholder ready and unready effect that just print the equipment + name and the affected slot. + + * src/character.cpp, src/kern.c, src/object.c: + o Character's now run the "ready" and "unready" hooks + o Added kern-obj-type-set/get-gob + +2006-09-12 Kris Parker + + * worlds/haxima-1.002/tools.scm: + fixed mirror/clock pclass being lost on reload + +2006-09-12 Gordon McNutt + + * src/character.cpp, src/closure.c, src/closure.h, src/object.c, src/object.h, src/sprite.c: + A few preliminary changes needed for the READY/UNREADY hooks + + * src/scheme.c: + Fixed the 'mismatched parenthesis: -1' error emitted by scheme when a file ends in ) + +2006-09-11 Gordon McNutt + + * worlds/haxima-1.002/adornments.png, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/sprites.scm: + o Added a staff and a staff glow sprite for wizards. + + * worlds/haxima-1.002/adornments.png, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm: + o Added some humanoid hair sprites. + + * worlds/haxima-1.002/bodies.png, worlds/haxima-1.002/clothes.png, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/start-new-game.scm: + o Added two more frames to the body and the robe template sprites. + o Added a mantle sprite to wear over robes. + +2006-09-10 Kris Parker + + * src/character.cpp, src/character.h, src/cmd.c, src/object.c, src/object.h, src/place.c, src/place.h: + first pass at detailed xamine + + * src/kern.c: + added kern-stdout-msg to log to stdout + + * src/object.c, src/object.h: + new standard ifc: 'sense' to detect all incoming/outgoing objects + + * worlds/haxima-1.002/addons.png: + switch icon symetry fixed so they dont move when flipped + + * worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + more spell sorting + + * worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/tools.scm: + clocks xamineable + + * worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/step.scm: + sense ifc scheme implementation + + * worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + improved mirror + +2006-09-10 Gordon McNutt + + * doc/MAP_HACKERS_GUIDE: + Time to start updating this + + * src/Missile.cpp, src/character.cpp, src/kern.c, src/object.c, src/sprite.c, src/sprite.h, worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/adornments.png, worlds/haxima-1.002/bodies.png, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/clothes.png, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/step.scm, worlds/haxima-1.002/tools.scm: + Kernel changes: + o Objects now save their custom sprites, if they have any, by generating a + kern-obj-set-sprite call. + o Objects now use a 'let' block when saving themselves. + o Cloned sprites now take an optional tag. If none is provided their tag is set + to NULL. + o Composite sprites now save themselves. + o Added kern-sprite-apply-matrix, which will apply a color-correction matrix to + a sprite in order to change its color scheme. + + Haxima changes: + o Calls to kern-sprite-clone update to pass the tag. + o Added 3 new sprite sets for paper doll development (bodies, adornments and + clothes). + o Added an example call to kern-sprite-apply-matrix which turns a gray robe + blue. + o The enchanter now uses a paper doll sprite. + o The sensor object now takes its target as a tag so it can save/reload. + o The mirror object now takes its background sprite as a tag so it can + save/reload properly. + + * src/sprite.c, worlds/haxima-1.002/bodies.png, worlds/haxima-1.002/clothes.png, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/start-new-game.scm: + Kernel changes: + o Fixed a bug in sprite_apply_matrix. Only the first frame of multi-frame + sprites was being processed correctly. Also added some minor speed hacks. + + Haxima changes: + o Added another animation frame to the body and robe sprites. + + * worlds/haxima-1.002/start-new-game.scm: + Oops. Didn't mean to check in this file on the last commit. + +2006-09-06 Gordon McNutt + + * src/sprite.c: + o Tinted sprites now use caching to improve rendering speed. + + * src/sprite.c: + Added sprite_new_internal() to pave the way for optimized tinted sprites + + * src/sprite.c: + Fixed faded sprites to work with new RGBA images + +2006-09-05 Gordon McNutt + + * src/Missile.cpp, src/cmdwin.c, src/kern.c, src/map.c, src/nazghul.c, src/object.c, src/place.c, src/play.c, src/player.cpp, src/screen.c, src/sky.c, src/sprite.c, src/sprite.h, src/status.c, src/Attic/tile.c, src/vehicle.cpp: + o Cleanup: changed sprite API to consistently use underscores instead of + mixed-case. + + * src/Party.cpp, src/character.cpp, src/cmd.c, src/cmd.h, src/ctrl.c, src/kern.c, src/place.c, src/player.cpp, src/session.c, src/sky.c, src/sprite.c, src/sprite.h, src/vehicle.cpp: + o Made the sprite definition hidden outside of sprite.c. + o Removed the cmdDumpPalette function as a result of the above. I don't think + anyone uses it anymore. + + * src/sprite.c: + o Cleanup: removed obsolete references to palettized surfaces from sprite.c. + +2006-09-03 Gordon McNutt + + * src/cmd.c, src/cmd.h, src/kern.c: + Added the a)ttack cursor movement shortcut keys to t)alk and targeted spells. + + * src/kern.c, src/sprite.c, src/sprite.h: + Initial (and very inefficient) cut at sprite-tinting. + + * worlds/haxima-1.002/spells.scm: + Bugfix in grav por + +2006-09-01 Kris Parker + + * worlds/haxima-1.002/absalot.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/portals.scm: + Added many clocks + + * worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/tools.scm: + New furniture- mirrors + +2006-08-31 Kris Parker + + * worlds/haxima-1.002/abandoned-farm.scm, worlds/haxima-1.002/tools.scm: + Broken clock available. Example at abandoned farm + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/cast-ui.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/powers.scm, worlds/haxima-1.002/spells.scm: + 1st circle spells with split off ui and caster stats + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/tools.scm: + Clock faces show approximate time + +2006-08-30 Kris Parker + + * worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + clock icon v3 + +2006-08-29 Kris Parker + + * worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/trigrave.scm: + A few clocks added to the world. + + * worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + Not entirely happy with the icon yet, but heres a clock town feature + +2006-08-28 Kris Parker + + * doc/null.gif, doc/users_guide.html: + 2nd pass at manual. + + * doc/users_guide.html, scripts/tocinator.pl: + autogenerated table of contents for manual + + * doc/users_guide.html: + Manual setup notes added as comment + +2006-08-27 Kris Parker + + * doc/users_guide.html: + First pass at html manual. Still a fair amount of cleaning up needed + + * src/clock.c, src/clock.h, src/cmd.c: + at gives vague description rather than accurate time + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/shapes.png: + alpha tweaks + + * worlds/haxima-1.002/arms.png, worlds/haxima-1.002/potions.png: + arms and potion sprites alphanated + + * worlds/haxima-1.002/books.png, worlds/haxima-1.002/food.png, worlds/haxima-1.002/jewelry.png: + transparent shadows + + * worlds/haxima-1.002/effects.png: + Global effects (timestop, quicken, antimagic) given effect icons + + * worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + added an in-game clock + +2006-08-27 Gordon McNutt + + * src/ascii.c, src/screen.c, worlds/haxima-1.002/charset.png: + Support for 32 bit-per-pixel colored text added to ascii.c. Screen + bits-per-pixel changed to 32, and charset.png updated to the 32 PNGA version. + + * src/cmd.c: + Fixed a couple of bugs in X)amine caused by recent cursor-movement changes + + * src/images.c: + Transparent blitting now works for images with an alpha channel. + + * src/screen.c: + Hack to support scaling images with alpha channel. + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/books.png, worlds/haxima-1.002/food.png, worlds/haxima-1.002/jewelry.png, worlds/haxima-1.002/money.png, worlds/haxima-1.002/moons.png, worlds/haxima-1.002/newfolks.png, worlds/haxima-1.002/newmonst.png, worlds/haxima-1.002/newterrain.png, worlds/haxima-1.002/reagents.png, worlds/haxima-1.002/rune.png, worlds/haxima-1.002/runestones.png, worlds/haxima-1.002/scrolls.png, worlds/haxima-1.002/shapes.png, worlds/haxima-1.002/special.png, worlds/haxima-1.002/tools.png: + Updated images to John's RGBA versions + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/start-new-game.scm: + Moved max-health to game.scm so it will be defined even for saved games + +2006-08-26 Kris Parker + + * src/Party.cpp, src/Party.h, src/combat.c, src/player.cpp: + characters at top of party list move first and are placed further into maps on entry + +2006-08-26 Gordon McNutt + + * src/Makefile.am, src/screen_dims.h: + Forgot to add a new file on my last + + * src/ascii.h, src/cfg.c, src/cfg.h, src/character.cpp, src/cmd.c, src/cmd.h, src/ctrl.c, src/dimensions.c, src/kern.c, src/menus.c, src/menus.h, src/nazghul.c, src/sound.c, src/sound.h, src/status.c: + o Added a Settings menu to change the screen size and turn sound on and + off. This is accessible from the startup menu or via the F10 key. + o Changed the way the status browser handles generic list selection. Instead of + always switching to tall mode it sets its height based on the number of entries + in the list. + +2006-08-24 Kris Parker + + * src/cmdwin.c: + cmdwin_vpush now +1 vs nullpointers + +2006-08-20 Kris Parker + + * doc/USERS_GUIDE, worlds/haxima-1.002/arms.scm: + all weapons bonusized + + * scripts/blenddat.txt: + re-blending rivers was broken + + * src/Arms.cpp, src/Arms.h, src/kern.c, worlds/haxima-1.002/arms.scm: + bonus modifiers shifted out to arms.scm + + * src/Arms.cpp, src/Arms.h, src/character.cpp, src/character.h, src/ctrl.c: + Instead of using fixed bonus modifiers, combat now queries them from weapons (which use fixed bonus modifiers- sigh) + + * worlds/haxima-1.002/arms.scm: + melee weapon bonuses set + +2006-08-20 Gordon McNutt + + * doc/USERS_GUIDE, src/Missile.cpp, src/Party.cpp, src/character.cpp, src/cmd.c, src/cmd.h, src/kern.c, src/object.c, src/player.cpp, src/vehicle.cpp, src/vehicle.h, worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/prices.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + o You can now sink empty ships with cannons. + o You can sell surplus ships to Bart in Oparine. + o You can name your ship when you board. Unnamed deserted ships will disappear + from the map after some time has passed. + o Tweaked down the sea monster encounters. Monotonous. + o Temporary NPC parties weren't saving their time-to-live, so on reload they + were permanent, meaning they accumulated until the player encountered them. + + * src/cmd.c: + Pressing a digit followed by the arrow key will make the cursor jump that distance when targeting + + * src/cmd.c, src/cmd.h, src/ctrl.c, src/kern.c: + Added shortcut keys for moving attack cursor + + * src/ctrl.c: + Targeting self for attack switches weapons + +2006-08-19 Kris Parker + + * src/character.cpp: + (x % 0) does nasty things to the system, so adding one to base attack/defense bonus. + + * src/character.cpp: + groupExitTo calling closure_exec with NULL caused crash + + * src/character.cpp, src/character.h, src/ctrl.c, src/kern.c, src/session.c, src/session.h, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/occs.scm: + First pass at stats affecting combat + +2006-08-19 Gordon McNutt + + * src/Party.cpp, src/cmd.c, src/cmdwin.c, src/cmdwin.h, src/conv.c, src/ctrl.c, src/kern.c, src/menus.c, src/player.cpp, src/status.c, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/jess.scm: + Re-wrote the cmdwin API and updated callers + + * src/closure.c: + Another way to fix closure_exec(0) + + * src/closure.c: + closure_exec() now coerces returned floating-point values to ints + + * src/cmd.c, src/event.c, src/event.h: + Mouse targeting done + + * src/cmd.c, src/event.c, src/map.c, src/map.h: + Initial hack at mouse targeting + + * src/cmdwin.c: + cmdwin now right-justifies if string is too long to fit in window + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/shapes.png, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Added dirt and gravel terrain + + * worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/potions.png, worlds/haxima-1.002/potions.scm: + Added some potion sprites + + * worlds/haxima-1.002/arms.scm: + Needs some polish, but I had to add Vial of Slimes before I forgot about it + + * worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/tooth.scm: + Vials of slime + +2006-08-17 Kris Parker + + * worlds/haxima-1.002/ability.scm: + Ok, the fireball now mostly does what I want, but its awfally hacky + +2006-08-16 Kris Parker + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/arms.scm: + first pass at more interesting fireball + + * worlds/haxima-1.002/potions.scm: + missing '+' in stat potions + +2006-08-15 Kris Parker + + * src/character.cpp, src/character.h, src/kern.c, src/object.c, src/object.h: + added kern-obj-inflict-damage- damage stuff with diplomatic and xp side effects + + * src/cmd.c, src/player.cpp, src/player.h: + Equipment sort on R)eady occurs before and after selection, rather that interrupt the ui + + * src/kern.c: + Added kern-init-random reseed rng based on time till script starts + + * src/status.c: + Ready listing shows available quantity of weapons, not total quantity + + * worlds/haxima-1.002/ability.scm: + magic missiles gives xp/annoys target + + * worlds/haxima-1.002/game.scm: + Reseeds rng on script start + + * worlds/haxima-1.002/spells.scm: + Cleaned out some debugging stuff left in by accident + +2006-08-14 Kris Parker + + * src/cmd.c: + Confirmation for quit without saving + +2006-08-14 Gordon McNutt + + * src/Container.cpp, src/Container.h, src/cmd.c, src/cmdwin.c: + U)sed and R)eadied items get moved to the top of the inventory list + +2006-08-13 Kris Parker + + * worlds/haxima-1.002/trigrave.scm: + fixed ai typo + +2006-08-13 Gordon McNutt + + * doc/USERS_GUIDE, worlds/haxima-1.002/books.scm: + Added the L)oiter command to the docs + + * doc/USERS_GUIDE: + Updated section on status codes + + * doc/USERS_GUIDE: + Fixed up the comments around saving and quitting + + * src/Makefile.am, src/cmd.c, src/cmd.h, src/common.c, src/common.h, src/ctrl.c, src/file.c, src/file.h, src/images.c, src/menus.c, src/nazghul.c, src/scheme.c, src/session.c, src/sound.c: + Part 1 of some cleanup; consolidating file utility functions + + * src/Makefile.am, src/cmd.c, src/cmd.h, src/ctrl.c, src/kern.c, src/menus.c, src/menus.h, src/nazghul.c, src/node.c, src/node.h, src/play.c, src/session.c, worlds/haxima-1.002/kern-init.scm: + Initial cut at multiple save games + + * src/character.cpp, src/kern.c, worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/abigail.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/anne.scm, worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/joel.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/mesmeme.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/selene.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/thud.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/zane.scm: + Feature request filled: NPC's as light sources + + * src/character.cpp, src/character.h, src/cmd.c, src/cmd.h, src/ctrl.c, src/file.c, src/player.cpp, src/player.h: + Hacked in a L)oiter command to pass time + + * src/cmd.c, src/file.c, src/file.h, src/menus.c, src/nazghul.c, src/play.c, src/scheme.c, src/scheme.h, src/session.c, src/session.h: + Cleanup 2: everyplace is now using the same common file access functions + + * worlds/haxima-1.002/gamestart-mech.scm, worlds/haxima-1.002/gamestart.scm, worlds/haxima-1.002/moongate.scm, worlds/haxima-1.002/start-new-game.scm: + Bugfix: subtle bug when saving/reloading from the character creation room + +2006-08-12 Kris Parker + + * worlds/haxima-1.002/occs.scm: + First pass at combat occ-abilities + + * worlds/haxima-1.002/potions.scm: + Testing stuff enhanced + +2006-08-12 Gordon McNutt + + * src/status.c: + Bug in ztats showing items in use + + * worlds/haxima-1.002/Makefile.am: + Some new files needed to be added so they will get installed with make install + +2006-08-10 Kris Parker + + * worlds/haxima-1.002/newfolks.png, worlds/haxima-1.002/shapes.png: + Fixed some of the more excessive graphics glitches (perforated paladins, pink rats, etc) + +2006-08-08 Kris Parker + + * src/character.cpp, src/status.c: + character::getXpForLevel(1) now returns 0 + creating characters with 0 xp now gives them min xp for their level + creating characters with -ve xp now gives them random xp appropriate for their level + + * src/status.c: + XP and Lvl labels were on wrong screens + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/abigail.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/anne.scm, worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/dennis.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/ghertie.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/joel.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/mesmeme.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/nossifer.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/selene.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/silas.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/start-new-game.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/tetzl.scm, worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/thorald.scm, worlds/haxima-1.002/thud.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/warritrix.scm, worlds/haxima-1.002/zane.scm: + Megapatch no 2: Most characters have random appropriate xp. All characters start at max hp/mp + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/abigail.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/anne.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/dennis.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/joel.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/selene.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/tetzl.scm, worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/trigrave.scm: + mega stats tweakage. Not that the player will notice, but *I* will know that everyone hv unique stats + +2006-08-07 Kris Parker + + * src/character.cpp: + Character::setLevel now sets experience appropriate for the new level rather than the old one + + * src/status.c: + Status window now reads HP: MP: XP:(<+ percent>%) + +2006-08-07 Gordon McNutt + + * src/status.c: + Changed XP to LVL + +2006-08-06 Kris Parker + + * src/ascii.c, src/screen.c, src/screen.h: + Text uses muted versions of colours + + * src/character.cpp: + isAttackTargetInRange(NULL) now returns true + + * src/character.cpp, src/character.h, src/cmd.c, src/ctrl.c, src/kern.c, src/player.cpp, src/status.c: + arms and weapons enumerations in Character now use an external interation index (allows multiple simultaneous enumeration) + + * src/effect.c, src/kern.c: + icon support added to kern-mk-effect + + * src/images.c: + image load error to stderr not stdout + + * worlds/haxima-1.002/cursor.png: + nicer blue spinner + + * worlds/haxima-1.002/cursor.png: + placeholder cursor.png + + * worlds/haxima-1.002/effects.png: + added paralysis + + * worlds/haxima-1.002/effects.png: + first attempt at effect icons + + * worlds/haxima-1.002/effects.scm: + effect spites use s_whatever instead of 's_whatever + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/sprites.scm: + most effects should now have icons + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm: + First few effect sprites set + + * worlds/haxima-1.002/gamestart-mech.scm, worlds/haxima-1.002/gamestart.scm: + character creation area + + * worlds/haxima-1.002/potions.scm: + some booster potions for rapid playtesting + + * worlds/haxima-1.002/sprites.scm: + fixed incrementing tile_number in effect sprites + + * worlds/haxima-1.002/start-new-game.scm: + uses character creation area + +2006-08-06 Gordon McNutt + + * src/effect.c, src/kern.c, src/status.c: + Comment/formatting changes only + + * src/effect.h: + Added a field for a status icon to the effect struct + + * src/kern.c, src/status.c: + Added effect icons to the party status viewer + + * src/kern.c: + kern_mk_effect must load sprites as pointers (not closures) or it throws a type error + + * src/status.c: + Status now uses a set of standardized colors + + * src/status.c: + Replaced the status code with the effect icon in the ztats view of the character effects + + * src/status.c: + Added mini-icons to the party view for readied weapons + +2006-08-05 Kris Parker + + * worlds/haxima-1.002/spells.scm: + new spell: burning hands (bet flam hur) + + * worlds/haxima-1.002/spells.scm: + wind spells now fire at arbitary angles + +2006-08-05 Gordon McNutt + + * src/Makefile.am: + Removed frame.h + +2006-08-02 Gordon McNutt + + * src/character.cpp, src/place.c, src/place.h: + Fixed player party members not pathfinding over step triggers + + * src/character.cpp, src/player.cpp: + Starvation is now a bit more serious + + * src/cmd.c: + Spells with a cost of 1 were not using any action points when cast + + * worlds/haxima-1.002/moongate.scm: + Fixed the problem where destination moongates remained open + + * worlds/haxima-1.002/nossifer.scm: + Made Nossifer immune to charm + + * worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/start-new-game.scm: + Undead now immune to sleep and magic kill (in addition to fire, poison and disease) + + * worlds/haxima-1.002/species.scm: + Increased the vision radius of sea creatures so they will close with the player on sea/land or sea/ship combat maps + + * worlds/haxima-1.002/spells.scm: + Added success/failure messages to spells that use contest-of-skill + +2006-08-01 Gordon McNutt + + * src/character.cpp: + When a PC tries to step off the edge of a map the code checks for a neighboring + place before it checks for a parent (this is opposite of what it used to + be). This allows towns to have side-exits to dungeon rooms (or other towns). + + * worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/bole.scm: + Fixed up Bill's conv to match the change in the dryad location + + * worlds/haxima-1.002/bole.scm: + Moved the dryad in Bole to a separate place accessible via a side-exit from Bole + +2006-07-31 Gordon McNutt + + * src/character.cpp, src/foogod.c, src/kern.c, src/play.c, src/player.cpp, src/player.h, src/session.c, src/session.h: + Fixed saving, loading and general behavior of the turn counter in the foogod window + + * src/foogod.c: + Fixed a bug introduced with turn count changes; starting nazghul with no save game arg would cause a crash + + * worlds/haxima-1.002/hackle.scm: + Fixed endless loop in Hackle's heal conversation when player alone + + * worlds/haxima-1.002/mushroom-cave.scm, worlds/haxima-1.002/npc-types.scm: + Yellow slimes no longer divide into green slimes. + +2006-07-30 Gordon McNutt + + * src/Container.h, src/Party.cpp, src/dimensions.c, src/nazghul.c, src/status.c: + Small overhaul of the status viewer code. This includes a partial fix for SF + Bug: [ 1518735 ] ztats - AC, by adding armament stats to all the relevant + viewer windows. + + * src/ascii.c, src/character.cpp, src/character.h, src/status.c, worlds/haxima-1.002/books.scm: + Removed AC from the status display. Modified the color-control syntax: ^c+= + pushes the current color but doesn't change it, ^c+ pushes the + current color and sets the new current color to . + + * src/ascii.c, src/ascii.h, src/ctrl.c, src/screen.c, src/screen.h, src/session.c, src/status.c, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/gregor.scm: + Added support for colorized text. A few places in the code and the game scripts + were tweaked to test and demonstrate usage. + + * src/character.cpp, src/character.h, src/cmd.c, src/ctrl.c, src/effect.c, src/effect.h, src/status.c, worlds/haxima-1.002/effects.scm: + More fiddling with the stat UI. It's getting downright chatty now. + + * src/status.c: + Added species and occupation to character stat UI + +2006-07-29 Gordon McNutt + + * src/common.h, src/event.c, src/nazghul.c, src/play.c, src/play.h, src/session.c: + Moved some more global variables into the new cfg env. + + * src/common.h, src/dimensions.c, src/dimensions.h, src/nazghul.c, src/screen.c: + Cleaned up the SCREEN_BPP stuff. For now it's hard-coded to 16 in screen.c. + + * src/dimensions.c, src/dimensions.h, src/nazghul.c: + Changed the -m (map size) option to -r (screen res). dimensions.c now converts + the desired screen res to a map size that will accomodate it. + +2006-07-27 Gordon McNutt + + * src/nazghul.c, src/session.c, worlds/haxima-1.002/bakup.scm, worlds/haxima-1.002/kern-init.scm: + Moved more stuff to the new cfg + +2006-07-26 Gordon McNutt + + * src/Makefile.am, src/ascii.c, src/ascii.h, src/cfg.c, src/cfg.h, src/cmdwin.c, src/common.h, src/foogod.c, src/images.c, src/kern.c, src/nazghul.c, src/scheme.c, src/screen.c, src/screen.h, src/session.c, src/session.h, src/sound.c, worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/kern-init.scm, worlds/haxima-1.002/moongate.scm: + This adds support for a general kernel initialization script. Early in startup, + right after parsing the command-line args, the kernel will attempt to load + INCLUDE_DIR/"kern-init.scm" to initialize itself enough to present the main + menu. This is done through the new kern-set-cfg/kern-get-cfg procedure calls, + and the new cfg.[ch] module, which basically provides a setenv/getenv-type + feature. Currently only a couple of values are in kern-init.scm, but I hope to + migrate more currently-hard-coded stuff out there in the days ahead. Beyond + that, the ability to load/save an options.scm file will enable us to have + persistent user options (eg, map viewer size and sound settings). + + * src/nazghul.c, worlds/haxima-1.002/Makefile.am: + Had to add some files to the install process; fixed a warning about the missing init script + +2006-07-24 Kris Parker + + * worlds/haxima-1.002/spells.scm: + spells updated to use occ abilities + +2006-07-23 Gordon McNutt + + * src/scheme.h: + USE_TRACING should be off by default; must have committed it by mistake + + * src/status.c, src/vmask.c: + Minor indentation and comment cleanup + +2006-07-22 Gordon McNutt + + * doc/USERS_GUIDE: + Added a note about food consumption + + * doc/USERS_GUIDE: + Added info on effects and an appendix for weapons and armor spoilers to the user's guide + + * src/angband.c: + Fixed the LOS bugs related to map viewer sizes < 19x19 + + * src/map.c: + Minor comment cleanup + + * worlds/haxima-1.002/arms.scm: + Melee and projectile weapons were adding an armor bonus instead of a deflection bonus + +2006-07-16 Gordon McNutt + + * src/nazghul.c: + The show-all-terrain option was missing from the -h(elp) command option + +2006-07-11 Gordon McNutt + + * src/Makefile.am, src/Party.cpp, src/common.c, src/common.h, src/console.c, src/dimensions.c, src/dimensions.h, src/map.c, src/nazghul.c, src/sky.c, src/status.c, src/status.h, src/vmask.h: + Just committed a CVS change to allow a smaller UI. In common.h, uncomment the + + //#define CONFIG_11X11_MAP + + line, recompile, and the screen will be 736x400. I've only done some limited + testing but things look surprisingly good. There might be a line-of-sight bug + and the splash screen needs some tweaks. Need to test some more and figure out + how to do this automatically and dynamically so rebuilds aren't required. By + reducing the console width from 42 to 30 characters the screen could be + 640x400, which will satisfy the 640x480 crowd at least. + +2006-07-10 Gordon McNutt + + * src/common.h, src/screen.c: + Smaller UI. In common.h, uncomment the + + //#define CONFIG_11X11_MAP + + line, recompile, and the screen will be 736x400. + +2006-07-09 Gordon McNutt + + * src/Being.cpp, src/Being.h: + Patch from Eero Tamminen for link error under Suse 9.1 + +2006-07-08 Kris Parker + + * src/kern.c: + added kern-get-total-minutes for numeric clock access + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/spells.scm: + circle 1 spells based on character abilities + + * worlds/haxima-1.002/occs.scm: + fixed problem with getting abilities for chars without occs + + * worlds/haxima-1.002/roland.scm: + roland now a warrior + +2006-07-07 Gordon McNutt + + * worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/zane.scm: + Brought Shroom's prices inline with other reagent-sellers; reduced prices on more expensive reagents with all sellers + +2006-07-03 Kris Parker + + * src/play.c: + synchs place to reset sleepers on reload + + * worlds/haxima-1.002/effects.scm: + sleep effect reactivates on reload + + * worlds/haxima-1.002/effects.scm: + spawned off slimes are less powerful than thier 'parent's + +2006-07-02 Kris Parker + + * worlds/haxima-1.002/mouse.scm: + Thud had escaped down the wrong branch of an if/else. Now recaptured. Also, now goes beserk back in town if not present (or is this too evil?) Note that this file still crashes if t or k are dead + +2006-07-02 Gordon McNutt + + * src/character.cpp: + Fix for kern-char-leave-player where kchar is not in party; call is benignly ignored + + * worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/moongate.scm, worlds/haxima-1.002/mouse.scm: + Cleaned up logic in mouse.scm. Modified kathryn.scm such that if Kathryn joins, + and Thud is alive, then Thud automatically joins. This simplifies some of the + logic in mouse.scm. + +2006-07-01 Kris Parker + + * src/kern.c, src/occ.c, src/occ.h: + added gob facilities to occupations + + * worlds/haxima-1.002/occs.scm: + occ data for magical ability (theyre just meaningless numbers till the spells get revamped tho) + + * worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/tools.scm: + lockpicking based on occ gobs + +2006-07-01 Gordon McNutt + + * src/cmd.c, src/map.c, src/map.h: + bugfix for [ 1475928 ]: look works in complete darkness. Using the lightmap, if + no light is hitting a tile then x)amine won't report it. Changed the wording of + x)amine to say "can't see!" regardless if the reason is out-of-LOS or too dark. + + * src/occ.c: + Occ destructor deletes its optional gob + + * src/play.c: + bugfix for [ 1475929 ]: sleeping npcs wake on reloads + + * worlds/haxima-1.002/spells.scm: + The big list of spells doesn't need to be permanent once it's registered in the kernel; takes up memory, slows down gc, etc + +2006-06-30 Roberto Amorim + + * scripts/nazghul.iss: + Adding the Inno Setup script file used to generate the Windows installer + +2006-06-30 Gordon McNutt + + * AUTHORS, ChangeLog, NEWS: + Final changes before 0.5.4 release + + * doc/USERS_GUIDE: + Minor change to save/load notes + + * scripts/RELEASE_CHECKOFF: + Added another note + +2006-06-29 Gordon McNutt + + * src/kern.c: + Added kern-char-is-dead? + + * src/player.cpp: + Dead party members were eating rations + + * worlds/haxima-1.002/abigail.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/zane.scm: + o Reduced reagent prices + o Bugfix: Angriss would accept dead party members, caused a crash + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/species.scm: + o Slime attacks increased slightly. + o NPC party generator, when determining how big to make the NPC party, doesn't + count dead member's as part of the player party size count + o Gazers given fangs as a natural weapon (instead of nothing) + + * worlds/haxima-1.002/game.scm: + Renamed a variable + +2006-06-28 Kris Parker + + * worlds/haxima-1.002/mouse.scm: + stray bracket removed + +2006-06-28 Gordon McNutt + + * configure.ac: + Bumped the version number + + * src/map.c: + Put the clock display back on the map viewer since there is no other way to tell time yet in haxima + + * src/player.cpp: + Camping in town took more time than player specified + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/ilya.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/zones.scm: + o Necromancer used generic response when asked about himself. + o People in Glasdrin couldn't give directions to Glasdrin. + o Ilya and Gregor were eating in the ULC of the kitchen. Gregor lacked a + complete schedule. + o Dropped sling damage by a point. + + * worlds/haxima-1.002/mouse.scm: + Thud was not getting removed if he was dead but Kathryn was alive + + * worlds/haxima-1.002/naz.scm: + Fixed the set-level procedure to simply call kern-char-set-level. It was trying + to set the hp and mp, too, but doing it incorrectly by not accounting for + custom mp and hp bonuses. This causes the Wanderer to start with 11/41 hit + points, making him wolf-meat. + +2006-06-25 Kris Parker + + * nazghul.nsi, nazinst.ico: + upgraded w32 installer + + * scripts/nazghulrun.au3: + compilable version of w32 save file backup script + +2006-06-25 Gordon McNutt + + * src/Makefile.am, src/closure.c, src/event.c, src/kern.c, src/opdefines.h, src/scheme-private.h, src/scheme.c, src/scheme.h, src/session.c, src/session.h: + Reverted scheme interpreter to previous version (w/o garbage collector + changes). I don't want to change something fundamental like the garbage + collector so soon before a release, and I want to do it differently anyway. + + * worlds/haxima-1.002/Makefile.am: + Added some missing files to Makefile.am. + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Added sludge terrain. I think we need some sludge. + +2006-06-24 Kris Parker + + * src/factions.h: + Quick fix for bug 1462932: checks for same faction in harm_relations. + make_hostile isnt given a similar check since that is only used in party-party attacks (and hence not player triggerable) + +2006-06-15 Gordon McNutt + + * src/Makefile.am, src/character.cpp, src/closure.c, src/event.c, src/kern.c, src/opdefines.h, src/play.c, src/scheme-private.h, src/scheme.c, src/scheme.h, src/session.c, src/session.h: + Fixing [ 1451252 ] Followers get stuck in follow mode. character::move now + checks for PC's trying to spin in follow mode. character::exec now passes the + flag to ignore companions to the pathfinding routine; I think it used to do + this and removing it was an early (bad) attempt to fix this bug. + + Also updating the Scheme garbage collector to use a new algorithm with less + latency. + + * src/character.cpp: + Fixing [ 1460699 ] kama wanders while sleeping. In character::exec() it now + checks for sleeping as an activity like eating and doesn't move. + +2006-05-28 Kris Parker + + * src/cmd.c: + No longer allows (and crashes on) diagonal wilderness (a)ttacks + + * worlds/haxima-1.002/ai.scm: + the kraken ai needed to default to the kernel mode in a few more cases + + * worlds/haxima-1.002/game.scm: + Added pclass-waterboulder, for boulders embedded in water terrain + +2006-04-25 Kris Parker + + * scripts/blenddat.txt, scripts/palette.txt: + new terrains in terrain blending scripts + + * src/kern.c: + mechanisms to retrieve unmodified stats added + + * worlds/haxima-1.002/ai.scm: + kraken will now default to kernel ai if no targets visible (rather than just sitting there) + + * worlds/haxima-1.002/blendterrains.scm, worlds/haxima-1.002/newterrain.png, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/signs.png, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + a few new terrains: signs for character creation + new boulders + + * worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/slimy-cavern.scm: + added boulders-in-water to maps + + * worlds/haxima-1.002/tools.scm: + dex helps pick locks + +2006-04-17 Kris Parker + + * worlds/haxima-1.002/ai.scm: + Fix for: krakens poisoning themselves on swamps and chomping decks players are standing on + +2006-04-17 Gordon McNutt + + * worlds/haxima-1.002/ai.scm: + Fixing krakens to not pursue invisible foes + +2006-04-14 Kris Parker + + * src/cmd.c, src/conv.c, src/conv.h: + The kern-conv-get-reply and kern-conv-get-string commands now use + our isprintable check + +2006-04-13 Kris Parker + + * src/character.cpp, src/character.h, src/kern.c: + read/write access to character str/dex/int + +2006-04-10 Kris Parker + + * scripts/blenddat.txt, scripts/blendmap.pl, scripts/palette.txt: + More terrain blending working. (Ongoing tweaks while blending new maps) + + * scripts/blendmap.pl: + Documentation is your friend. It reduces the next person to use your softwares desire to murder you brutally + + * worlds/haxima-1.002/abandoned-farm.scm, worlds/haxima-1.002/absalot.scm, worlds/haxima-1.002/ancient-derelict.scm, worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/dank-cave.scm, worlds/haxima-1.002/eastpass.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/kun.scm, worlds/haxima-1.002/lich-tomb.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/mans-hideout.scm, worlds/haxima-1.002/merciful-death.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/mushroom-cave.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/poor-house.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/talking-ankh.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/void-temple.scm, worlds/haxima-1.002/westpass.scm: + Maps use blended terrains + + * worlds/haxima-1.002/blendterrains.scm, worlds/haxima-1.002/combat-maps.scm, worlds/haxima-1.002/newterrain.png, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Support for blended terrains + +2006-04-09 Kris Parker + + * scripts/blenddat.txt, scripts/blendmap.pl, scripts/unblenddat.txt: + Blending much more advanced and now handles most terrain types + + * scripts/blendmap.pl: + Updated the help somewhat + +2006-04-05 Kris Parker + + * doc/USERS_GUIDE: + Fixed ingredients in 'Mix' tutorial, and made it a better fit to the actual game interface + + * worlds/haxima-1.002/conv.scm: + Typo in basic-engi + +2006-03-29 Gordon McNutt + + * src/Being.cpp, src/Being.h, src/character.cpp: + Bugfix: followers get stuck in follow mode. They were switching places with one + another over and over in an attempt to reach the party leader. The option to + ignore companions is a flag passed to the pathfinding algorithm, in the case of + follow mode I no longer pass that flag, so followers will pathfind around one + another instead of switching places. + +2006-03-28 Gordon McNutt + + * src/conv.c: + Bugfix: [1451180] Shift key adds letters in conversation + + The new isprintable(char c) function which replaced libc's isprint was declared to + take a char arg. Some values like 304 (the value for the left shift key on my system), + when downcast to 8 bits, fell into the 32-127 range and were declared + printable. Fixed this by changing to isprintable(int c). + +2006-03-23 Kris Parker + + * scripts/blenddat.txt, scripts/blendmap.pl: + Blends more terrain types + +2006-03-22 Kris Parker + + * scripts/blenddat.txt, scripts/blendmap.pl, scripts/splitmap.pl: + New toys: pre-rendered terrain blending, and splitting large maps down to tiles for composites + + * worlds/haxima-1.002/shard.scm: + Added mountains south of eastpass + +2006-03-21 Kris Parker + + * scripts/maptoxpm.pl, scripts/mergemap.pl, scripts/xpmtomap.pl: + Added some map editting scripts + + * scripts/palette.txt: + Belatedly added palette data for map scripts + +2006-03-19 Gordon McNutt + + * src/character.cpp: + Bugfix: wait on NPC bed (awake), when NPC tries to kick you out of bed we get + an assert because the player is not sleeping. Fixed this by having the NPC + check that the player is asleep first. Otherwise it waits for the player to + leave. + +2006-03-18 Kris Parker + + * worlds/haxima-1.002/ilya.scm: + Ilya now gives correct directions to farm + + * worlds/haxima-1.002/ini.scm: + Gave ini appropriate xp for level + + * worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/zones.scm: + Jake&Percival no longer sleepwalk + + * worlds/haxima-1.002/mesmeme.scm: + Mesmeme can now be asked to leave + +2006-03-16 Kris Parker + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/endless-deeps.scm, worlds/haxima-1.002/trigrave.scm: + Dragon quest rune is now in Kurpolis deeps + + * worlds/haxima-1.002/amy.scm: + Amy mentioned the accursed, but didnt provide any information on them. Now you get some gossip. + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/lever.scm, worlds/haxima-1.002/mans-hideout.scm, worlds/haxima-1.002/sprites.scm: + Hidden lever now searchable + + * worlds/haxima-1.002/terrains.scm: + Less specific water naming + +2006-03-14 Kris Parker + + * worlds/haxima-1.002/gen.scm: + Gen now has appropriate xp for his level + +2006-03-13 Kris Parker + + * worlds/haxima-1.002/alchemist.scm: + Alchemist remembers completed quests + +2006-03-12 Kris Parker + + * worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/start-new-game.scm: + Linked in endless deeps level + + * worlds/haxima-1.002/r2a_mech.scm, worlds/haxima-1.002/road_to_absalot.scm: + road to absalot now works after save/reload (oops) + +2006-03-12 Gordon McNutt + + * worlds/haxima-1.002/warritrix.scm: + Fixed up the Warritrix's conversation + +2006-03-11 Gordon McNutt + + * src/common.h, src/nazghul.c, src/play.c, src/screen.c, src/status.c: + Some minor cleanup, and a fix for the status display, which wasn't showing a + title on startup. + + * src/kern.c: + Composite maps were not getting blended. It's not sufficient to blend the + sub-maps, because they're edges aren't blended and it makes their seams visible + in the composite map. + +2006-03-10 Gordon McNutt + + * src/Being.cpp, src/object.c: + Workaround for [ 1114054 ] messages for off-screen NPC's getting printed: + While the pathfinding code attempts to handle a mechanism it disables console + messages. This prevents mechanism scripts from printing to the console when + NPC's handle them during normal pathfinding. + +2006-03-08 Kris Parker + + * worlds/haxima-1.002/endless-deeps-mech.scm: + Added more critters to the deeps + + * worlds/haxima-1.002/endless-deeps-mech.scm: + New random templates: lava and swamp + + * worlds/haxima-1.002/endless-deeps-mech.scm, worlds/haxima-1.002/endless-deeps.scm: + Initial upload of third garrison and endless deeps + + * worlds/haxima-1.002/joel.scm: + Joel still had the old paladins in the tunnel plot. + +2006-03-08 Gordon McNutt + + * src/cmd.c: + If the player handles a nameless mech the console prints "Fyodor handles a + hidden mechanism". Ie, nameless is assumed to mean "hidden". A hack, so if the + assumption becomes unwieldy we'll have to add some more support for different + types of "hidden-ness". + +2006-03-07 Kris Parker + + * worlds/haxima-1.002/keep.scm: + Alternative treasure room access + +2006-03-07 Gordon McNutt + + * src/cmd.c: + [ 1437442 ] t)alk targets invisible people. + + Now it doesn't. + + * worlds/haxima-1.002/abigail.scm, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/lever.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/zones.scm: + Fix for [ 1434216 ] where's abigail? + + Added Abigail character. + +2006-03-06 Gordon McNutt + + * src/Makefile.am, src/blender.h, src/combat.c, src/kern.c: + The terrain blenders are now run on automatically-generated combat maps. + + * src/play.c, src/session.c, src/wind.c, src/wind.h: + Fix for [ 1429543 ] wind not updated on load + + session_load() now calls windRepaint(). Also, added windSave() since I noticed + that the wind direction was not getting saved. session_save() now calls it. + + * worlds/haxima-1.002/combat-maps.scm: + Fix for [ 1431953 ] bad default combat map with blended terrain + + The case for all existing blended terrains has been fixed by assigning a combat + map to each of them. This will have to be done for all future blended terrains + as well as they are added. + +2006-02-25 Kris Parker + + * worlds/haxima-1.002/spells.scm: + Fix for invisibility spells not using up scrolls (they probaby didnt use reagents either) + +2006-02-25 Gordon McNutt + + * src/object.h, src/player.cpp, src/player.h: + Fix for [ 1429541 ] extra ship on town entry + + Added a check to see if the player was in a vehicle when trying to move onto a + subplace. If so, denied. + + * worlds/haxima-1.002/alchemist.scm: + A few stylistic tweaks to Alchemist's conv + + * worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Restoring a few things that were accidentally removed + +2006-02-24 Kris Parker + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/newterrain.png, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Added path through road to absalot to match Alchemists lich quest + +2006-02-23 Gordon McNutt + + * src/character.cpp: + Fix for [ 1425039 ] Solo mode + possession = lockup + + The charm works by setting a being's current faction to the + caster's. Character::setCurrentFaction() already checks if the character is a + party member, I added another check to see if the character was in solo mode, + and if so to set the party mode to follow. + + Also found a bug where unreadyAll() was calling + player_party->unrefInventoryObject(arms) after unready() already did, causing + some oddities in the player inventory. + +2006-02-22 Gordon McNutt + + * src/place.c: + Turning off some noise debug + + * src/place.c: + Fix for 1425025: abuse of party moded + save game. + + Fixed this by addressing the order in which objects are saved in the current + place. Previously, they were saved by tile order, so in addition to what the + bug report noted you could get some other odd things. Now, they're saved in + turn list order, and the current object is always saved at the head of the + list. This ensures that on reload the object which saved the game begins the + turn order and the place then continues executing objects in the original + order. + +2006-02-18 Kris Parker + + * worlds/haxima-1.002/spells.scm: + Blink spells now only work withing LOS + + * worlds/haxima-1.002/spells.scm: + Blink spells will no longer transport the caster onto an impassable terrain + +2006-02-18 Gordon McNutt + + * src/cmd.c: + Aborting a spell should not cost mana + +2006-02-17 Kris Parker + + * worlds/haxima-1.002/engineer.scm: + Quests now require component quantities as in the voidship plans. + TODO: grammer on 'we still need X' messages needs work + +2006-02-17 Janne Johansson + + * src/ascii.c: + uninitialized nitpickings. shuts gcc4 up + +2006-02-17 Gordon McNutt + + * src/ascii.c: + Got rid of some dead code I noticed thanks to Janne's last patch + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/npc-types.scm: + Demons (and Nossifer) now immune to kill spell + + * worlds/haxima-1.002/nossifer.scm: + Fix for 1425031: spelling/grammer errors in nossifer.scm. Fixed as suggested. + +2006-02-15 Gordon McNutt + + * scripts/RELEASE_CHECKOFF, src/Being.cpp, src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/ctrl.c, src/event.c, src/kern.c, src/object.c, src/object.h, src/species.c, src/species.h, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/species.scm: + Fix for bug [ 1423898 ]: immobile critters. Critters like dryads and hydras are + supposed to be stationary. Early efforts to make this happen using the movement + modes and passability masks didn't work, so I did it in their AI's. But this + allowed their NPC parties to move on the map. With this change a species may + have a "stationary" flag. Any member of that species, and any party which + contains a living member of that species, will not move on the map, although + they will attack the player normally. + +2006-02-14 Gordon McNutt + + * src/character.cpp: + Fix for 1421524: abuse of solo mode/rendezvous. If hostiles are around, solo + mode party member's no longer instantly pathfind to the party leader when the + player enters Follow mode. + + * src/closure.c, src/map.c, src/scheme.c, src/tick.c, src/tick.h: + Changes for 64bit compilation based on Jason Tibbs patch + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Fix for 1423370: fire slimes divide into green slimes. Changed the slime-split + effect to be a generic split effect. It now has its own gob which specifies the + npc type tag to use to create the clone. Had to modify the generic npc + constructor in npc-types.scm to expect some effects to specify a gob ctor and + parms. + +2006-02-12 Gordon McNutt + + * src/place.c, src/play.c: + Added a performance optimization: the pathfinding algorithm now makes a quick + check to see if the target is surrounded by impassible terrain. If so, it + aborts early. Makes all the difference for cases like sea creatures trying to + pathfind to the player party in the middle of dry land. + +2006-02-11 Kris Parker + + * worlds/haxima-1.002/newterrain.png: + Added corner pieces for light forest. Also some plains corners without the shore effect + +2006-02-11 Gordon McNutt + + * src/event.c, src/event.h, src/nazghul.c: + Fixed missing keystrokes by adding a backlog queue in event.c. Not the dramatic improvement I was hoping for, unfortunately. + + * worlds/haxima-1.002/effects.scm: + Bomb traps no longer self-destrruct + + * worlds/haxima-1.002/kama.scm: + After joining once, Kama gives coords to Angriss in response to RUKA + +2006-02-10 Kris Parker + + * worlds/haxima-1.002/newterrain.png: + Added: + High resolution mountains & forests + Hill edge effects for blended terrain + + * worlds/haxima-1.002/sprites.scm: + Added sprite definitions for hires mountains/forest + + * worlds/haxima-1.002/tools.png: + Updated sextant + +2006-02-10 Gordon McNutt + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/merciful-death.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + Added a sextant + +2006-02-09 Kris Parker + + * worlds/haxima-1.002/rune.png: + Uploaded 'Etched' look for runic sign text + +2006-02-09 Gordon McNutt + + * worlds/haxima-1.002/spells.scm: + Removed LAT and LONG from in-wis verbage, as Tristan points out these are backwards + +2006-02-08 Gordon McNutt + + * src/Missile.cpp, src/kern.c, src/object.c, src/terrain_map.c, src/terrain_map.h: + Arrows on the ground were spinning whenever anyone shot an arrow; similar for other ammo types + + * src/kern.c, src/session.c, src/session.h: + Added kern-mk-blender, creates a terrain blender which is automatically applied to all maps as they are created + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/hidden.scm, worlds/haxima-1.002/newterrain.png, worlds/haxima-1.002/old-absalot.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrains.scm: + Searching for the S rune revealed it, but the player couldn't see it and might assume that searching for it put it in his inventory. This change adds the notion of a 'hidden' object which, when searched, becomes a normal visible object. This is done via a wrapper object which responds to the 'search' signal by creating the hidden object. + + * worlds/haxima-1.002/green-tower.scm: + Moved the lever in GT + + * worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrains.scm: + Converted kern-terrain-map blend calls to kern-mk-blender + +2006-02-06 Gordon McNutt + + * src/kern.c, src/terrain_map.c, src/terrain_map.h: + Added kern-terrain-map-blend + + * src/kern.c, src/sprite.c, src/sprite.h: + Added ability to 'decorate' sprites with other sprites, making layered sprites + + * worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrains.scm: + Blending shard and gregor's hut maps + + * worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Added some shore sprites and shore terrains based on Kris Parker's work + + * worlds/haxima-1.002/newterrain.png: + Terrain pieces + +2006-02-05 Gordon McNutt + + * AUTHORS, BUGS, ChangeLog, INSTALL, NEWS, configure.ac, scripts/RELEASE_CHECKOFF: + Preparing for 0.5.3 release + + * INSTALL: + Updated instructions on running the game + + * doc/USERS_GUIDE: + Updated for new install + + * src/combat.c, src/kern.c, src/place.c, src/place.h, src/session.c, src/terrain_map.c, src/terrain_map.h: + Added ref counting for terrain maps + + * src/kern.c, src/place.c, src/place.h: + Added kern-place-set/get-terrain-map + + * worlds/haxima-1.002/Makefile.am: + Wrong filename + + * worlds/haxima-1.002/effects.scm: + Bugfix from Bernhard Link: faction-wood-spider is nowehere defined, use faction-spider + +2006-02-04 Gordon McNutt + + * src/character.cpp, src/cmd.c, src/player.cpp, src/player.h: + Bugfix: if the script called kern-char-unready on a PC it would mess up the player party inventory counts, could cause an assert in status.c + + * worlds/haxima-1.002/Makefile.am, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/tower.png: + Added Kris Parker's new tower sprite and the activated altar sprite + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm: + Bugfix: hydra's weren't appearing on wilderness combat maps + + * worlds/haxima-1.002/arms.scm: + Balance: fireballs no longer drop fire fields where they hit + + * worlds/haxima-1.002/engineer.scm: + Fixed typo + + * worlds/haxima-1.002/newmonst.png, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/sprites.scm: + Added Kris Parker's new gint mage sprite + + * worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/species.scm: + Fixed dragons, hydras and lichs to drop blood using normal drop; prevents them from dropping on the wilderness + + * worlds/haxima-1.002/npc-types.scm: + Kris Parker's change: add loot to accursed npc types + + * worlds/haxima-1.002/shard.scm: + Changed Fens to use shallow water to keep out the pirate ships from getting spawned + +2006-02-03 Gordon McNutt + + * src/nazghul.c: + Added -I and -G to the command-line help + + * src/nazghul.c, worlds/haxima-1.002/Makefile.am: + Removed hard-coded haxima.scm from the kernel. It now assumes the more generic start-new-game.scm is the file to load to start a new game + + * worlds/haxima-1.002/Attic/haxima.scm: + Moved from here + + * worlds/haxima-1.002/npc-types.scm: + Accursed Templar should use human knight sprite + + * worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spider.scm: + o Spiders were still dropping loot in wilderness, converted them to use + standard loot-drop which fixes this + o Fire slimes were supposed to drop flaming oils as loot, fixed that + + * worlds/haxima-1.002/start-new-game.scm: + Replacement for haxima.scm + + * worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/zones.scm: + Fixed Gregor and Tooth's sleeping locations + +2006-02-02 Gordon McNutt + + * AUTHORS, BUGS, ChangeLog, NEWS: + *** empty log message *** + + * Makefile.am, Attic/PRESS_RELEASE, m4/Makefile.am, src/Makefile.am, worlds/Makefile.am, worlds/haxima-1.002/Makefile.am: + Bernhard Link's patch to add maintainer-clean as a target to the makefiles + + * autogen.sh, configure.ac: + Bernhard Link's configure patch + + * nazghul.nsi: + Windows installer will bundle .bat files + + * scripts/RELEASE_CHECKOFF: + Updates made on last release + + * src/cmdwin.c, src/console.c, src/nazghul.c: + Bernhard Link's debug patch to create .console and .cmdwin iff DEBUG is defined + + * src/common.c, src/common.h, src/images.c, src/nazghul.c, src/scheme.c, src/session.c, src/sound.c, worlds/haxima-1.002/Makefile.am: + Bernhard Link's patch to add -I and -G options + + * src/nazghul.c: + Bernhard Link's usage patch + + * src/play.c, src/sky.c: + Last submit broke new game startup; also previous eclipse code made new game startup all dark (which looks really cool, but was wrong) + + * src/play.c: + Bugfix: nazghul junk (where junk was not a valid load file) caused a segfault + + * worlds/haxima-1.002/Makefile.am: + Install newfolks.png + + * worlds/haxima-1.002/Makefile.am: + Bernhard Link's patch: don't install Makefile.am, do install newmonst.png + + * worlds/haxima-1.002/ability.scm: + Disarm now drops the target's weapon on the ground at his feet + +2006-02-01 Gordon McNutt + + * nazghul.nsi: + Nullsoft installer script for windows + + * src/Party.cpp, src/Party.h, src/character.cpp, src/cmd.c, src/cmd.h, src/combat.c, src/ctrl.c, src/event.c, src/foogod.c, src/kern.c, src/nazghul.c, src/place.c, src/play.c, src/sky.c: + G)et now always scoops up everything + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/potions.scm: + Misc bugfixes + + * worlds/haxima-1.002/newfolks.png, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm: + Adding Kris Parker's new player character sprites + +2006-01-31 Gordon McNutt + + * worlds/haxima-1.002/kama.scm: + Bugfix: ask Kama to rejoin after he leaves and he just points at the door + + * worlds/haxima-1.002/roland.scm: + Bugfix: after leaving, Roland couldn't rejoin + +2006-01-29 Gordon McNutt + + * AUTHORS: + Recorded new sprites from Kris Parker + + * worlds/haxima-1.002/arms.scm: + Tweaked armour defense + + * worlds/haxima-1.002/chester.scm: + Bumped price of plate + + * worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/newmonst.png, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm: + Added Kris Parker's new goblin sprites + + * worlds/haxima-1.002/npc-types.scm: + Bugfix: troll loot not using tags + + * worlds/haxima-1.002/shroom.scm: + Typo in conv + +2006-01-28 Gordon McNutt + + * src/kern.c, src/object.c, src/object.h: + Adding better support for irregular plural names + + * src/object.c: + Takes care of a few more plural name cases + + * src/sky.c, src/sky.h: + Added eclipse + + * worlds/haxima-1.002/food.scm: + Fixed plural food names + + * worlds/haxima-1.002/Attic/haxima.scm: + Kris Parker's improved astronomy + + * worlds/haxima-1.002/money.scm: + Using singular name for coin + + * worlds/haxima-1.002/moons.png: + New transparent moon sprites + + * worlds/haxima-1.002/naz.scm: + Drunken staggering checks for an occupant + +2006-01-27 Janne Johansson + + * src/terrain_map.c: + no sub-optimizations, just the fix. Sorry for borking my first few commits + + * src/terrain_map.c: + merging two types of fixes isn't good. sorry for the bad commit + + * src/terrain_map.c: + remove warning about possible use of h2,w2 initialized + +2006-01-27 Gordon McNutt + + * worlds/haxima-1.002/Attic/haxima.scm: + Implemented Kris Parker's recommended changes to the opening sequence in the moongate clearing + + * worlds/haxima-1.002/moongate.scm: + Increasing the brightness of moongates + + * worlds/haxima-1.002/roland.scm: + Roland now uses the human knight sprite + +2006-01-26 Gordon McNutt + + * ChangeLog, NEWS, scripts/RELEASE_CHECKOFF: + *** empty log message *** + + * src/nazghul.c: + Added Janne to the credits for his patches + + * worlds/haxima-1.002/Makefile.am: + Added some missing files to the list + +2006-01-25 Gordon McNutt + + * AUTHORS: + Updated AUTHORS to reflect recent submissions + + * doc/USERS_GUIDE, src/cmd.c, src/cmd.h, src/ctrl.c, worlds/haxima-1.002/books.scm: + Applied patch from Tim Douglas to fix H)elp command; added ctrl-q)quit q/o saving at his suggestion + + * src/terrain_map.c: + Applying patch from Janne Johansson for compiler warning + + * worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/naz.scm: + Promoted some generally useful code from mouse.scm to naz.scm + + * worlds/haxima-1.002/naz.scm: + Bugfix: purchasing a cure service from a healer didn't work + +2006-01-24 Gordon McNutt + + * configure.ac: + Patch from Janne Johansson + + * src/character.cpp, src/map.c, src/scheme.c: + Adding casts to double for calls to pow() and sqrt() + + * src/map.c, src/nazghul.c: + Got rid of getop_long and a few old options I don't want to support any more + + * src/nazghul.c: + Patch from Janne Johansson for Sun compiler + + * src/sprite.h: + Removed some obsolete code + +2006-01-23 Gordon McNutt + + * src/screen.c: + Bugfix: when zoomed out, transparency shows up as magenta + + * worlds/haxima-1.002/arms.scm: + Arms balance tweaking + + * worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Reworked edge spawning to make it easier to tune + + * worlds/haxima-1.002/species.scm: + Increased dragon HP + +2006-01-22 Gordon McNutt + + * src/Party.cpp: + Bugfix (1411788): NPC parties getting into towns and dungeons + + * src/ascii.c, src/ascii.h, src/screen.c: + Added support for colored console text; nothing using it yet but it does work + + * src/character.cpp: + Doubled XP required for level advancement + + * src/cmd.c: + Casting spells gives XP + + * src/combat.c: + Bugfix: NPC attacks while on (but not aboard) ship + + * src/ctrl.c, worlds/haxima-1.002/books.scm: + Changed quit-without-saving keybinding from ctrl-Q to ctrl-S + + * src/nazghul.c: + Added Steve Riberty to art credits for new rune sprites + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/food.png, worlds/haxima-1.002/reagents.png, worlds/haxima-1.002/runestones.png, worlds/haxima-1.002/shapes.png, worlds/haxima-1.002/signs.png, worlds/haxima-1.002/special.png, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/tools.png: + Added transparency to all sprites + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/food.png, worlds/haxima-1.002/shapes.png: + From Kris, added transparency to some more sprites + + * worlds/haxima-1.002/ai.scm: + Bugfix: use-ranged-spells not returning #f when it didn't cast anything, cause dryads to walk + + * worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/town-entry.scm: + Bugfix: Bole's inn-room door was not being locked on town re-entry + + * worlds/haxima-1.002/conv.scm: + Oparine townsfolk now give directions to Green Tower + + * worlds/haxima-1.002/dank-cave.scm: + Bugfix: ladder up from Dank Cave led to wrong location + + * worlds/haxima-1.002/enchanter.scm: + Enchanter was using generic response to ENCH keyword + + * worlds/haxima-1.002/kathryn.scm: + Bugfix: Kathryn not giving player her Wis Quas scroll upon join + + * worlds/haxima-1.002/monster-generator.scm: + Removed some obsolete code + + * worlds/haxima-1.002/npc-types.scm: + Craven archers now armed with daggers for when they run out of ammo + + * worlds/haxima-1.002/oparine.scm: + Fixed some signs and terrain + + * worlds/haxima-1.002/palette.scm: + Bugfix: alchemy sign confused with arms shop sign + + * worlds/haxima-1.002/scrolls.scm: + Canceling u)se scroll was using up scroll + + * worlds/haxima-1.002/thiefs_den.scm: + Removing unthiefly treasure from Thief's Den + + * worlds/haxima-1.002/traps_3.scm: + Bugfix: spawn points in Fun with Levers weren't getting triggered + +2006-01-19 Gordon McNutt + + * src/character.h, src/combat.h, src/kern.c, src/object.h, src/play.c, src/player.h, src/status.c, src/status.h, src/tree.h: + Fixed all -pedantic warnings over which I have control (ie, not in SDL headers) + + * src/cmd.c: + Fixing an access-after-deleted bug in mixing spells + + * src/cmd.c: + Renamed getchar to cmd_getchar to avoid collision on openBSD + + * worlds/haxima-1.002/runes.scm, worlds/haxima-1.002/runestones.png, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm: + New rune stone sprites courtesy of Steve Riberdy + +2006-01-18 Gordon McNutt + + * src/Container.cpp, src/Field.cpp, src/Makefile.am, src/astar.c, src/closure.c, src/cmd.c, src/combat.c, src/ctrl.c, src/dice.c, src/dtable.c, src/kern.c, src/map.c, src/object.c, src/place.c, src/scheme.c, src/session.c, src/sky.c, src/sound.c, src/species.c, src/terrain.c, src/vmask.c: + Kernel changes: + o Added -Wall for CFLAGS as well as CXXFLAGS + o Fixed all the -Wall compilation warnings + o Bugfix: when t)alking and a person was nearby, target origin started on + person instead of player + + * src/ascii.c, src/character.cpp, src/event.c, src/nazghul.c, src/player.cpp, src/sprite.c: + Some -Wall compiler warning fixes + + * src/cmd.c, src/ctrl.c: + Removed old Ctrl-S command to save terrain map; unnecessary now that terrain maps are saved along with the rest of the game, and harmful in that some distros don't have a writable /tmp/ + + * src/place.c: + Kernel changes: + o Bugfix: terrain effects (like fire) were being applied to monster generator + objects + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Haxima changes: + o New NPC type: fire slimes + +2006-01-17 Gordon McNutt + + * src/conv.c: + Fix for assert in ascii.c + +2006-01-16 Gordon McNutt + + * worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/tooth.scm: + Misc. fixes provided by Roland Hautz + + * worlds/haxima-1.002/npc-types.scm: + NPC's no longer drop loot on the wilderness map + + * worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/shapes.png, worlds/haxima-1.002/sprites.scm: + Added Kris Parker's human knight sprite + +2006-01-11 Gordon McNutt + + * worlds/haxima-1.002/gen.scm: + Haxima changes: + o Gen needed some bufs since he can potentially become a player party member + + * worlds/haxima-1.002/runes.scm: + Haxima changes: + o Bugfix: g)et didn't work with Runes on the ground + +2006-01-10 Gordon McNutt + + * src/ascii.c: + Kernel changes: + o asciiPaint() now maps unrecognized chars to '?' and bleats a warning. This is + to help debug the assert(c>=' ') in SF bug 1399049. + + * src/cmd.c: + Kernel changes: + o Bugfix: SF 1114048: selling itesm - list updated improperly. Actually, list + was just getting built improperly from the get-go. + +2006-01-09 Gordon McNutt + + * worlds/haxima-1.002/absalot.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/kun.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/signs.png, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/trigrave.scm: + Haxima changes: + o Added some "sign" sprites + +2006-01-08 Gordon McNutt + + * scripts/RELEASE_CHECKOFF: + Added comment about windows text files + + * worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/treasury.scm: + Haxima changes: + o Bugfix: auto-generated corpses were saving improperly, causing null objects + to be in them on reload + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/moongate-clearing.scm: + Haxima changes: + o Bugfix: old entrance to slimy cavern still in moongate clearing + o Bugfix: +4 iron helm stats were wrong + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Bugfix: kathryn's letter was defined in kathryn.scm, which might not be + loaded before the letter is referenced in the script. + o Bugfix: found a part of the wilderness map that was incorrectly impassable + + * worlds/haxima-1.002/mouse.scm: + Haxima changes: + o Bugfix: if Kathrn in party but Thud alive and not in party, crash when player + encounters the Mouse + + * worlds/haxima-1.002/spells.scm: + Haxima changes: + o Bugfix: some spells like In Ex Por would be consumed even if the player + aborted without selecting a target (In Sanct, Sanct and An Ex Por were also + affected) + +2006-01-08 Andreas Bauer + + * configure.ac: + *** empty log message *** + +2006-01-07 Gordon McNutt + + * scripts/RELEASE_CHECKOFF, src/Party.cpp, worlds/haxima-1.002/edge-spawn.scm: + Making sure the last few fixes were committed + + * src/Party.cpp, src/character.cpp, src/character.h, src/object.c, src/object.h, src/player.cpp, worlds/haxima-1.002/items.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/spider.scm: + Haxima changes: + o Bugfix: spider's sometimes dropped piles of spider silk with zero (0) objects + in them + o Bugfix: cannon-killing a large gint party cuases a crash. Someone in the + party was dropping a healing potion. When a healing potion execs it looks for + a nearby Being to put itself into its inventory. On the wilderness, it was + finding the gint party, and trying to call a Character method on a Party + object. Crash! + + * src/character.cpp, src/player.cpp, src/player.h: + Kernel changes: + o Bugfix: if a party member died it's readied items were lost. + + * worlds/haxima-1.002/luximene.scm: + Haxima changes: + o Bugfix: error in the script when the Necromancer summoned Luximene. + o Added more stuff to Luximene's conversation + + * worlds/haxima-1.002/shard.scm: + Haxima changes: + o Bugfix: moongate near Glasdrin was positioned over an impassable mountain + + * worlds/haxima-1.002/shroom.scm: + Bugfix: shroom's trade conv broken by typo + +2006-01-05 Gordon McNutt + + * src/Party.cpp: + Kernel changes: + o Bugfix: Party::save() was not saving one of the arguments to + kern-party-set-vehicle, this caused a bad save file when the player saved + with pirates somewhere on the map + +2006-01-04 Gordon McNutt + + * doc/USERS_GUIDE: + doc changes + +2006-01-04 Andreas Bauer + + * worlds/haxima-1.002/Makefile.am: + Initial. + +2006-01-03 Andreas Bauer + + * Makefile.am, configure.ac, src/Makefile.am, worlds/Makefile.am: + Added haxima to build system. + +2005-12-31 Gordon McNutt + + * doc/USERS_GUIDE: + Minor edits to USERS_GUIDE + + * worlds/haxima-1.002/lich-tomb.scm: + Fixed ladder up in Lich's Tomb, was referring to old Keep Crypt + +2005-12-30 Gordon McNutt + + * AUTHORS, BUGS, Attic/Makefile.in, Attic/configure, doc/USERS_GUIDE, scripts/RELEASE_CHECKOFF, scripts/ghul-test-install, worlds/Makefile.am: + USERS_GUIDE, Makefile.in and misc other final tweaks + + * src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/nazghul.c, src/player.cpp, src/vmask.c: + Kernel changes: + o Reduced action point cost for PC spell-casting by 1/2 + o Changed the main menu order: Journey Onward is always first if it's + applicable + o If a party member dies it unreadies all of its arms + o The X)amine command shows the XY coords only in Developer Mode + o Turned off switching to round-robin mode on entrance to a hostile place. Just + feels weird during play. + o Added a user confirmation check before over-writing an existing saved game + when "Start New Game" is selected + + * src/character.cpp, src/cmd.c, src/map.c, src/tick.c: + Kernel changes: + o Reduced action point cost for PC spell-casting by 1/2 + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/eastpass.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/ilya.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/moongate.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spider.scm, worlds/haxima-1.002/traps_2.scm, worlds/haxima-1.002/tutorial_town.scm, worlds/haxima-1.002/tutorial_wilderness.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Bugfix: various spells needed some maintenance + o Bugfix: scrolls misspelled in Lia's shop script + o Bugfix: queen spider's would cast web spew when out of range + o Tweaked some loot drops + o Increased starting player HP but reduced HP gain per level + + * worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/moon.scm, worlds/haxima-1.002/moongate.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Haxima changes: + o Bugfix: various spells needed some maintenance + + * worlds/haxima-1.002/special.png: + A couple of new images I forgot to check in. + + * worlds/haxima-1.002/thorald.scm: + Adding tutorial NPC to repository + +2005-12-29 Gordon McNutt + + * INSTALL, README: + Updated the README and INSTALL files. + + * src/Missile.cpp, src/Party.cpp, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/ctrl.c, src/effect.c, src/foogod.c, src/kern.c, src/list.h, src/map.c, src/nazghul.c, src/object.c, src/place.c, src/play.c, src/player.cpp, src/player.h, src/scheme.c, src/session.c, src/session.h, src/status.c, src/vmask.c, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/tools.scm, worlds/haxima-1.002/tutorial.scm, worlds/haxima-1.002/tutorial_cave.scm, worlds/haxima-1.002/tutorial_town.scm, worlds/haxima-1.002/tutorial_wilderness.scm: + Haxima changes: + o Finished the tutorial. + + Kernel changes: + o Reverted most of my last changes since they made reload unstable. + o Main menu does not loop (big memory leak if it does) + + * src/ctrl.c, src/nazghul.c: + Kernel changes: + o Made the terraform and zoom commands available only with the --developer + option on the command line + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/zane.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Misc tweaks to the scripts + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/tutorial.scm, worlds/haxima-1.002/tutorial_town.scm: + Haxima changes: + o Conversation tweaks. + + * worlds/haxima-1.002/shard.scm: + Haxima changes: + o Paved a road from Trigrave north to the Fen + +2005-12-28 Gordon McNutt + + * src/Missile.cpp, src/Party.cpp, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/ctrl.c, src/effect.c, src/foogod.c, src/kern.c, src/list.h, src/map.c, src/nazghul.c, src/object.c, src/place.c, src/play.c, src/player.cpp, src/player.h, src/scheme.c, src/session.c, src/session.h, src/status.c, src/vmask.c, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/tutorial.scm, worlds/haxima-1.002/tutorial_town.scm: + Haxima changes: + o Added tutorial.scm to provide a walkthrough of the basic commands (unfinished) + + Kernel changes: + o Added tutorial to the main menu + o Made the global player party into the session struct. + o Changed the way the player party is allocated/freed + + * src/character.cpp, src/nazghul.c, src/play.c, src/session.h, src/status.c, src/status.h, worlds/haxima-1.002/main-menu.scm, worlds/haxima-1.002/slywan.scm: + Haxima changes: + o Added main-menu.scm to support main menu UI + + Kernel changes: + o Added main menu UI. If no load file is specified to nazghul it will show a + menu allowing the user to select a new game or to journey onward. + o Quit&Save now falls back to the main menu UI. + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/kun.scm, worlds/haxima-1.002/kun.scm, worlds/haxima-1.002/kun.scm, worlds/haxima-1.002/mesmeme.scm, worlds/haxima-1.002/mesmeme.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/slywan.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/tetzl.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/tooth.scm, worlds/haxima-1.002/zones.scm, worlds/haxima-1.002/zones.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o More stuff in new town + +2005-12-27 Gordon McNutt + + * src/ctrl.c, src/map.c: + Kernel changes: + o Bugfix: projectile animation speed varied from host to host + + * worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/jake.scm, worlds/haxima-1.002/kun.scm, worlds/haxima-1.002/mesmeme.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added extra town & some NPCs + + * worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/ilya.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/roland.scm: + Haxima changes: + o Tweaked Ilya's conv + + * worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Reworked Oparine + +2005-12-26 Gordon McNutt + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/ancient-derelict.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/vehicles.scm: + Haxima changes: + o Added some sprites for a couple of special items + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/prison.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/special.scm: + Haxima changes: + o Modified the wilderness map. + + * worlds/haxima-1.002/combat-maps.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Added lava bridge combat map + o Added mountain combat map + + * worlds/haxima-1.002/crypt.scm, worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Reworked Green Tower Lower + + * worlds/haxima-1.002/dank-cave.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/step.scm: + Haxima changes: + o Populated Dank Cave + o Fixed In Quas Corp spell + + * worlds/haxima-1.002/effects.scm: + Haxima changes: + o Bugfix: sleep effect did not wake up victim when it expired + + * worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/prison.scm, worlds/haxima-1.002/tools.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Reworked Glasdrin Prison. + +2005-12-25 Gordon McNutt + + * src/Being.cpp, src/Being.h, src/character.cpp, src/character.h, src/kern.c: + Kernel changes: + o Bugfix: charm an NPC and try Z)tats on the NPC's turn => crash. I fixed this + by tearing out the kernel implementation of "charm" and replacing it with a + simple faction change. Finished implementing the notion of "current" vs + "base" faction. + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/dank-cave.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/nossifer.scm: + Haxima changes: + o Changed the way the charm effect is implemented. + +2005-12-24 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/character.cpp, src/kern.c: + Kernel changes: + o Bugfix: hang if a character joins the player when already in the player party + + * src/character.cpp, src/ctrl.c, src/kern.c: + Kernel changes: + o Character::clone() now clones readied items, too + + * src/kern.c, src/player.cpp, worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/kama.scm: + Haxima changes: + o NPC's who will join now check if they are already in player party when asked + to join again (safe if they don't this just fixes the messages) + o Added LEAVe to conversations so the player can dismiss party members if he + wants to. + + Kernel changes: + o Bugfix: if an npc left and rejoined the game would hang. + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/altar-room.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/spells.scm: + Haxima changes: + o bugfix: after loading a saved game, killing a wizard resulted in script + errors because the wizard loot list wasn't using tags + o Added summon-demon ability for warlocks + o Added turn-invisible ability for demons + o Populated Altar Room + o Fixed In Quas Xen spell + + * worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/kalcifax.scm: + Haxima changes: + o NPC's who will join now check if they are already in player party when asked + to join again (safe if they don't this just fixes the messages) + + * worlds/haxima-1.002/amy.scm, worlds/haxima-1.002/poor-house.scm: + Haxima changes: + o Added Amy + + * worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/kama.scm: + Haxima changes: + o Changed Kama's occupations + + * worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/slimy-cavern.scm: + Haxima changes: + o Moved slimy cave + o Altered Roland's conv + +2005-12-23 Gordon McNutt + + * doc/USERS_GUIDE, src/kern.c, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/jim.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/spells.scm: + Haxima changes: + o Added Wis Sanct, detect trap + o Added An Sanct Ylem, disarm trap + + Kernel changes: + o Added kern-obj-is-container? + o Added kern-obj-is-trapped? + o Added kern-obj-remove-trap + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/jim.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/zane.scm: + Haxima changes: + o Added effects for potions of dragon's, hydra's and lich's blood + o Added a couple of new "hidden" spells + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrain-to-ptype.scm, worlds/haxima-1.002/vehicles.scm: + Haxima changes: + o Added pirate NPC parties + o Tuned ship cannon damage + +2005-12-22 Gordon McNutt + + * src/character.cpp, src/kern.c, src/place.c, src/place.h, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/town-entry.scm, worlds/haxima-1.002/Attic/trigrave-entry.scm, worlds/haxima-1.002/trigrave.scm: + Haxima changes: + o Fixed inn room doors in all the towns. On entry to a town all inn room doors + are locked. + + Kernel changes: + o Bugfix: NPC's with multi-place schedules might start in the wrong town. + o Previously a place's on-entry hook would only support one hook fx, now it + will support a list of them. + + * src/kern.c, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/prison.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/town-entry.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Redid Glasdrin's map to reduce the size and number of guards. + + Kernel changes: + o Performance improvement: added kern-obj-is-field?. The is-field? procedure in + the script was the bottleneck causing too-frequent garbage collection cycles + in places with lots of combatant NPC's (like guards). This change reduces + gc frequency in Glasdrin by almost 300%. + + * src/sprite.c, src/sprite.h, src/vehicle.cpp: + Kernel changes: + o Bugfix: if two ships were both visible, their sprites would always have the + same facing even if the ships didn't. The sprites were in lockstep. + +2005-12-22 Andreas Bauer + + * ChangeLog, configure.ac: + configure.ac: test for SDL_image + +2005-12-21 Gordon McNutt + + * src/character.cpp, src/character.h, src/object.c, src/session.h, worlds/haxima-1.002/abe.scm, worlds/haxima-1.002/jewelry.png, worlds/haxima-1.002/jewelry.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/runes.scm, worlds/haxima-1.002/thiefs_den.scm, worlds/haxima-1.002/traps_4.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Fixed a few NPC schedules + o Added some missing files + + Kernel changes: + o NPC's now kick the player out of their bed + + * src/cmd.c, src/common.c, src/common.h, src/ctrl.c, worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/Attic/haxima.scm: + Haxima changes: + o Restoring a few test values to real game values + + Kernel changes: + o Build error fix: renamed log2 to logBase2. Apparently log2 conflicts with + newer versions of math.h. + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/jim.scm, worlds/haxima-1.002/npc-types.scm: + Haxima changes: + o Converted all (pertinent) npc types to use the new treasure drop system. + o Changed price of morning stars in Trigrave. + +2005-12-20 Gordon McNutt + + * src/character.cpp, src/object.c, src/object.h, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Haxima changes: + o Added L1 nixies without ranged weapons + o Added a new treasure drop effect + + Kernel changes: + o Added a new on-death hook + + * worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/parties.scm: + Haxima changes: + o Bugfix: npc party generation had a bug where it wouldn't generate rare party + types + +2005-12-19 Gordon McNutt + + * src/place.c: + Kernel changes: + o Bugfix: if combat was initiated over a town, on exit the town would be + removed from the map. Of, if the player saved during that combat, the save + file would crash when loaded. + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Haxima changes: + o Added some npc and npc party types + +2005-12-18 Gordon McNutt + + * src/character.cpp, worlds/haxima-1.002/camping-map.scm, worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Haxima changes: + o Wilderness combat tuning + + Kernel changes: + o Advancement tuning + +2005-12-17 Gordon McNutt + + * src/character.cpp, src/cmd.c, src/kern.c, src/player.cpp, src/player.h, worlds/haxima-1.002/ankh-shrine.scm, worlds/haxima-1.002/demon-gate.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/nossifer.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/talking-ankh.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Fixed up end-game + + Kernel changes: + o Added kern-end-game to gracefully end the game when it is over + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/dennis.scm, worlds/haxima-1.002/nossifer.scm, worlds/haxima-1.002/old-absalot.scm, worlds/haxima-1.002/selene.scm, worlds/haxima-1.002/silas.scm: + Haxima changes: + o Altered Accursed NPC conversations to streamline the plot + + * worlds/haxima-1.002/absalot.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/joel.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm: + Haxima changes: + o Rearranged dungeons on road to absalot + o Added Joel, a shepherd + o Added Gate to Absalot on wilderness map + o Added a pick (new tool) + + * worlds/haxima-1.002/combat-maps.scm: + Haxima changes: + o Fixed up bridge combat maps & camping map + + * worlds/haxima-1.002/combat-maps.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm: + Haxima changes: + o Improved the wilderness combat maps + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/Attic/haxima.scm: + Haxima changes: + o Updates to Enchanter's conv + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/tools.scm: + Haxima changes: + o Added Tower of Absalot + +2005-12-16 Gordon McNutt + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/crypt.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/necromancers-lair.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Added Necromancer's cave to the map + o Moved Crypt from Keep to level below GTL + + * worlds/haxima-1.002/ancient-derelict.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/special.scm: + Haxima changes: + o Added an ancient derelict + + * worlds/haxima-1.002/chanticleer.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/crypt.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/gwen.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/the-man.scm: + Haxima changes: + o Moved the location of Lost Halls + o Tweaked some conversations + + * worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/warritrix.scm: + Haxima changes: + o Added ghost of Warritrix + o Fixed randomly-generated corpses to use same argument scheme as containers + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/warritrix.scm: + Haxima changes: + o Added Bet Por (single-character teleport) and Vas Por (whole-party teleport) + + * worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/road_to_absalot.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Moved Fire Sea to its own dungeon + +2005-12-14 Gordon McNutt + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/moongate.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/old-absalot.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/void-temple.scm: + Haxima changes: + o Misc tweaks here and there + +2005-12-13 Gordon McNutt + + * src/character.cpp, src/kern.c, src/place.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/keep_crypt_mech.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Kama to GTL + o Tweaked Gen's conv + + Kernel changes: + o Bugfix: broke character saving when I added saving of the force-drop flag + + * src/kern.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/shroom.scm: + Haxima changes: + o Changed Angriss to be L20 + o Changed web-spew to use 1/2 level (not 100%) + + Kernel changes: + o Bugfix: misplace "g" in kern.c caused broke kern-map-repaint + + * src/play.c, src/session.c, worlds/haxima-1.001/shard.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Added the moons & moongates + + Kernel changes: + o Bugfix: the sun and moon weren't appearing in the sky window when the game + first started. As soon as the player took a turn they would appear. Needed to + call sky_advance() as soon as the current Place was established to force a + repaint of the sky window. + + * src/player.cpp, worlds/haxima-1.002/kraken-lakes.scm: + *** empty log message *** + + * worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/kalcifax.scm, worlds/haxima-1.002/kama.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Kalcifax, the wandering mage + +2005-12-11 Gordon McNutt + + * src/character.cpp, src/character.h, src/cmd.c, src/kern.c, src/status.c, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/ghertie.scm: + Haxima changes: + o And more conversation tweaks + + Kernel changes: + o New feature: when buying/selling, the quantity the player currently owns is + shown in brackets. + o Annoyance fix: on reload, shopkeepers had to goto the top left corner of their + appointed area before they were done "commuting". Until then they would not buy + or sell. + +2005-12-10 Gordon McNutt + + * src/character.cpp, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/chanticleer.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/silas.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/spider.scm: + Haxima changes: + o More conversation tweaks + + Kernel changes: + o Player can now switch places with non-hostile non-party members (as well as + party members). This helps the "blocked in the hallway" syndrome. + o Bugfix: paralysis was having no effect on player character's in follow mode. + + * src/cmd.c, src/ctrl.c, src/kern.c, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/gate-guard.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/the-man.scm: + Haxima changes: + o And more conversation tweaks + + Kernel changes: + o New feature: if a player character has no saved target, and the player gives + it the a)ttack command, the crosshair will start on the nearest hostile instead + of on the PC. This should somewhat reduce the risk of carpal tunnel. + o Did something similar for the t)alk command. + o Bugfix: kern_blit_map() was not flushing the vmask cache, causing LOS + problems when terrain-altering mechanisms were handled + +2005-12-08 Gordon McNutt + + * doc/USERS_GUIDE, src/character.cpp, src/place.c, src/place.h, worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/anne.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm: + Haxima changes: + o Bugfix: the gate guard in Paladin's Hold wasn't getting cleaned up on + respawn, causing an ever-increasing population of gate guards cluttering up + the hallway + o Added ladder between Kraken Lakes and Fire Sea level + o Bugfix: species' on-death closures weren't getting registered + o Bugfix: the potion sprite set had a bug that made the newer potions have no + sprite + + Kernel changes: + o Bugfix: Character::save() was saving intelligence and dexterity as the return + values from getIntelligence() and getDexterity(), which add the species + values. This causes characters to grow in intelligence and dexterity with + each save/load cycle. + o Bugfix: circularly-connected places weren't saving their neighborliness + relationship correctly, resulting in some places getting isolated. + +2005-12-07 Gordon McNutt + + * src/cmd.c, src/ctrl.c, worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/food.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/steward.scm: + Haxima changes: + o Tweaked the world map a bit so that Glasdrin may be reached by land. + o Added to some conversations + + Kernel changes: + o ui_trade() no longer automatically puts the bought item in inventory if the + item has a 'buy hook. + o Giving player characters a damage bonus. + +2005-12-06 Gordon McNutt + + * doc/USERS_GUIDE, src/cmd.c, src/combat.c, src/ctrl.c, src/kern.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/eastpass.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/jim.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/reagents.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/thud.scm, worlds/haxima-1.002/traps_3.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/westpass.scm: + Doc changes: + o Added a list of the effect codes shown in the status window for party members + to the USERS GUISE + + Haxima changes: + o Minor bugfixes to scripts and maps + + Kernel changes: + o R)eady command now prompts for party member when in follow mode + o Added highlight boxes to X)amine command + +2005-12-04 Gordon McNutt + + * src/Being.cpp, src/Being.h, src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/kern.c: + Kernel changes: + o Moved the name member of the Character class up to the Being class and made + it private. Moved mut/acc up there as well so now the Party class can enjoy + all the benefits of having its very own name. Equality to all the classes! + o Added kern-being-set-name so the script can name parties + + * src/Party.cpp, src/kern.c, src/map.c, src/object.c, src/object.h, src/place.c: + Kernel changes: + o Added optional time-to-live (TTL) count on objects. If set, the count + decrements every time the object gets a turn. When the count expires if the + player is not in LOS the object is removed from the game. + o Added kern-obj-set-ttl for the script + + * src/Party.cpp, src/Party.h, src/ctrl.c, src/kern.c, src/object.c, src/player.cpp, src/player.h: + Kernel changes: + o Cleaned up NPC parties, eliminating the PartyType class and lots of other + useless leftovers. Will be much easier to make NPC parties now from the + script, more like making NPC characters now. + + * src/cmd.c, src/combat.c, src/kern.c: + Kernel changes: + o Added kern-obj-set-conv + + * src/combat.c, src/map.c, src/place.c, src/session.c: + Kernel changes: + o Finally fixed a noxious intermittent bug that's been haunting me for months: + LOS getting messed up. Turns out it would only happen with reloads, due to + map subplaces not getting deleted, resulting in player character's not + getting deleted and hence not removing their views before the next session + starts. Philosophically, this comes from mixing persistent state (internal to + map.c in this case) with per-session state. Learn from my mistakes, kiddies. + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/gregors-hut-zones.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/terrain-to-ptype.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added a bunch more wilderness party types + o Named all the wilderness party types + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Haxima changes: + o Added Westpass, a ranger camp that guards a mountain pass + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/gwen.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/Attic/moongate-clearing-zones.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Miscellaneous stuff while testing early game playability. + + * worlds/haxima-1.002/edge-spawn.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/step.scm, worlds/haxima-1.002/terrain-to-ptype.scm: + Haxima changes: + o Added new wilderness NPC party generator + +2005-12-03 Gordon McNutt + + * src/character.cpp, src/cmd.c, src/ctrl.c, src/dtable.c, src/dtable.h, src/factions.h, src/place.c, src/screen.c, src/screen.h, src/session.h: + Kernel changes: + o Prompt player before attacking non-hostiles (already had this in party mode, + but looks like it was lost a while ago in town mode) + o The x)amine command now shows diplomacy status of other beings + o Commands that select characters on the map now show hostile's with a red box + around them, allies with green, and neutrals with yellow. Hopefully this and + the last change will keep newbies from trying to fist Gregor to death when + they start the game. + + * src/kern.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/spells.scm: + Haxima changes: + + o Populated Fire Sea with a dragon. One is probably enough. + + Kernel changes: + + o Bugfix: in a previous checkin I accidentally screwed up + kern-terrain-get-pclass; looks like I was trying to add + kern-terrain-blocks-los? or something and got them mixed up + + o Added kern-terrain-blocks-los? (since I already had an implementation) + + * src/map.c, src/map.h, src/object.c, src/place.c, src/play.c, src/scheme-private.h, src/session.c, src/session.h: + Kernel changes: + o Added mapSetSelected() so that the currently selected player character will + show up brightly even in dark rooms (but will not light up its surroundings) + o If reload fails the console message reflects an error (it was always declaring + success) + o When the player changes places the turn is ended (the place_exec loop + exits). Otherwise, until the turn is over if somebody shoots an arrow or + takes damage the animations are shown in the viewer for the NEW place. + + * worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/forsaken-prison.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added and populated Watchpoint dungeon room + o Moved ladder between first and second level of Kurpolis + o Populated Forsaken Prison dungeon room + o Tweaked some maps and convs + +2005-12-02 Gordon McNutt + + * src/character.cpp, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/absalot.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/spells.scm: + Haxima changes: + o Populated Fire Bridge + o Added enslave ability for gazers + o Added narcotize ability for gazers + o Tweaked tremor spell + o Added corrupted halberdier and crossbowman NPC types + o Added ladder to Absalot + + Kernel changes: + o Bugfix: charm was not working right + +2005-11-30 Gordon McNutt + + * doc/USERS_GUIDE, src/kern.c, worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/spells.scm: + Haxima changes: + o Populated Rivulets of Fire dungeon room + o Added telekinesis spell + + Kernel changes: + o Added kern-obj-is-mech? to support telekinesis spell + +2005-11-29 Gordon McNutt + + * src/character.cpp, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/step.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Added chomp-deck ability for krakens + o Added step spawn points (again... newer version) + o Finished adding monsters to the Deepness + o Fixed a bug in the acid effect + o Added kraken, sea serpent and hydra AI + + Kernel changes: + o When characters advance a level they get full hp and mana restoration + o Character::setLevel() also sets XP for that level + +2005-11-28 Gordon McNutt + + * src/cmd.c, src/kern.c, src/player.cpp, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/yellow-slime.scm: + Haxima changes: + o Added acid effect and acid bolt (untested) + o Finished Pools + + Kernel changes: + o Casting spells dec's action points + + * src/cmd.c, src/cmd.h, src/ctrl.c, src/object.c, src/object.h, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/lich-tomb.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Added fire immunity + o Skeletons immune to fire and poison + o Finished Lich's Tomb + + Kernel changes: + o Added a nil hook for effects like fire immunity which don't do anything other + than exist + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/occs.scm: + Haxima changes: + o Added Craven Archer NPC type + o Finished Death Knight Keep + + * worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/treasury.scm: + Haxima changes: + o Added lost treasury + +2005-11-27 Gordon McNutt + + * src/Being.cpp, src/cmd.c, src/ctrl.c, src/kern.c, src/place.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/spells.scm: + Haxima changes: + o Finished Great Hall + o Fixed Vas Flam and Grav Por spells + o Fixed player missile spells to go through the abilities layer once target + selected, makes missile spell code more common + + Kernel changes: + o kern_fire_missile was causing double hits + o Compressed some combat console verbage + + * worlds/haxima-1.002/alex.scm, worlds/haxima-1.002/jones.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Finished Paladin's Hold + +2005-11-26 Gordon McNutt + + * worlds/haxima-1.002/anne.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/gate-guard.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/step.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Modified gate guards a bit + o Mostly finished up Paladin's Hold + +2005-11-25 Gordon McNutt + + * src/common.h, src/place.c, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/old-mine.scm, worlds/haxima-1.002/tools.scm: + Haxima changes: + o Added some ghosts to the Old Mine + o Added wind traps which blow out torches + o Seperated torch-light effect from generic light effect + o Bugfix: effect removal procedures should not call kern-obj-remove-effect, or + endless recursion results. + + Kernel changes: + o Reduced MIN_PLAYER_LIGHT from 128 to 8, so that torches become a bit more important. + + * worlds/haxima-1.002/food.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/old-mine.scm: + Haxima changes: + o Finished Old Mine + +2005-11-23 Gordon McNutt + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/old-mine.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/troll.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Finished Goblin Kingdoms + +2005-11-21 Gordon McNutt + + * src/Being.cpp, src/ctrl.c, worlds/haxima-1.002/abandoned-cellar.scm, worlds/haxima-1.002/abandoned-farm.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep_crypt_mech.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/merciful-death.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/mushroom-cave.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/poor-house.scm, worlds/haxima-1.002/slimy-cavern.scm: + Haxima changes: + o Added guard-pt, a special case of spawn-pt, for guards + o Changed re-spawn time from one hour and one minute to one day + + Kernel changes: + o Finally fixed the "FIXME: use Being::pathfindTo" messages coming from ctrl.c + o When the party leader switches from Follow mode to Round Robin mode he no + longer forfeits his own turn. + + * src/cmd.c, worlds/haxima-1.002/abandoned-cellar.scm, worlds/haxima-1.002/abandoned-farm.scm, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/Attic/af-entry.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/mushroom-cave.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/poor-house.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/Attic/slimy-cavern-entry.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm: + Haxima changes: + o All NPC types added + + Kernel changes: + o Bugfix: if a chest was on a mech which could not be opened, trying to open + the chest would have no effect. + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/anne.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/douglas.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Douglas and Anne to the Entrance to Kurpolis + +2005-11-19 Gordon McNutt + + * src/character.cpp, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep_crypt_mech.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/merciful-death.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/species.scm: + Haxima changes: + o Converted/added ranger, skeletal spear-thrower and skeletal warrior types to + new npc format + o Bugfix: skeletons had no limbs + + Kernel changes: + o When NPC's are choosing arms they now consider the defense and to-hit + values. Attack, defense and armor are given more weight than to-hit. + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm: + Haxima changes: + o Added the teleport ability for NPC's + o Added a cave goblin priest NPC type + +2005-11-18 Gordon McNutt + + * src/character.cpp, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/species.scm: + Haxima changes: + o Split ork faction and species into cave goblin and forest goblin + o Converted some existing goblin npc types into forest goblin hunters and + stalkers, and cave goblin slingers and berserkers. + o Added an axe weapon type + o Modified most of the Goblin Kingdom dungeons to use the new monster spawning + method + + Kernel changes: + o Bugfix: crash in Character::setTarget(). Mis-handling the targets refcount in + a corner case. + +2005-11-17 Gordon McNutt + + * src/clock.c, src/clock.h, src/ctrl.c, src/kern.c, src/place.c, src/player.cpp, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm: + Haxima changes: + o Added the new monster-spawning system for dungeon rooms. This is much simpler + than the previous monster generator systems, at the cost of some features + which weren't much used. + + Kernel changes: + o Moved the place on-entry hook invocation to the place_enter() function + o kern-get-time now returns the year, month, week and day as well as the hour + and minute + +2005-11-16 Gordon McNutt + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/kobj.scm, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/troll.scm: + Haxima changes: + o Started consolidating the NPC gobs + +2005-11-14 Gordon McNutt + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/spider.scm: + Haxima changes: + o Added forest goblin shaman + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/species.scm: + Haxima changes: + o Made curried wrapper for kern-mk-species + o Reorg'd species.scm into table format like arms.scm (make balance easier) + o Made curried wrapper for kern-mk-occ + o Reorg'd occ.scm into table format (balancing easier) + +2005-10-31 Gordon McNutt + + * worlds/haxima-1.002/altar-room.scm, worlds/haxima-1.002/dank-cave.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/lich-tomb.scm, worlds/haxima-1.002/old-mine.scm: + Haxima changes: + o Added Old Mine map + o Added Lich Tomb map + o Added Altar Room map + o Added Dank Cave map + +2005-10-30 Gordon McNutt + + * worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/kraken-lakes.scm, worlds/haxima-1.002/tblit.scm: + Haxima changes: + o Added maps for 4th level of Kurpolis + + * worlds/haxima-1.002/forsaken-prison.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/mans-hideout.scm: + Haxima changes: + o Added Forsaken Prison map + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/kraken-lakes.scm: + Haxima changes: + o Added Kraken Lakes level & its maps + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm: + Haxima changes: + o Added Death Knight's Hold + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/tblit.scm: + Haxima changes: + o Added Treasury room + +2005-10-29 Gordon McNutt + + * worlds/haxima-1.002/Attic/goblin-battle.scm, worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/grey-goblin-village.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/Attic/kurpolis.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/Attic/troll-den.scm: + Haxima changes: + o Re-organized the source for the first level of Kurpolis + o Modifed the entrance to Kurpolis to be more entrance-y + + * worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/Attic/keep_crypt.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Added Paladin's Hold + + * worlds/haxima-1.002/goblin-kingdoms.scm, worlds/haxima-1.002/Attic/haxima.scm: + Haxima changes: + o Added Shaman's Grove map + +2005-10-28 Gordon McNutt + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/nossifer.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/talking-ankh.scm: + Haxima changes: + o Added Nossifer + +2005-10-25 Gordon McNutt + + * worlds/haxima-1.002/ankh-shrine.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/silas.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/talking-ankh.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Added Ankh Shrine + o Added talking ankh + +2005-10-24 Gordon McNutt + + * worlds/haxima-1.002/dennis.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/old-absalot.scm, worlds/haxima-1.002/selene.scm, worlds/haxima-1.002/silas.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Selene + o Added Dennis + +2005-10-23 Gordon McNutt + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/old-absalot.scm, worlds/haxima-1.002/silas.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Silas + +2005-10-22 Gordon McNutt + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/items.scm, worlds/haxima-1.002/luximene.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/necromancer.scm, worlds/haxima-1.002/necromancers-lair.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Necromancer + o Added Luximene + +2005-10-21 Gordon McNutt + + * worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/jorn.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Jorn, Ghertie's first mate + +2005-10-20 Gordon McNutt + + * src/Container.cpp, src/Container.h, src/kern.c, src/terrain_map.c, worlds/haxima-1.002/gholet.scm, worlds/haxima-1.002/prison.scm: + Haxima changes: + o Added NPC Gholet + + Kernel changes: + o Bugfix: if script called kern-obj-remove-from-inventory with a count arg + greater than the numer available to remove we'd assert in + Container::takeOut. Replaced the assert with return false and emit a warning + to the console. + +2005-10-19 Gordon McNutt + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/prison.scm: + Haxima changes: + o Added Sam's Prison Chamber map as a prison below Glasdrin + +2005-10-18 Gordon McNutt + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/meaney.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/poor-house.scm, worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Meaney, one of Ghertie's ex-crew + +2005-10-17 Gordon McNutt + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/ghertie.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/poor-house.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Poor House + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/ghertie.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm: + Haxima changes: + o Added Ghertie's Quest. + +2005-10-16 Gordon McNutt + + * src/cmd.c, src/kern.c, src/player.cpp, worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Tweaked the maps a bit around the Engineer's Hut + o A few fixes to the Engineer's conversation + + Kernel changes: + o Bugfix: if reloading a game saved while on board a vehicle, upon disembarking + the vehicle would be inadvertently destroyed. Needed to add a ref_inc on load + to prevent this. + o Characters that were sleeping due to a spell would still respond with a + conversation (unlike characters sleeping due to their schedule telling them + to). Since "sleep" is a concept known to the kernel I added a check for it. + o Bugfix: sleeping party members shouldn't be able to rendezvous + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/ghertie.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/mans-hideout.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/the-man.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added the MAN + o Tweaked Ghertie's conversation + +2005-10-13 Gordon McNutt + + * worlds/haxima-1.002/engineer.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/vehicles.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added engineer + o Added voidship + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Put Lost Halls on the wilderness map + + * worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/spells.scm: + Haxima changes: + o Sprinkled lost halls with corpse loot + o Bugfix: wind spells were broken, calling kern-being-is-hostile? on non-being + objects; caused a crash + +2005-10-12 Gordon McNutt + + * src/kern.c, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spider.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/troll.scm: + Haxima changes: + o Bugfix: mongen2 exec was not evaluating kern-char-get-location, caused + monster generation to fail with a script error + o Bugfix: bog was poisoning non-being objects and emitting the noxious "Noxious + fumes!" message + o Added Gint npc type + o Added monster generators to Lost Halls + + Kernel changes: + o Bugfix: kern_char_get_occ was not returning sc->NIL for null occs + +2005-10-11 Gordon McNutt + + * src/character.cpp, src/cmd.c, src/common.c, src/common.h, src/kern.c, src/object.c, src/object.h, src/place.c, src/place.h, worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/objs.scm: + Haxima changes: + o Added searchable corpses with loot + + Kernel changes: + o Added a hook for 'search' on objects + +2005-10-10 Gordon McNutt + + * src/character.cpp, src/kern.c, worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/spider.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Added Angriss and finished her lair + + Kernel changes: + o Added kern-conv-begin, so npc's can initiate conversation with the player + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/naz.scm: + Haxima changes: + o Broke up the Lost Halls dungeon into dungeon rooms + o Added some procs to simplify dungeon room creation + +2005-10-07 Gordon McNutt + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/angriss.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/ilya.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/spider.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Almost done with Angriss lair + o Added Angriss; mostly done + o Implemented web-spew as an ability + +2005-10-05 Gordon McNutt + + * worlds/haxima-1.002/angriss-lair.scm, worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/special.scm, worlds/haxima-1.002/spider.scm, worlds/haxima-1.002/step.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Added most of Angriss's Lair + +2005-10-04 Gordon McNutt + + * src/cmd.c, src/kern.c, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/merciful-death.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/raise-merciful-death.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Added the wreck of the Merciful Death + o Added Vas Uus Ylem spell + + Kernel changes: + o Added place-add-subplace + o Bugfix: if a spell closure returned no-effect cmdCastSpell would call + log_end() twice and assert in log.c + +2005-10-03 Gordon McNutt + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/fire_sea.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Added deep lava sprite and terrain type + o Added Rune of Wisdom + o Reverted boulders to being impassable + + * worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/old-absalot.scm: + Haxima changes: + o Added permanent versions of all energy fields + o Dispell field spell will now worn on spider webs + o Added Rune of Skill + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/void-temple.scm: + Haxima changes: + o Added void temple + o Added Rune of Discretion + +2005-10-02 Gordon McNutt + + * worlds/haxima-1.002/absalot.scm, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/old-absalot.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Put Absalot on the main map + o Added mechs and... other stuff to Old Absalot + + * worlds/haxima-1.002/absalot.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/old-absalot.scm: + Haxima changes: + o Added maps for Absalot and Old Absalot + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/engineers-hut.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/vehicles.scm: + Haxima changes: + o Added map and objects for the Engineer's Hut + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/lever.scm, worlds/haxima-1.002/mans-hideout.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/tblit.scm: + Haxima changes: + o Added map and objects for the MAN's Hidedout + + * worlds/haxima-1.002/earl.scm: + Haxima changes: + o Earl sells shovels + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm, worlds/haxima-1.002/trigrave.scm: + Haxima changes: + o Added support for buried objects and a shovel + o Added Rune of Power + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/necromancers-lair.scm: + Haxima changes: + o Added map and objects for the Necromancers Lair + +2005-09-30 Gordon McNutt + + * src/cmd.c, src/common.h, src/object.c, src/object.h, worlds/haxima-1.002/food.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/jeffreys.scm, worlds/haxima-1.002/jess.scm: + Haxima changes: + o Added Jeffries to Glasdrin + o Fixed buying alcohol to add drunkuness effect (previously picking up alcohol + from the ground would do this, but not buying it) + + Kernel changes: + o Cut back turns per hour from 60 to 20 so time will pass more quickly + o Added support for the 'buy hook to object types (to support alcohol + purchases) + +2005-09-29 Gordon McNutt + + * worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/shapes.png, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added guard generators to Glasdrin + + * worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/ini.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Ini, a paladin of Glasdrin + +2005-09-28 Gordon McNutt + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/steward.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Victoria, ruler of Glasdrin + o Added a female ruler sprite + +2005-09-27 Gordon McNutt + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/chester.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Chester, arms dealer, to Glasdrin + +2005-09-26 Gordon McNutt + + * src/ctrl.c, src/map.c, src/map.h, src/place.c, src/play.c, src/scheme-private.h: + Kernel changes: + o Increased scheme CELL_SEGSIZE from 5,000 to 40,000. This reduced the + frequency of garbage collection cycles and improves responsiveness. It also + dramatically improves the load time. + o Reduced scheme CELL_NSEGMENT from 20 to 10. Since the total size was + increased with the above change I'm reverting the change I made to this + earlier when scheme was running out of memory. It isn't necessary now. + o Added a REPAINT_IF_OLD flag to map updates made solely for animation + purposes. The intention is to cut back on unnecessary map repaints in cases + where the map was recently repainted due to player actions. Should also + eliminate the "dancing sprite" effect which occurs after animation repaints + are held off for short periods during special effects like map jitter or map + flash. + + * worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/jess.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Jess, barkeep, to Glasdrin + +2005-09-25 Gordon McNutt + + * src/cmd.c, src/kern.c, src/kern.c, worlds/haxima-1.002/angela.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/patch.scm, worlds/haxima-1.002/prices.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/zones.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Map tweaks to Glasdrin + o Added doc Patch to Glasdrin + o Added npc healer scripts + + + Kernel changes: + o kern_ui_select_party_member now cleans up cmdwin + +2005-09-24 Gordon McNutt + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/keep.scm, worlds/haxima-1.002/Attic/keep_crypt.scm, worlds/haxima-1.002/keep_crypt_mech.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/objs.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm: + Haxima changes: + o Added Crypt dungeon room + +2005-09-23 Gordon McNutt + + * src/kern.c, worlds/haxima-1.002/bart.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/prices.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Added Bart the shipwright to Oparine; player can now buy ships + o Bugfix: the dungeons kurpolis and mushroom cave needed to be designated by + tags, not raw variables, in their mk-dungeon calls + + Kernel changes: + o kern-place-get-vehicle + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Lia, reagent-seller of Oparine + o Added Fing, a nixie of Oparine + + * worlds/haxima-1.002/fing.scm, worlds/haxima-1.002/ghertie.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/lia.scm, worlds/haxima-1.002/oparine.scm: + Haxima changes: + o Added Ghertie to Oparine + +2005-09-22 Gordon McNutt + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/henry.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Henry the barkeep to Oparine + + * worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/gwen.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/oscar.scm, worlds/haxima-1.002/prices.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added Oscar the Innkeeper to Oparine + +2005-09-21 Gordon McNutt + + * worlds/haxima-1.002/alchemist.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/potions.png, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added the Alchemist + o Added three new (inert) potion types: dragon's blood, hydra's blood and + lich's blood + +2005-09-20 Gordon McNutt + + * worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added the Alchemist shop to Oparine + o Set zones for Oparine + +2005-09-19 Gordon McNutt + + * src/kern.c, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/naz.scm: + Haxima changes: + o Added end of first quest and start of main quest to enchanter's conv + + Kernel changes: + o Added kern-char-add-experience + +2005-09-18 Gordon McNutt + + * src/character.cpp, src/character.h, src/kern.c, worlds/haxima-1.002/books.png, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/thud.scm, worlds/haxima-1.002/traps_1.scm: + Haxima changes: + o Finished testing/tweaks to Kathryn/Thud/Thief scenario + + Kernel changes: + o Added kern-char-force-drop and relevant support. With this, the scripter can + indicate that he wants a particular character to always drop their chest (as + opposed to dropping it based on a probability) + +2005-09-17 Gordon McNutt + + * src/character.cpp, src/kern.c, src/object.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/thud.scm: + Haxima changes: + o Bugfix: when warping in Thud and Kathryn their schedules are reset to null + o Added spell-sword-ai, Kathryn uses it + + Kernel changes: + o Added kern-char-set-schedule + o Bugfix: if a character is eating and the schedule is set to NULL then the + character will be stuck eating (and doing nothing else!). + + * src/kern.c, src/player.cpp, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/naz.scm: + Haxima changes: + o Bugfix: when losing gold or food console message said eg, "You lose -500 + gold". Got rid of the negative sign in these messages. + + Kernel changes: + o Scaled back the thief's conversation in accordance with some plot changes + o Bugfix: kobj-get was printing eg, "Jack gets a beer" even when Jack didn't + really get the beer (because Jack lacked a container in which to put the + beer) + +2005-09-15 Gordon McNutt + + * src/character.cpp, src/character.h, src/kern.c, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/mouse.scm, worlds/haxima-1.002/naz.scm: + Haxima changes: + o Added Mouse, the Accursed Thief; not fully tested yet + o kobj-get checks if kern-obj-put-into succeeded (it won't for npc's with no container) + + Kernel changes: + o Added Character::leavePlayer() to remove player party members + o Added kern-char-leave-player + o kern-obj-remove uses Object::remove() now instead of place_remove_object() + o kern-obj-put-into now returns bool + +2005-09-13 Gordon McNutt + + * src/cmd.c, src/object.c, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/food.scm, worlds/haxima-1.002/Attic/haxima.scm: + Haxima changes: + o Added Thief's Den + o Added rune types + + Kernel changes: + o Added simple critical hits: if (20 <= (1d20 + log2(lvl))) then the defender's + armor is ignored. + o Disarming traps is now (20 <= (1d20 + log2(dex) + log2(lvl))) + + * src/cmd.c, src/common.c, src/common.h, src/ctrl.c, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/traps_1.scm, worlds/haxima-1.002/traps_2.scm, worlds/haxima-1.002/traps_3.scm: + Haxima changes: + o Added final trap level to Thief's ladder, it's quite evil IMHO + o Arranged riddles in first trap level to be serial and different + o Tweaked some armor/weapon values + + Kernel changes: + o Added simple critical hits: if (20 <= (1d20 + log2(lvl))) then the defender's + armor is ignored. + o Disarming traps is now (20 <= (1d20 + log2(dex) + log2(lvl))) + +2005-09-11 Gordon McNutt + + * src/character.cpp, src/character.h, src/cmd.c, src/ctrl.c, src/ctrl.h, src/kern.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm: + Haxima changes: + + o Added mk-edge-gen, which creates a v2 monster generator that doesn't care if + the player is in LOS. Intended for edge-of-map or over-portal generators, + where it doesn't look odd for an npc to suddenly appear. + + o Bugfix: vampiric-touch might destroy it's victim then try to print its + name. Uses refcount now. + + Kernel changes: + + o Character level added as a bonus to to-hit and to-def + + o Bugfix: was not calculating attacker's to-hit penalty from armor + + o Bugfix: could h)andle invisible mechs when not revealed + + * src/character.cpp, src/cmd.c, src/kern.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/items.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/potions.scm: + Haxima changes: + o vampiric touch damage limited to victim's hp + o Mana and healing potions on the ground will check for an adjacent npc that + wants them. If the npc does not have an action point debt it will + automatically get the potion, losing an action point in the process. This + idea comes from Ray Dillinger's discussion of "Displaced Actions". This way + npc's don't have to know about potions and search for them every turn. Since + potions are rarer than npc's and quickly picked up, it's more efficient to + have the potion search for npcs! + o bugfix: death knights of insufficient level were using disease touch + + Kernel changes: + o Bugfix: on reload a character's readied arms were also added to its + inventory, causing a double count of readied items. + o Bugfix: kern_obj_remove_from_inventory was doing nothing on + non-player-controlled characters (because Character::takeOut was doing + nothing) + + * src/character.cpp, src/character.h, src/cmd.c, src/kern.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm: + Haxima changes: + o Added ability.scm for special NPC abilities + o Death knights use Disease Touch and Vampiric Touch + o Death knights drink mana potions + + Kernel changes: + o Added Character::setMana + o Added kern-char-get-max-mana + o Added kern-char-set-hp + o Added kern-char-set-mana + o Added kern-type-get-name + o Bugfix: kern_ui_select_party_member not printing a "-" in the cmdwin + + * src/ctrl.c, src/kern.c, worlds/haxima-1.002/ability.scm, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/occs.scm: + Haxima changes: + o Added disarm ability at L3 + o Guard AI attempts to disarm foes + + Kernel changes: + o Added kern-char-get-readied-weapons + o Added kern-char-unready + o Added more verbose combat spewage + +2005-09-10 Gordon McNutt + + * src/character.cpp, src/character.h, src/kern.c, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/npc-types.scm: + Haxima changes: + o death-knight generator in great hall sets level to 1d8 (test of kernel + changes) + + Kernel changes: + o Added Character::setLevel + o Added kern-char-set-level + o Descriptions of characters via x)amine now show their level + + * src/ctrl.c, worlds/haxima-1.002/gate-guard.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/mushroom-cave.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/Attic/slimy-cavern-entry.scm, worlds/haxima-1.002/spider.scm, worlds/haxima-1.002/troll.scm, worlds/haxima-1.002/yellow-slime.scm: + Haxima changes: + o Added step version of mongen2 + o Bugfix: where yellow slimes summoned green slimes I forgot to remove a + parameter passed to the spell, caused a crash + + Kernel changes: + o ctrl.c -- ctrl_idle() now checks return value of AI closure. The closure + should return true iff it handled the turn. If it returns false then control + falls through to the standard kernel AI. This allows magic users or creatures + with special ability to test if they want to do something unique, and if not + then to go ahead with the generic AI. + + * src/kern.c, worlds/haxima-1.002/Attic/goblin-battle.scm, worlds/haxima-1.002/Attic/grey-goblin-village.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/tools.scm, worlds/haxima-1.002/Attic/troll-den.scm: + Haxima changes: + o Upgraded all monster generators to mongen2 + o Upgraded mk-green-slime to be mk-gen-step + o Fixed torches + o With the kernel change below got rid of all the spurious "Noxious fumes!" + messages which occur in boggy places when slimes are around + + Kernel changes: + o kern_obj_add_effect propogates back the result of obj->addEffect() so the + script can check if the effect was actually applied + +2005-09-08 Gordon McNutt + + * src/Container.h, src/character.cpp, src/cmd.c, src/common.h, src/kern.c, src/map.c, src/map.h, src/object.c, src/place.c, src/session.c, src/session.h, worlds/haxima-1.002/combat-maps.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/portcullis.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/tblit.scm: + Haxima changes: + o Added dungeon room: Thief's Ladder III + o Added Death Knight npc type + o Added halberdier guard npc type + o Added crossbow guard npc type + + Kernel changes: + o Added hard-coded probabilities to drop items and chests instead of dropping + all the time. Less litter. + o When an object gets hit it flashes a damage sprite + o Bugfix: in the rare occasions when more than one being occupies the same tile + the X)amine command was only showing one of them + +2005-09-07 Gordon McNutt + + * worlds/haxima-1.002/bim.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/lever.scm, worlds/haxima-1.002/traps_2.scm, worlds/haxima-1.002/traps_3.scm, worlds/haxima-1.002/traps_3_mechs.scm: + Haxima changes: + o Added dungeon room Thief's Ladder II + +2005-09-06 Gordon McNutt + + * worlds/haxima-1.002/bim.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/portcullis.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/traps_1.scm, worlds/haxima-1.002/traps_2.scm: + Haxima changes: + o Added dungeon room Thief's Ladder II + +2005-09-05 Gordon McNutt + + * src/clock.c, src/clock.h, src/cmd.c, src/foogod.c, src/kern.c, src/object.c, worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/gwen.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/melvin.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/shroom.scm: + Haxima changes: + o Added Melvin of Bole + o Added Hackle of Bole + o Added Thief's Door (destination not correct yet) + + Kernel changes: + o Added kern-get-time to return time-of-day as (hours . minutes) + o Effects on generic objects now saved/loaded + o Bugfix: Reveal was not shown in status window + + * worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/hackle.scm, worlds/haxima-1.002/Attic/haxima.scm: + Haxima changes: + o Map cleanup in Bole + o Conversation tweaks in Bole + + * worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/traps_1.scm: + Haxima changes: + o Added dungeon room Thief's Ladder I + o Wired up Thief's Door destination + o Added riddle mechanism + +2005-09-03 Gordon McNutt + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/chanticleer.scm, worlds/haxima-1.002/food.scm, worlds/haxima-1.002/miggs.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/trigrave.scm: + Haxima changes: + o Added Miggs, tavern-keeper of Trigrave + o Added a fat townswoman sprite + +2005-09-02 Gordon McNutt + + * worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/food.png, worlds/haxima-1.002/food.scm, worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added a "drunk" effect for alcoholic beverages + +2005-09-01 Gordon McNutt + + * src/Container.cpp, src/cmd.c, src/kern.c, worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/chanticleer.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/gwen.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/jim.scm, worlds/haxima-1.002/scrolls.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/Attic/trigrave-zones.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Added a stun wand + o Maintenance on Trigrave conversations + o Added Earl's chest + + Kernel changes: + o Containers now save/reload effects on them + o The 'open' command no longer works on invisible containers and mechs (unless + Reveal is in effect) + + * worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/trigrave.scm: + Haxima changes: + o Added a stun wand + o Maintenance on Trigrave conversations + +2005-08-28 Gordon McNutt + + * worlds/haxima-1.002/camping-map.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/scrolls.scm, worlds/haxima-1.002/zane.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Removed all the guards and mongens from Enchanter's Tower + o Added magically locked doors, treasure and beds to ET + o Added Enchanter to ET + +2005-08-25 Gordon McNutt + + * src/character.cpp, src/ctrl.c, src/dtable.h, src/kern.c, src/object.c, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/gate-guard.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/zane.scm: + Kernel changes: + o Added kern-being-is-ally? + o Added kern-being-get-visible-allies + o Added kern-char-get-level + o Bugfix: dtable_are_allies() was referencing the value for hostiles, not + allies + o Tweaked XP needed for advancement down a little; level 2 now occurs at 32XP + o NPC's with ranged weapons will try and move away from foes who are blocking + them + + Haxima changes: + o Added slime and skeleton generators to enchanter's tower + o Enchanter's gate guards will summon rangers when they see hostiles + o Gate guards will also cast dispell undead if they see skeletons + +2005-08-24 Gordon McNutt + + * worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/gate-guard.scm: + Haxima changes: + o Gate guards now pathfind to their posts. + +2005-08-23 Gordon McNutt + + * configure.ac, src/kern.c, src/nazghul.c, src/session.c, worlds/haxima-1.002/bim.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/gate-guard.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/kobj.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/Attic/spawnpoint.scm, worlds/haxima-1.002/splash.png, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/timer.scm: + Build changes: + o Bumped version to 0.5 + + Kernel changes: + o Changed location where kernel looks for splash image to be the current + directory + o Erasing screen before painting frame for first time to get rid of residual + splash image + + Haxima changes: + o Minor conversation cleanup + o Added gate-guard.scm + o Added gate guards to enchanters tower + o Updated splash image + o Added a generic timer mech; originally I planned to use this with gate guards + but didn't need it. Since these will probably prove to be useful for other + things I'm adding the file to CVS (but not loading it on startup). + + * src/character.cpp, src/kern.c, src/place.c, src/place.h: + Kernel changes: + o Bugfix: npc's no longer try to shoot at targets through walls. The + Character::canSee() method now checks LOS + + * worlds/haxima-1.002/Attic/af-entry.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/Attic/slimy-cave-entry.scm, worlds/haxima-1.002/Attic/slimy-cavern-entry.scm, worlds/haxima-1.002/species.scm: + Haxima changes: + o Consistently named all the "is-species?" type procedures + + * worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/gate-guard.scm, worlds/haxima-1.002/Attic/haxima.scm: + Haxima changes: + o Added green slime generator to enchanter's tower + o Gate guards now close their gates when hostiles are visible + +2005-08-21 Gordon McNutt + + * src/character.cpp, src/ctrl.c, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/ilya.scm, worlds/haxima-1.002/shard.scm: + Kernel changes: + o Bugfix: ctrl_do_attack() was referring to the target after it could have been + destroyed, causing an assert + + Haxima changes: + o Repositioned Gregor's Hut + o Repositioned Abandoned Farm + o Some conversation cleanup + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/oparine.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Added Oparine + +2005-08-20 Gordon McNutt + + * worlds/haxima-1.002/glasdrin.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Added Glasdrin + +2005-08-11 Gordon McNutt + + * worlds/haxima-1.002/enchanters-tower.scm: + Haxima changes: + o Tweaks to enchtwr + +2005-08-10 Gordon McNutt + + * worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Reworked enchanter's tower into something smaller + +2005-08-09 Gordon McNutt + + * worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/npc-types.scm: + Haxima changes: + o Added Troll Den dungeon room + o Fixed troll boulder-throwing + o Tweaked troll npc type equipment + + * worlds/haxima-1.002/bill.scm, worlds/haxima-1.002/bole.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/kathryn.scm, worlds/haxima-1.002/may.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/thud.scm, worlds/haxima-1.002/zones.scm: + Haxima changes: + o Ported Bole and existing occupants + +2005-08-08 Gordon McNutt + + * src/kern.c, src/scheme.c, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/Attic/goblin-battle.scm, worlds/haxima-1.002/Attic/grey-goblin-village.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/Attic/troll-den.scm, worlds/haxima-1.002/troll.scm: + Haxima changes: + o Added Troll Den dungeon room + o Fixed troll boulder-throwing + +2005-08-07 Gordon McNutt + + * src/character.cpp, src/common.h, src/kern.c, src/place.c, src/place.h, worlds/haxima-1.001/enchanters-tower.scm, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/Attic/grey-goblin-village.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/Attic/kurpolis.scm, worlds/haxima-1.002/mushroom-cave.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/sprites.scm: + Kernel changes: + o At long last, after no end of polite requests from Sam, implemented u5-style + "adjacent" dungeon rooms, where stepping off the map edge of one dungeon will + land you in a neighboring room. It should work with towns and, for all I + know, wilderness zones, too (but stepping off the edge of a wilderness combat + map will still take you back to the wilderness). + + Haxima changes: + o Added two stub dungeon rooms + o Fixed the entrance to the mushroom cave to use an auto-entrance portal; this + is the recommended way for all wilderness dungeon entrances (at some point in + the past I must have removed the party E)nter command... don't recall when or + why) + + * src/character.cpp, src/player.cpp, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/Attic/save.scm: + Kernel changes: + o Bugfix: with the recent multi-place schedule changes, when an NPC with a + schedule joins the player party it must be removed from the list of NPC's + with schedule, otherwise on entry to a town the kernel will try and move it + to its appointment, resulting in crashes or missing party members. + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/doris.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/gwen.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/sprites.scm: + Haxima changes: + o Added Doris to Green Tower + o Added a female townsman sprite + + * worlds/haxima-1.002/deric.scm, worlds/haxima-1.002/green-tower.scm: + Haxima changes: + o Added Deric to Green Tower + + * worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/goblin-battle.scm, worlds/haxima-1.002/Attic/grey-goblin-village.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/Attic/kurpolis.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/species.scm: + Haxima changes: + o Added dungeon room: Goblin Village + o Added dungeon room: Goblin Battle + +2005-08-06 Gordon McNutt + + * src/character.cpp, src/kern.c, src/place.c, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/mushroom-cave.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/reagents.png, worlds/haxima-1.002/reagents.scm, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/species.scm: + Kernel changes: + o Bugfix: x)amine crashed when a monster generator was examined after loading a + saved game. Fix is a hack: objects w/o names are assumed to be intentionally + never-visible. + + Haxima changes: + o Ported mushroom cave from ghulscript + o Ported Shroom's mushroom quest from ghulscript + + * src/place.c, worlds/haxima-1.002/green-tower-lower.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/portcullis.scm, worlds/haxima-1.002/Attic/save.scm: + Kernel changes: + + o Bugfix: if two chests were stacked on the same tile with nothing else then + x)amine would only report one; this was generally true of any objects that + had the same ObjectType + + Haxima changes: + o Mechanisms and other objects added to Green Tower + o Added Green Tower Lower and its mechanisms + + * src/play.c, src/vmask.c, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/Attic/sched.scm, worlds/haxima-1.002/shroom.scm: + Kernel changes: + o Added call to vmask_flush_all in the reload function in an attempt to fix the + remembered-vmask problem on reload; had no visible effect but I think we need + + Haxima changes: + o Added Shroom to Green Tower + + * worlds/haxima-1.002/books.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/Attic/save.scm: + Haxima changes: + o Added Gen to Green Tower + +2005-08-05 Gordon McNutt + + * worlds/haxima-1.002/door.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/green-tower.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Added Green Tower; map is there but most objects and NPCs still have to be + ported from the old ghulscript + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Finished fining-in the wilderness map + +2005-08-04 Gordon McNutt + + * worlds/haxima-1.002/addons.png, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/terrains.scm: + Haxima changes: + o Created a "stars" terrain type and sprite + o Filled in "void" part of wilderness map with stars + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o More work on the wilderness map + + * worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/shard.scm: + Haxima changes: + o Began to fine-in the area around the shrine + + * worlds/haxima-1.002/shard.scm: + Haxima changes: + o Finished roughing out the wilderness map + +2005-08-03 Gordon McNutt + + * src/Party.cpp, src/kern.c, src/terrain_map.c, src/terrain_map.h, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/shard.scm: + Kernel changes: + o Added composite maps + o Bugfix: failing to create characters in Party::createMembers() resulted in an + infinite loop. It now bails out gracefully if this fails. + + Haxima changes: + o Modified shard.scm to create a composite map for the wilderness + o Removed more references to deleted object types in npc-types.scm + + * src/cmd.c, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/shard.scm: + Kernel changes: + o Bugfix: infinite loop in terrain-fill function if starting point has same + terrain type as the fill + + Haxima changes: + o Expanded shard map to 128x96, 60% roughed-in + +2005-08-02 Gordon McNutt + + * Attic/Makefile.in, src/Party.cpp, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/Attic/save.scm: + Bugfix: crash if an npc factory references an invalid object + + * src/heap.h: + Cleaned up header + +2005-08-01 Gordon McNutt + + * src/character.cpp, src/combat.c, src/common.h, src/ctrl.c, src/object.c, src/player.cpp, src/player.h: + Kernel changes: + o +5 XP to the whole party on combat victory + o Moved some of the AI stuff to prepare for more AI changes + +2005-07-30 Gordon McNutt + + * src/status.c: + bugfix: spells without sprites would crash in ztats; now check for a null sprite. I'm not going to invest in sprites for spells since they never appear outside of inventory. + + * worlds/haxima-1.002/abandoned-cellar.scm, worlds/haxima-1.002/abandoned-farm.scm, worlds/haxima-1.002/addons.png, worlds/haxima-1.002/Attic/af-entry.scm, worlds/haxima-1.002/ai.scm, worlds/haxima-1.002/arms.png, worlds/haxima-1.002/arms.scm, worlds/haxima-1.002/bakup.scm, worlds/haxima-1.002/beds.scm, worlds/haxima-1.002/bim.scm, worlds/haxima-1.002/books.png, worlds/haxima-1.002/books.scm, worlds/haxima-1.002/bridge.scm, worlds/haxima-1.002/camping-map.scm, worlds/haxima-1.002/cannon.wav, worlds/haxima-1.002/chanticleer.scm, worlds/haxima-1.002/charset.png, worlds/haxima-1.002/combat-maps.scm, worlds/haxima-1.002/containers.scm, worlds/haxima-1.002/conv.scm, worlds/haxima-1.002/damage.wav, worlds/haxima-1.002/door.scm, worlds/haxima-1.002/drawbridge.scm, worlds/haxima-1.002/earl.scm, worlds/haxima-1.002/effects.scm, worlds/haxima-1.002/enchanter.scm, worlds/haxima-1.002/enchanters-tower-zones.scm, worlds/haxima-1.002/enchanters-tower.scm, worlds/haxima-1.002/enter_moongate.wav, worlds/haxima-1.002/fields.scm, worlds/haxima-1.002/food.png, worlds/haxima-1.002/food.scm, worlds/haxima-1.002/frame.png, worlds/haxima-1.002/game.scm, worlds/haxima-1.002/gen.scm, worlds/haxima-1.002/generic-mech.scm, worlds/haxima-1.002/gregor.scm, worlds/haxima-1.002/Attic/gregors-hut-zones.scm, worlds/haxima-1.002/gregors-hut.scm, worlds/haxima-1.002/gwen.scm, worlds/haxima-1.002/Attic/haxima.scm, worlds/haxima-1.002/horse.wav, worlds/haxima-1.002/ifc.scm, worlds/haxima-1.002/ilya.scm, worlds/haxima-1.002/init.scm, worlds/haxima-1.002/items.scm, worlds/haxima-1.002/jim.scm, worlds/haxima-1.002/kobj.scm, worlds/haxima-1.002/lever.scm, worlds/haxima-1.002/loc.scm, worlds/haxima-1.002/lost-halls.scm, worlds/haxima-1.002/money.png, worlds/haxima-1.002/money.scm, worlds/haxima-1.002/monster-generator.scm, worlds/haxima-1.002/moon.scm, worlds/haxima-1.002/Attic/moongate-clearing-zones.scm, worlds/haxima-1.002/moongate-clearing.scm, worlds/haxima-1.002/moongate.scm, worlds/haxima-1.002/moons.png, worlds/haxima-1.002/naz.scm, worlds/haxima-1.002/npc-types.scm, worlds/haxima-1.002/objs.scm, worlds/haxima-1.002/occs.scm, worlds/haxima-1.002/palette.scm, worlds/haxima-1.002/parties.scm, worlds/haxima-1.002/Attic/player.scm, worlds/haxima-1.002/portals.scm, worlds/haxima-1.002/portcullis.scm, worlds/haxima-1.002/potions.png, worlds/haxima-1.002/potions.scm, worlds/haxima-1.002/pre-entry-hooks.scm, worlds/haxima-1.002/reagents.png, worlds/haxima-1.002/reagents.scm, worlds/haxima-1.002/roland.scm, worlds/haxima-1.002/rowing.wav, worlds/haxima-1.002/rune.png, worlds/haxima-1.002/Attic/save.scm, worlds/haxima-1.002/Attic/sched.scm, worlds/haxima-1.002/scrolls.png, worlds/haxima-1.002/scrolls.scm, worlds/haxima-1.002/shapes.png, worlds/haxima-1.002/shard.scm, worlds/haxima-1.002/shroom.scm, worlds/haxima-1.002/Attic/slimy-cave-entry.scm, worlds/haxima-1.002/Attic/slimy-cavern-entry.scm, worlds/haxima-1.002/slimy-cavern-zones.scm, worlds/haxima-1.002/slimy-cavern.scm, worlds/haxima-1.002/sounds.scm, worlds/haxima-1.002/Attic/spawnpoint.scm, worlds/haxima-1.002/species.scm, worlds/haxima-1.002/spells.scm, worlds/haxima-1.002/spider.scm, worlds/haxima-1.002/sprite-sets.scm, worlds/haxima-1.002/sprites.scm, worlds/haxima-1.002/tblit.scm, worlds/haxima-1.002/terrains.scm, worlds/haxima-1.002/tools.png, worlds/haxima-1.002/tools.scm, worlds/haxima-1.002/Attic/trigrave-entry.scm, worlds/haxima-1.002/Attic/trigrave-zones.scm, worlds/haxima-1.002/trigrave.scm, worlds/haxima-1.002/troll.scm, worlds/haxima-1.002/urt.scm, worlds/haxima-1.002/vehicles.scm, worlds/haxima-1.002/walk.wav, worlds/haxima-1.002/yellow-slime.scm, worlds/haxima-1.002/zane.scm: + New stripped-down haxima + +2005-05-29 Gordon McNutt + + * src/astar.h, src/cmd.c, src/cursor.cpp, src/cursor.h, src/map.c, src/place.c, src/place.h: + Kernel changes: + o The cursor feature now shades the region which is out of cursor range. I + believe this feature was originally suggested by Sam. + o Added a fast circle-drawing routine to map.c but decided not to use it for + now. + +2005-05-28 Gordon McNutt + + * src/character.cpp, worlds/haxima-1.001/enchanters-tower-zones.scm, worlds/haxima-1.001/enchanters-tower.scm, worlds/haxima-1.001/gregor.scm, worlds/haxima-1.001/gregors-hut-zones.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/zane.scm: + Part 3 of changes to allow character schedules to span multiple places + + Kernel changes: + o Bugfixes + + Haxima changes: + o Gregors now splits his time between his hut and the moongate clearing (first + multi-place schedule) + + * src/character.cpp, src/character.h, src/place.c, src/play.c, src/sched.c, src/sched.h, src/session.c, src/session.h: + Part 2 of changes to allow character schedules to span multiple places + + Kernel changes: + o Added a list for characters with schedules to the session struct + o Modified Character::setSchedule() to add itself to the list if the schedule + is not null + o Modified Character destructor to remove itself from the list if it was put on + it + o Added Character::introduce() method to drop an npc onto the map if it needs + to come in on the current hour. Currently it just drops the npc onto its + appointment. + o Modifed Character::commuting to handle off-place destinations as a special + case. Currently it just teleports them out to their destination. + o Modified the play loop to check for characters that need to be introduced on + the hour. + + * src/cmd.c, src/cmd.h, src/ctrl.c, src/event.c, src/event.h: + Kernel changes: + o Consolidated some of the movecursor functions in cmd.c + +2005-05-27 Gordon McNutt + + * scripts/RELEASE_CHECKOFF, scripts/ghul-indent, src/character.cpp, src/kern.c, src/object.c, src/sched.c, src/sched.h, worlds/haxima-1.001/chanticleer.scm, worlds/haxima-1.001/enchanters-tower-zones.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/gregors-hut-zones.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/trigrave-zones.scm: + Part 1 of changes to allow character schedules to span multiple places + + Kernel changes: + o Modified kern-mk-sched to specify a place for each schedule entry + o Added place_sym and place to struct appt (sched.h) + o Added sched_get_appointment(), passing in the time; this resolves the scheme + place varname to the kernel place structure + o Modified Character::synchronize() to use sched_get_appointment() and to get + the place from the appointment instead of itself + + Haxima changes: + o Modified all scheme appointments to specify the place + +2005-04-21 Gordon McNutt + + * src/Attic/agent.c: + Bugfix: manually unreadying items readied by the agent + +2005-03-16 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h: + nazbot_br changes: + o Added type_is_usable() + o Added actor_use_item() + o Removed unimplemented function declarations from agent.h + + * worlds/haxima-1.001/Attic/atf.scm, worlds/haxima-1.001/Attic/map-3.scm: + Changed map-3.scm to have the steal-item quest + +2005-03-12 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, src/nazghul.c, src/session.h, worlds/haxima-1.001/Attic/map-1.scm, worlds/haxima-1.001/Attic/map-2.scm, worlds/haxima-1.001/Attic/map-3.scm: + Kernel changes: + o agent_quit() requires the actor as an arg now (so it can evaluate the final + score) + o main() now returns the agent score if the agent accomplished the goal and + zero otherwise + o Added two new fields to the session struct for the agent score and success + flag + + Script changes: + o Added three new startup games for agent training: map-1.scm, map-2.scm and + map-3.scm. These are all 32x32 single-map games and re-use existing maps. + + * worlds/haxima-1.001/Attic/atf.scm: + Added health and mana potions suitable for a bot (no selection ui) + + * worlds/haxima-1.001/Attic/map-1.scm: + file map-1.scm was initially added on branch nazbot_br. + + * worlds/haxima-1.001/Attic/map-2.scm: + file map-2.scm was initially added on branch nazbot_br. + + * worlds/haxima-1.001/Attic/map-3.scm: + file map-3.scm was initially added on branch nazbot_br. + +2005-03-05 Gordon McNutt + + * src/Attic/agent.c, src/cmd.c, worlds/haxima-1.001/Attic/atf.scm: + Kernel changes: + o actor_readied() and actor_attack_being() account for the species weapon, if + any + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c: + Had to pull spell mixing back out -- spell casting is so interactive that this feature will probably have to wait until next time. Added functions to get current hit and mana points. + + * src/Attic/beowulf.c, worlds/haxima-1.001/Attic/arena.scm, worlds/haxima-1.001/Attic/atf.scm: + Script changes: + o Added mk-map, a wrapper to simplify making places + + Kernel changes: + o Added beowulf_move to standardize the door-opening strategy for all movement + +2005-03-04 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, worlds/haxima-1.001/Attic/arena.scm: + Added actor_mix to the agent interface for mixing spells + +2005-03-03 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c: + Removed more functions from the agent interface + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c: + More cleanup of agent interface; removed some functions I decided I didn't want in the interface + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, src/kern.c: + More docs and cleanup to the agent interface + +2005-03-01 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, src/kern.c, worlds/haxima-1.001/Attic/arena.scm, worlds/haxima-1.001/Attic/atf.scm: + Kernel changes: + o Implemented goal-checking for KILL_ALL_MONSTERS + o Split actor_eval into actor_eval and actor_accomplished_goal + + * src/Attic/agent.c, worlds/haxima-1.001/Attic/atf.scm: + Kernel changes: + o Implemented goal-checking for ESCAPE_DUNGEON + + * src/Attic/agent.h: + nazbot_br changes: + o adding comments to document agent.h + +2005-02-19 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/kern.c, src/session.c, src/session.h, worlds/haxima-1.001/Attic/atf.scm, worlds/haxima-1.001/items.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/dgervais/dg_commodities.trans.png: + Kernel changes: + o Added kern_agent_set_goal + o Implemented goal-checking for GOAL_STEAL_ITEM + + Image changes: + o Modified a copy of dgervais glowing grail sprite to pulsate + +2005-02-18 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, src/closure.c, src/kern.c, src/session.h, worlds/haxima-1.001/Attic/arena.scm, worlds/haxima-1.001/Attic/atf.scm: + Kernel changes: + o Added actor_eval + o Added kern_set_agent_eval_weights + + Bot changes: + o Bugfix: beowulf_rearm did not clear the rearm flag when it had no arms, + causing it to get stuck trying to rearm + + Script changes: + o Added gold to arena.scm + o atf.scm calls kern-set-agent-eval-weights + +2005-02-16 Gordon McNutt + + * src/Attic/beowulf.c: + ifdefined-out unfinished code + + * worlds/haxima-1.001/Attic/arena.scm: + file arena.scm was initially added on branch nazbot_br. + + * worlds/haxima-1.001/Attic/arena.scm, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/enchanters-tower.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/palette.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/terrains.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + making sure nazbot_br is checked in + + * worlds/haxima-1.001/Attic/atf.scm: + file atf.scm was initially added on branch nazbot_br. + + * worlds/haxima-1.001/Attic/atf.scm: + The agent training framework start file + +2005-02-15 Gordon McNutt + + * AUTHORS, BUGS, ChangeLog, INSTALL, Attic/aclocal.m4, scripts/RELEASE_CHECKOFF, scripts/ghul-test-install, src/nazghul.c, src/play.c, worlds/haxima-1.001/images/gmcnutt/features2.png: + Kernel changes: + o using PACKAGE_VERSION from config.h now + + * Attic/Makefile.in, Attic/configure, scripts/RELEASE_CHECKOFF, src/object.c: + Kernel changes: + o removed some noisy debug + +2005-02-12 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c: + nazbot_br changes: + o bot quits when nothing left to explore + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, src/character.cpp, src/knapsack.h: + nazbot_br changes: + o bot rearms itself when it gets some loot + o bot opens doors + +2005-02-09 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c: + nazbot_br changes: + o player bot opens chests and picks up items + +2005-02-08 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, src/character.cpp: + nazbot_br changes: + o player bot pursues and attacks hostiles in LOS + +2005-02-06 Gordon McNutt + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c: + nazbot_br changes: + o agent keeps track of where it has seen hostiles, loot, or hazardous terrain + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, src/kern.c, src/map.c, src/object.c, src/place.c, src/place.h: + nazbot_br changes: + o agent will try and explore the entire map, keeping track of where it has been + and where it could not find a path to + +2005-02-06 Andreas Bauer + + * configure.ac: + Sun Feb 6 12:23:20 CET 2005 Andreas Bauer + + * configure.ac: AC_CONFIG_HEADERS, use [] around file name + * configure.ac: increase program version number to 0.4.0 + +2005-02-05 Gordon McNutt + + * src/Makefile.am, src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, src/Attic/beowulf.h, src/character.cpp, src/character.h, src/ctrl.c: + nazbot_br changes: + o agents can now keep state on their actors, one agent per actor + o characters now keep a pointer to their agent + o ctrl allocates an agent when needed + o characters destroy agents when they are destroyed + o beowulf agent ifc placed behind generic agent ifc + + * src/Makefile.am, src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c, src/ctrl.c, src/ctrl.h, src/nazghul.c, src/play.c: + The ';' key now toggles the player bot on/off + + * src/Attic/agent.c: + file agent.c was initially added on branch nazbot_br. + + * src/Attic/agent.c, src/Attic/agent.h, src/Attic/beowulf.c: + nazbot_br changes: + o agent can move around randomly + + * src/Attic/agent.h: + file agent.h was initially added on branch nazbot_br. + + * src/Attic/beowulf.c: + file beowulf.c was initially added on branch nazbot_br. + + * src/Attic/beowulf.h: + file beowulf.h was initially added on branch nazbot_br. + + * src/nazghul.c: + Added --bot switch + +2005-02-02 Gordon McNutt + + * src/character.cpp, src/nazghul.c, src/object.c: + Kernel changes: + o Bugfix: crash when printing the name of the player party's inventory + o Bugfix: crash when exiting a place after a player party member's last target + died due to extenuating circumstances (ie fire field) + + * worlds/haxima-1.001/enchanters-tower.scm: + Added some missing script files + +2005-01-30 Andreas Bauer + + * ChangeLog, Makefile.am, autogen.sh, configure.ac, m4/Makefile.am, m4/sdl.m4: + Sun Jan 30 17:50:58 CET 2005 Andreas Bauer + + * m4/sdl.m4: new + * configure.ac: modify check for SDL library + +2005-01-28 Gordon McNutt + + * AUTHORS: + Filled out AUTHORS based on ChangeLog + + * BUGS, ChangeLog, Attic/RELEASE_NOTES, Attic/configure, Attic/configure.in, doc/USERS_GUIDE, scripts/RELEASE_CHECKOFF, src/cmd.c, src/nazghul.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm: + Pre-release checkin: + o updated version number + o put startup scripts at defaults + +2005-01-27 Gordon McNutt + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/chanticleer.scm, worlds/haxima-1.001/containers.scm, worlds/haxima-1.001/gwen.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/jim.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/trigrave.scm, worlds/haxima-1.001/images/mixed/mine-32x32.png: + Haxima changes + o Fixed some deficiencies in the Trigrave conversations. + +2005-01-26 Gordon McNutt + + * doc/USERS_GUIDE, src/astar.c, src/character.cpp, src/kern.c, src/place.c, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/enchanters-tower-zones.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/zane.scm: + Kernel changes: + o Increased max depth of pathfinding since it wasn't enough for the 65x65 + Enchanter's Tower + o Fixed a lurking bug where we could overwrite an array boundary if an NPC had + over 100 items in their container + o Improved NPC self-arming alg by ignoring items with zero heuristic value + + Haxima changes: + o Added Zane, a ranger who hangs out at the Enchanter's Tower + + * worlds/haxima-1.001/conv.scm, worlds/haxima-1.001/earl.scm, worlds/haxima-1.001/spells.scm, worlds/haxima-1.001/zane.scm: + Haxima changes + o Zane trades in some reagents and potions + o Removed some reagents from Earl's shop + o Added the "Sanct Nox" spell which grants temporary immunity to poison + +2005-01-25 Gordon McNutt + + * src/cmd.c: + Kernel changes: + o Implemented feature request [ 1071337 ] Rest until sunrise + + * src/ctrl.c: + Kernel changes: + o Implemented feature request [ 1071364 ] Automatically open doors by walking + into them. Didn't implement auto-lockpicking since the kernel can't tell a + door from a lever (the kernel doesn't know what a door or a lockpick is, or + that they are related). Bummer. + + * src/ctrl.c: + Kernel changes: + o Implemented feature request [ 1074366 ] Leave combat map with Esc after + victory + + * src/status.c: + Kernel changes: + o Implemented feature request [ 1074387 ] Page up/down keys should always work + in item menus. + + * worlds/haxima-1.001/earl.scm, worlds/haxima-1.001/gwen.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/jim.scm: + Haxima changes + o Modified the shopkeeper's dialogues to indicate what time they open, as per + feature request [ 1074389 ]. + + * worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/spells.scm: + Haxima changes + o Implemented feature request [ 1074364 ] Resurrected characters should be + asleep + +2005-01-23 Gordon McNutt + + * ChangeLog, src/place.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/spider.scm: + Haxima changes: + o Rebalanced movement costs and speeds to improve performance in the Abandoned + Farm and the Lost Halls. + o Simplified spider egg execution to speedup performance + + * ChangeLog, src/ctrl.c, src/dtable.c, src/dtable.h, src/effect.c, src/effect.h, src/factions.h, src/kern.c, src/object.c, worlds/haxima-1.001/Attic/class-bak.scm, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/shard.scm, worlds/haxima-1.001/spells.scm: + Kernel changes: + o Fixed [ 1106462 ] An Xen Bet + o Changed diplomacy table from being stack-based to a simple + increment/decrement + o Added another function to effects: restart, to be used specifically when + restoring effects on a reload + + Haxima changes: + o Added the An Xen Bet spell as mentioned in Ilya's conv + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/npc-types.scm: + Haxima + o Refactored doors to make it easier to add new types. + o Added a windowed door to Roland's cell + o Added a few new keywords to Roland's conversation + o Added images and sprites for a windowed door + + * worlds/haxima-1.001/haxima.scm: + Haxima changes + o More work on enchanter's tower + + * worlds/haxima-1.001/palette.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/terrains.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + Haxima changes + o More work on enchanter's tower + o Added a brazier sprite & terrain type + +2005-01-22 Gordon McNutt + + * src/Arms.cpp, src/Party.cpp, src/character.cpp, src/cmd.c, src/combat.c, src/kern.c, src/object.c, src/object.h, src/place.c, src/play.c, src/player.cpp, src/player.h, src/session.c, worlds/haxima-1.001/abandoned-cellar.scm, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/food.scm, worlds/haxima-1.001/gen.scm, worlds/haxima-1.001/ilya.scm, worlds/haxima-1.001/money.scm, worlds/haxima-1.001/moongate.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/objs.scm, worlds/haxima-1.001/spells.scm: + Kernel changes: + o obj_dec_ref now destroys an object at zero counts + o removed kern_obj_destroy + o added kern_obj_inc_ref & kern_obj_dec_ref + o most objects now destroyed by ref counts instead of explicit calls to delete + o fixed 1065888: "refcount targets" + + Haxima changes: + o More work on Enchanter's Tower + o changes on par with kern_* api changes + + * src/Container.cpp, src/place.c: + Kernel changes: + o Fixed [ 1107183 ] get from top of stack + + * src/character.cpp, src/kern.c: + Kernel changes: + o Fixed 1065895 "bow vanishes": NPC characters automatically unready their + weapons when they run out of ammo. But the weapon was not "mirrored" in the + NPC's inventory container. Now it is. + + * worlds/haxima-1.001/door.scm: + Haxima changes: + o Added doors, minor tweaks to Enchanter's Tower + +2005-01-22 Andreas Bauer + + * COPYING, ChangeLog: + Remove nazghul/examples/data/images/.xvpics. + +2005-01-21 Gordon McNutt + + * src/cmd.c: + Kernel changes: + o Added a "fill" command to terrain editing mode + + Haxima changes: + o More work on Enchanter's Tower + + * src/ctrl.c: + Bugfix: \n in cmdwin_print caused crash + + * src/session.c, worlds/haxima-1.001/session.scm: + Kernel changes: + o Fixed 1067142 "Session->camping_proc corrupted" + + Haxima changes: + o Fixed crash when opening the troll corpse in abandoned cellar (it was created + as an object instead of a container) + +2005-01-20 Gordon McNutt + + * src/cmd.c, src/cmd.h, src/ctrl.c, src/terrain.c, src/terrain.h, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/road.scm, worlds/haxima-1.001/sprites.scm: + Kernel changes: + o In terraform mode, holding down CTRL while pressing the arrow keys paints + continuously. + o Also in terraform mode, pressing 'c' (for C)opy) will set the terrain "pen" + to be the terrain type beneath the cursor. + + Haxima changes: + o Second draft of Enchanter's Tower main floor map + +2005-01-19 Gordon McNutt + + * src/player.cpp: + Fix for 1071359: "Camp: setting a watch means certain death". The guard was not + properly waking up companions, and not exiting guard mode, either. In unguarded + ambushes party members do wake up at random as intended so that should be good + as well. + +2005-01-18 Gordon McNutt + + * src/cmd.h, src/ctrl.c, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/items.scm, worlds/haxima-1.001/money.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/shard.scm: + Fix for bug 1074739 "Spelling errors" + + * src/kern.c, worlds/haxima-1.001/haxima.scm: + Fix for bug 1074360 "Crash when using picklocks on + objects". kern_type_get_gifc() was not checking for a NULL gifc before + dereferencing it. + + * src/kern.c, worlds/haxima-1.001/gwen.scm, worlds/haxima-1.001/haxima.scm: + Fix for bug 1074371 "Inn prices lower than advertised". Modified kern_conv_say + to take integer args as well as strings. Room price now single-sourced in a + scheme variable. + + * worlds/haxima-1.001/door.scm: + Fix for bug 1074370 "Occupied doors should stay open". Modified the door-close + proc to check if the tile is occupied. If not, the door remains with a pending + timeout of 1, which will continue to try and close the door on consecutive exec + cycles. + +2005-01-17 Gordon McNutt + + * Attic/Makefile.in, src/cmd.c: + Fix for bug 1074739 "Spelling errors" + +2004-12-11 Andreas Bauer + + * AUTHORS, ChangeLog, Makefile.am, Attic/Makefile.in, NEWS, Attic/RELEASE_NOTES, Attic/acinclude.m4, Attic/aclocal.m4, autogen.sh, Attic/config.guess, Attic/config.sub, Attic/configure, configure.ac, Attic/configure.in, Attic/depcomp, Attic/install-sh, Attic/ltmain.sh, Attic/missing, Attic/mkinstalldirs, m4/ChangeLog, m4/Makefile.am, m4/acinclude.m4, src/Makefile.am, src/Attic/Makefile.in, worlds/Attic/Makefile.in: + Changed build system to GNU-compliant scheme. + +2004-12-04 Gordon McNutt + + * AUTHORS: + file AUTHORS was initially added on branch gmcnutt_scheme. + + * AUTHORS, ChangeLog, Attic/Makefile.in, Attic/aclocal.m4, Attic/configure, Attic/configure.in, src/Attic/Makefile.in, worlds/haxima-1.001/ilya.scm: + This incorporates Andreas Bauer's patch for configure.in. Developers should + probably upgrade their build tools to the latest versions: + + automake -- 1.7.9 + aclocal -- 1.7.9 + autoconf -- 2.59 + + If you have trouble try this: + + aclocal + autoconf + ./configure + + And if you STILL have trouble try automake and repeat. After that I don't know + any more than you do. + + * ChangeLog: + file ChangeLog was initially added on branch gmcnutt_scheme. + +2004-11-21 Gordon McNutt + + * src/character.cpp, src/kern.c, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/lost-halls.scm, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/npc-types.scm, worlds/haxima-1.001/terrains.scm, worlds/haxima-1.001/troll.scm: + Haxima changes: + o Added more monster generators to Lost Halls + o Characters can now climb over boulders but they might slip and fall (with + damage) + + Kernel changes: + o Added kern-obj-get-dir + + * worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/lost-halls.scm, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/npc-types.scm: + Haxima changes: + o Added monster generators for dungeons/towns + o Put a troll generator in the lost halls + +2004-11-20 Gordon McNutt + + * src/cmd.c, src/cmd.h, src/kern.c, worlds/haxima-1.001/chanticleer.scm, worlds/haxima-1.001/door.scm, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/haxima.scm: + Haxima changes: + o Reduced destructiveness of flaming oil + o Filled in some holes in Chanticleer's conversation + + Kernel changes: + o Added kern-conv-get-amount + + * worlds/haxima-1.001/door.scm, worlds/haxima-1.001/roland.scm, worlds/haxima-1.001/slimy-cavern.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/mixed/mine-32x32.png: + Haxima + o Refactored doors to make it easier to add new types. + o Added a windowed door to Roland's cell + o Added a few new keywords to Roland's conversation + o Added images and sprites for a windowed door + +2004-11-19 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/closure.c, src/kern.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/roland.scm: + Haxima changes: + o Roland now greets the player as soon as he can see any player party members + + Kernel changes: + o Added kern-party-get-members + +2004-11-18 Gordon McNutt + + * src/ctrl.c, worlds/haxima-1.001/ai.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/npc-types.scm, worlds/haxima-1.001/roland.scm, worlds/haxima-1.001/troll.scm: + Haxima changes: + o Fixed bandit taunts to run only once per bandit + o Added (lame) troll taunts + o Roland now offers to join more prominently + + Kernel changes: + o Moved mode-change commands above the check for action points (if the party + leader is paralyzed the player can exit Follow mode so the other party + members don't stand around like drooling idiots while they get whaled on) + +2004-11-16 Gordon McNutt + + * src/Party.cpp, src/character.cpp, src/character.h, src/kern.c, src/play.c, worlds/haxima-1.001/effects.scm: + More stuff to get NPC creation all in one sock. + + Haxima changes: + o Changed slime-split effect to use mk-green-slime instead of kern-obj-clone + and removed call to obsolete slime-init + + Kernel changes: + o Removed kern-init-stock-char from the API, only kern-mk-char should be used + from now on. + o Removed Character::initItems() + o Updated Character::initStock() in light of other changes + + * src/kern.c, src/occ.c, src/occ.h, worlds/haxima-1.001/af-entry.scm, worlds/haxima-1.001/npc-types.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/troll.scm: + More stuff to get NPC creation all in one sock. + + Haxima changes: + o Bugfix: trolls didn't have their ai set and couldn't pick up rocks because + they had no container + o Updated all calls to kern-mk-occ to reflect changes in the occ struct. + + Kernel changes: + o Removed the container and item stuff from the occupation data structure; + character inventories are always initialized now via their script + constructors. + o Update kern-mk-occ to remove the obsolete arguments + +2004-11-14 Gordon McNutt + + * Attic/RELEASE_NOTES, src/Container.cpp, src/Party.cpp, src/Party.h, src/character.cpp, src/closure.c, src/kern.c, src/scheme.c, src/scheme.h, worlds/haxima-1.001/abandoned-cellar.scm, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/containers.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/gregors-hut-zones.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/ilya.scm, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/npc-types.scm, worlds/haxima-1.001/objs.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/parties.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spells.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm: + More refactoring for npc type cleanup. + + Haxima changes: + o Modify kern_mk_party_type: remove the occupation and ai and replace them with + a npc type factory closure + o Fixup all script references to kern-mk-party-type + o Convert all uses of kern-mk-stock-char to kern-mk-char (add npc type + factories) + + Kernel changes: + o Modify GroupInfo for PartyType: remove occ and ai and replace them with an + npc factory closure + o Modify PartyType::addGroup to reflect these changes + o Modify PartyType::~PartyType to reflect these changes + o Modify Party::createMembers to use the closure instead of calling + o Character::initStock() + o Modify closure_exec to return a foreign func as a void * + +2004-11-08 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/kern.c, src/scheme.c, src/session.c: + Step 1 1/2 of refactoring for new npc type factories + +2004-11-06 Gordon McNutt + + * doc/engine_extension_and_design/ENGINE_CLEANUP, doc/engine_extension_and_design/ENGINE_DESIGN_NOTES, src/Container.cpp, src/Party.cpp, src/character.cpp, src/closure.c, src/closure.h, src/kern.c, src/occ.c, src/occ.h, src/place.c, src/session.c, worlds/haxima-1.001/haxima.scm: + Fixed one nasty crash on reload; more still lurking + +2004-11-02 Gordon McNutt + + * doc/engine_extension_and_design/ENGINE_CLEANUP, doc/engine_extension_and_design/ENGINE_DESIGN_NOTES: + New doc files + +2004-11-01 Gordon McNutt + + * src/combat.c, src/common.c, src/common.h, src/player.cpp, src/player.h, src/session.c, src/sound.c, src/sprite.c, src/sprite.h: + Removed some obsolete code; added call to SDL_CloseAudio on exit (when sound is used) + + * src/object.c: + Bugfix: uninitialized string in ObjectType class caused intermittent crash on reload + +2004-10-28 Sam Glasby + + * worlds/haxima-1.001/images/dgervais/dg_weapons.trans.png: + Fixed the eldritch blade (left of the flaming sword). + The second animation frame was offset 1 pixel to the right. + +2004-10-25 Gordon McNutt + + * BUGS, Attic/RELEASE_NOTES, Attic/configure.in, doc/USERS_GUIDE, src/character.cpp, src/nazghul.c, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/earl.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/roland.scm, worlds/haxima-1.001/scrolls.scm, worlds/haxima-1.001/slimy-cavern.scm, worlds/haxima-1.001/spells.scm: + Haxima changes: + o Roland now does a pathfinding test when asked to join + o Roland now (again) states his fealty to Lord Froederick when asked to join + o Added a resurrection scroll; put one in starter chest; can by more in trigrave + o Change Roland's level to 3 + o Added equipment for Roland + o Reduced count of flaming oil for bandits + o Reduced range of xbow + o Roland mentions that he will JOIN + + Kernel changes: + o Special message now printed when a party member dies + + * Attic/Makefile.in, Attic/configure, scripts/RELEASE_CHECKOFF, worlds/haxima-1.001/haxima.scm: + Final checkin before release + +2004-10-24 Gordon McNutt + + * src/kern.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/roland.scm: + Haxima changes: + o Roland now does a pathfinding test when asked to join + o Roland now (again) states his fealty to Lord Froederick when asked to join + + * worlds/haxima-1.001/ai.scm, worlds/haxima-1.001/items.scm, worlds/haxima-1.001/scrolls.scm: + Adding a missed file + + * worlds/haxima-1.001/combat-maps.scm, worlds/haxima-1.001/palette.scm, worlds/haxima-1.001/shard.scm, worlds/haxima-1.001/terrains.scm, worlds/haxima-1.001/images/mixed/mine-32x32.png: + Haxima changes: + o Added combat maps for east-west bridges and roads + + * worlds/haxima-1.001/items.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + *** empty log message *** + +2004-10-23 Gordon McNutt + + * src/character.cpp, src/character.cpp, src/character.h, src/kern.c, src/object.c, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/roland.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/trigrave.scm: + Kernel changes: + o Bugfix: crash on reload due to double-deallocation of convs + + * src/cmd.c, src/cmd.h, src/ctrl.c, src/play.c, worlds/haxima-1.001/haxima.scm: + Haxima changes: + o Added a hint about the shrine cave in the startup script. + + Kernel changes: + o Added a "help" command bound to '?' + + * worlds/haxima-1.001/camping-map.scm, worlds/haxima-1.001/haxima.scm: + Haxima changes: + o Saved games now have wilderness ambushes + + * worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/naz.scm: + Haxima changes: + o Removed the "L" from status for light effects + + * worlds/haxima-1.001/game.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/parties.scm, worlds/haxima-1.001/roland.scm, worlds/haxima-1.001/species.scm: + Haxima changes: + o Switched the bandits to use the generic script ai + o Added taunts to the generic ai + +2004-10-22 Gordon McNutt + + * src/Party.cpp, src/player.cpp: + Kernel changes: + o Fixed some bugs that appeared when an NPC joined the player party + + * src/closure.c, worlds/haxima-1.001/camping-map.scm, worlds/haxima-1.001/earl.scm, worlds/haxima-1.001/gwen.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/objs.scm, worlds/haxima-1.001/occs.scm: + Haxima changes: + o Adde reagents and potions to the Trigrave Dry Goods store + o Added a chance of getting healing potions from bandits + + Kernel changes: + o Bugfix: broke entry to trigrave with recent changes + +2004-10-21 Gordon McNutt + + * src/Being.cpp, src/Being.h, src/Container.cpp, src/Field.cpp, src/Party.cpp, src/character.cpp, src/character.h, src/closure.c, src/closure.h, src/ctrl.c, src/effect.c, src/kern.c, src/object.c, src/place.c, src/session.c, src/session.h, src/sky.c, src/terrain.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/kobj.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/roland.scm, worlds/haxima-1.001/slimy-cavern-zones.scm, worlds/haxima-1.001/slimy-cavern.scm: + Haxima changes: + o Modified pathfind to use the new kern-being-pathfind-to + o Added an ai for roland which will have him try to escape; once escaped it + reverts to the default kernel ai + + Kernel changes: + o Moved Character::pathfindTo up to Being::pathfindTo + o Added kern-being-pathfind-to + o Added kern-char-set-ai + o Changed all closure_del() to closure_unref(); closures must be destoryed via + ref counts (otherwise setting the closure to null from within the closure + might cause scheme to gc it before we can extract the return value in + closure_exec) + + * src/kern.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/roland.scm: + Haxima changes: + o Roland will join the player once freed + + Kernel changes: + o Added kern-char-join-player (still has some bugs) + + * worlds/haxima-1.001/roland.scm, worlds/haxima-1.001/slimy-cavern.scm: + Haxima changes: + o Started on Roland, a prisoner in the slime cave. + +2004-10-20 Gordon McNutt + + * src/Party.cpp, src/character.cpp, src/character.h, src/combat.c, src/combat.h, src/kern.c, src/play.c, src/player.cpp, src/session.c, src/session.h, worlds/haxima-1.001/af-entry.scm, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/camping-map.scm, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spells.scm, worlds/haxima-1.001/spider.scm: + Haxima changes: + o Added the camping map + o Added a camping hook to generate ambushes while the player is camping in the + wilderness + + Kernel changes: + o Added kern-ambush-while-camping + o Changed kern-obj-is-char? to kern-obj-is-being? + o Changed kern-char-is-hostile? to kern-being-is-hostile? + o Added a camping_proc hook to the session + o Modified the main loop to invoke the session's camping_proc every turn when + the player is camping + + * src/character.cpp, src/character.h, src/common.h, src/kern.c, src/player.cpp, src/status.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/scrolls.scm, worlds/haxima-1.001/session.scm: + Haxima changes: + o Parameters to kern-mk-player changed (due to removal of rest credits) + o Doubled the light per torch + + Kernel changes: + o Ripped out rest credits + + * worlds/haxima-1.001/earl.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/lost-halls.scm, worlds/haxima-1.001/portals.scm, worlds/haxima-1.001/shard.scm: + Haxima changes: + o Added lost-halls.scm, a port of Sam's ork cave from the old ghulscript + o Added a mine entrance as an auto-portal + +2004-10-19 Gordon McNutt + + * src/character.cpp, src/character.h, src/cmd.c, src/common.h, src/ctrl.c, src/kern.c, src/occ.h, src/species.h, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm: + These changes polish up the experience/advancement system a bit. + + Haxima changes: + o Set experience levels for all existing species and occs + + Kernel changes: + o Got rid of wasElevated and setElevated methods in Character class + o Added getExperienceValue method to Character class + o Added xpval fields to species and occ structs + o Removed addExperience in cmdOpen for traps + o Removed addExperience for attacks + o Added addExperience for kills + o Got rid of hard-coded XP values in common.h + o Added a console message when any Character gains a level + o Added a mapFlash when a player-controlled Character gains a level + +2004-10-18 Gordon McNutt + + * src/kern.c, src/object.c, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/jim.scm, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/parties.scm, worlds/haxima-1.001/shard.scm: + Haxima changes: + o Added a bandit generator by the river + o Monster and ambush generators invisible + o Added a bandit occupation + o Added a bandit gang npc party type + + Kernel changes: + o kern-obj-set-visible now returns the object + o NPC parties were not wandering; fixed them + + * src/place.c, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/shard.scm, worlds/haxima-1.001/slimy-cavern.scm, worlds/haxima-1.001/species.scm: + Haxima changes: + o Tweaked the moongate clearing map to make the northeast cave more obvious + o Added a bandit party waiting just outside the shrine + o Added some bandits to the back of the slimy cave + o Commented-out the "advanced items" chests + o Added a sling type and put one in the starter chest + o Gave the slime's acid spray a sprite + o Removed one slime generator from the Slimy Cave and moved the other; also + gave it a target location other than its own where slimes appear from + o Added a faction for outlaws (so they will fight with monsters) + o Rebalanced slime damage + o Reduced default movement speed to 1 to prevent NPCs from jumping around + erratically in town + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/earl.scm, worlds/haxima-1.001/trigrave-zones.scm, worlds/haxima-1.001/trigrave.scm: + Haxima changes: + o Added Earl, proprieter of the Trigrave general store + + * worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/trigrave.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + Changed Chanticleer's sprite + +2004-10-17 Gordon McNutt + + * src/ctrl.c, src/kern.c, worlds/haxima-1.001/monster-generator.scm: + Haxima changes: + o Made an ambush generator constructor + o Changed spider generators from party generators to ambush generators + + Kernel changes: + o Added kern-begin-combat to support ambushes + + * src/kern.c, src/scheme.c, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/shard.scm: + Haxima changes: + o The ambush generators now monitor a region of the map + + Kernel changes: + o Added kern-get-player to return a reference to the player party + o kern-begin-combat now uses the correct orientation for ambushes + + * src/kern.c, worlds/haxima-1.001/combat-maps.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/terrains.scm: + Haxima changes: + o Ported over the old ghulscript combat maps for grass, forest and hills + + Kernel changes: + o Added kern-terrain-set-combat-map + + * src/sched.c, src/sched.h, worlds/haxima-1.001/chanticleer.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/gwen.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/ifc.scm, worlds/haxima-1.001/shard.scm, worlds/haxima-1.001/trigrave-zones.scm, worlds/haxima-1.001/trigrave.scm: + Haxima changes: + o Expanded Chanticleer's conversation and added him to trigrave + o Renamed the inn and tweaked some torch placement + o Added more beds + + Kernel changes: + o Added an activity for "drunk" (yes, I need to get these activities out of the + kernel...) + + * worlds/haxima-1.001/shard.scm: + Haxima changes: + o Added roads (as terrains, not features) to the shard surface. + +2004-10-16 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/abandoned-cellar.scm, worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/bakup.scm, worlds/haxima-1.001/camping-map.scm, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/palette.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/slimy-cavern.scm, worlds/haxima-1.001/terrains.scm, worlds/haxima-1.001/trigrave.scm, worlds/haxima-1.001/vehicles.scm: + Palette cleanup. + Changing pal_expanded to have all glyphs be 2 characters wide. + Added non-LOS-blocking versions of various terrains. + +2004-10-16 Gordon McNutt + + * src/astar.c, src/astar.h, src/character.cpp, src/character.h, src/kern.c, src/player.cpp, worlds/haxima-1.001/door.scm, worlds/haxima-1.001/gwen.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/ifc.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/trigrave-entry.scm, worlds/haxima-1.001/trigrave.scm: + o Bugfix: hard to get large parties through doors. Fixed this with two fairly + significant changes to character pathfinding. One change is that characters + now cache their paths so they can reuse them on subsequent turns if their + target destination has not changed. The second change is that by default they + pathfind through mechanisms. If they come to an impassable tile they check + for a mechanism and if it can be handled. If so, they handle it. This takes + care of doors. If the tile is still impassable they find a new path around + it. + + * src/character.cpp, src/character.h, src/kern.c, src/object.c, src/object.h, src/player.cpp, src/player.h, worlds/haxima-1.001/beds.scm, worlds/haxima-1.001/food.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/gwen.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/money.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/trigrave.scm: + Haxima changes: + o Added an object type for gold coins + o Fixed a bug in getting food (it was ignoring the object count) + o Gave the player some starting gold in the supplies chest + o Changed the innkeeper so that when she is eating she won't engage in business + + Engine changes: + o Added an addGold method analogous to the existing addFood methods + + * src/kern.c, src/play.c, src/player.cpp, src/session.c, src/session.h: + Engine changes: + o Time runs faster when sleeping and camping + + * worlds/haxima-1.001/spells.scm: + Haxima changes: + o Torches weren't getting removed from inventory when they were used. + +2004-10-15 Gordon McNutt + + * src/cmd.c: + o Bugfix: opening corpses on doors. Fixed this by adding a selection dialog to + cmdGet. Used whenever a container and a mech are found on the same + tile. We'll probably want to extend it to handle an arbitrary number of + targets but for now its fixed at just the two. + + * worlds/haxima-1.001/chanticleer.scm: + Start of a new character + + * worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm: + Eliminated the spider corpses + + * worlds/haxima-1.001/troll.scm: + Bugfix: accidentally checked in a partial change + +2004-10-14 Gordon McNutt + + * worlds/haxima-1.001/gwen.scm, worlds/haxima-1.001/trigrave-zones.scm, worlds/haxima-1.001/trigrave.scm: + Put the innkeeper into trigrave + + * worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/trigrave.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + Added a new sprite: gray-robed humanoid (for Gwen the Innkeeper of Trigrave) + +2004-10-13 Gordon McNutt + + * doc/USERS_GUIDE, src/kern.c, worlds/haxima-1.001/spells.scm: + Bugfix: webs getting dropped on impassable terrain + + * src/combat.c, src/kern.c, src/place.c, src/scheme.c, src/terrain_map.c, src/terrain_map.h: + Bugfix: ship maps getting saved multiple times + + * src/scheme-private.h: + Increased memory for scheme allocator (running out when reloading in session.scm) + + * worlds/haxima-1.001/camping-map.scm, worlds/haxima-1.001/session.scm: + Bugfix: broke save/reload in session.scm with my last map-saving fix; this fixes it + + * worlds/haxima-1.001/gwen.scm: + Minor change to conv + + * worlds/haxima-1.001/gwen.scm: + New character started + +2004-10-12 Gordon McNutt + + * README: + Changed the reference to INSTALL and USERS_GUIDE to the top where people can find it easier + + * worlds/haxima-1.001/jim.scm, worlds/haxima-1.001/Attic/john_iron.scm, worlds/haxima-1.001/trigrave-zones.scm, worlds/haxima-1.001/trigrave.scm: + Changed the blacksmith in trigrave + +2004-10-11 Gordon McNutt + + * src/Container.cpp: + Bugfix: save/reload gives extra weapons. Readied items were being saved twice. + + * worlds/haxima-1.001/Attic/john_iron.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/trigrave-zones.scm, worlds/haxima-1.001/trigrave.scm: + Added a blacksmith to trigrave + + * worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/parties.scm, worlds/haxima-1.001/shard.scm: + Added some basic random encounter generators to the wilderness + +2004-10-10 Gordon McNutt + + * BUGS, INSTALL, Attic/Makefile.in, README, Attic/RELEASE_NOTES, Attic/configure, Attic/configure.in, doc/USERS_GUIDE, scripts/RELEASE_CHECKOFF, src/kern.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/shard.scm, worlds/haxima-1.001/trigrave.scm: + Added (unpopulated) town: Trigrave + + * src/Attic/Makefile.in, src/nazghul.c, src/player.cpp: + Bugfix: segfault when saving games started with the --sound 0 option + + * src/scheme.c: + Patch from Tim Douglas to fix compile error on Max OS X v10.3.5 + +2004-10-09 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/moongate-clearing.scm: + Added many new arms and armor types, and added instances into the game. + + * worlds/haxima-1.001/P_terrain_test.scm: + Removed _map (a test/example of some kind). + + * worlds/haxima-1.001/moongate-clearing.scm: + Fixed up some width/alignment issues due to width-1 boulder glyphs within the map. + + * worlds/haxima-1.001/objs.scm: + Added some new chest types. + + * worlds/haxima-1.001/reagents.scm: + Fixed their order. Commented out a 'bloodmoss' type which seemed to be a duplicate. + +2004-10-09 Gordon McNutt + + * src/Arms.cpp, src/Arms.h, src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/combat.c, src/event.c, src/kern.c, src/nazghul.c, src/object.c, src/object.h, src/player.cpp, src/player.h, src/sound.c, src/sound.h, src/species.c, src/species.h, src/vehicle.cpp, src/vehicle.h, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/sounds.scm: + o Sounds are now loaded as kernel objects. This change is intended to eliminate + the lag when playing sounds under windows. + +2004-10-07 Gordon McNutt + + * Attic/Makefile.in, src/Attic/Makefile.in: + Fixing a borken Makefile.in (hopefully) + + * Attic/depcomp, src/Makefile.am, src/Attic/Makefile.in, src/nazghul.c, src/play.c, src/tick.c, src/tick.h: + o Bugfix: tick generation is paused while loading/reloading. In the process of + fixing this I tore the existing tick code out of nazghul.c and put it in its + own tick.c. Added routines to pause and resume tick generation. + + * src/cmd.c, src/cmd.h: + Fixed the CTRL- keys used by the T)erraform command to use UNICODE so it will work on non-US keyboards + + * src/cmd.c, src/cmd.h, src/ctrl.c, src/event.h: + Karl Garrison's patch to dump terrain sprites as one BMP per frame + + * worlds/haxima-1.001/sounds/cannon.wav, worlds/haxima-1.001/sounds/damage.wav, worlds/haxima-1.001/sounds/enter_moongate.wav, worlds/haxima-1.001/sounds/horse.wav, worlds/haxima-1.001/sounds/rowing.wav, worlds/haxima-1.001/sounds/walk.wav: + New sound files from Sam + +2004-10-06 Gordon McNutt + + * src/character.cpp, src/character.h, src/cmd.c, src/player.cpp: + o Bugfix: N)ew Order when the leader is one member and a dead or incapacitated + member is the other would effectively hang the system when in follow + mode. With this change incapacitated members cannot be selected as the party + leader. + + * src/cmd.c: + Fixed: opening a chest describes everything on the tile, not just the contents + + * src/ctrl.c: + o UI change. If the player has just one party member and he uses the A)ttack + command the party will not switch out of follow mode. This way the camera + remains centered on the character. + + * src/gob.c, src/object.c, src/scheme.c: + Fixed a memory leak. Wasn't freeing the hook entries on the hook lists maintained by objects. + + * src/map.c, src/nazghul.c: + Bugfix: on some redhat systems we would crash on exit (even without sound enabled) + + * src/sound.c: + Corrected the copyright notice at the top of this file + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/haxima.scm: + Rebalanced slimes + + * worlds/haxima-1.001/terrains.scm: + Made bogs exude poisonous fumes again + +2004-10-05 Gordon McNutt + + * src/event.c: + Removed #ifdefs for UNICODE + + * src/event.c: + Bugfix: UNICODE changes broke Page Up/Down, now fixed for US keyboards (unsure about others) + + * src/nazghul.c, src/Attic/splash.png: + Added splash screen on startup + + * src/Attic/splash.png: + Removed extra copy of splash image file + + * src/terrain_map.c: + o Bugfix: saving/reloading on win32. The problem was in terrain_map_save, where + the tiles were being saved as printf("%02s", tag). On windows it printed the + leading zero, on linux not. Removed the zero and all is well. Not sure why I + had a zero there to begin with. + + * worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate.scm: + o Fixed the long delays in the opening cut scene. These were not unique to + win32. During the port I had to change usleep to SDL_Delay, which takes a + longer unit of time as an argument. + + * worlds/haxima-1.001/images/gmcnutt/splash.png: + Adding splash image. + +2004-10-04 Gordon McNutt + + * src/ctrl.c, src/event.c, src/event.h: + o Converted to UNICODE for keypresses. + + * src/ctrl.c, src/object.c, src/player.cpp, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/slimy-cavern.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spells.scm: + Added slime to the Slimy Cavern + + * worlds/haxima-1.001/effects.scm: + Bugfix: when paralysis wore off it allowed the player to attack while ensnared + + * worlds/haxima-1.001/slimy-cavern.scm: + Fixed load error in slimy-cave.scm due to a missing (unnecessary) file + +2004-10-03 Gordon McNutt + + * Attic/RELEASE_NOTES, Attic/configure, Attic/configure.in, Attic/depcomp, scripts/RELEASE_CHECKOFF, src/Party.cpp, src/character.cpp, src/cmd.c, src/common.c, src/ctrl.c, src/images.c, src/kern.c, src/map.c, src/nazghul.c, src/scheme.c, src/scheme.h, src/screen.c, src/session.c, src/wind.c: + Changes needed to compile and run under win32 + + * Attic/depcomp: + file depcomp was initially added on branch gmcnutt_scheme. + + * worlds/haxima-1.001/abandoned-cellar.scm, worlds/haxima-1.001/bridge.scm, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/ilya.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/portals.scm, worlds/haxima-1.001/scrolls.scm, worlds/haxima-1.001/slimy-cavern.scm: + o Added a cave entrance to moongate-clearing + o Added torches to the warchest + o Added a troll and troll corpse to abandoned-cellar + +2004-10-02 Gordon McNutt + + * BUGS, COPYING, INSTALL, Attic/RELEASE_NOTES, Attic/configure, Attic/configure.in, doc/USERS_GUIDE, scripts/RELEASE_CHECKOFF, src/ctrl.c, src/nazghul.c, src/place.c, src/play.c, worlds/haxima-1.001/haxima.scm: + Last-minute tweaks for release + + * worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/ilya.scm, worlds/haxima-1.001/pre-entry-hooks.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm: + o Bugfix: Entering green tower from session.scm was crashing due to an + out-of-date entry procedure. + o Bugfix: could not complete puska quest due to invalid scheme proc in ilya's + code + +2004-10-01 Gordon McNutt + + * src/status.c: + o UI change: added a "Misc" pane to the inventory UI. Objects which don't fall + into any of the other categories (readyable, usable, mixable or castable) are + displayed here. + + * worlds/haxima-1.001/abandoned-cellar.scm, worlds/haxima-1.001/ilya.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + o Finished implementing the puska quest + +2004-09-30 Gordon McNutt + + * scripts/RELEASE_CHECKOFF, src/cmd.c, src/kern.c, src/place.c, src/play.c, src/player.cpp, src/scheme.c, src/session.h: + o Bugfix: LOS on reload was messed up. On reload, the current place was locked + so it did not get cleaned up => any objects in the place did not get cleaned + up => player characters did not get destroyed => they did not remove their + map views => in the new session, the old map views were still hanging around, + contributing to player LOS. + + * src/character.cpp, src/place.c, src/scheme.c: + o Added an assert to ensure that the kernel has released all of its references + to scheme cells when we tear down the scheme session. This assert currently + fires on reload. That's because we tear down the scheme session before we + tear down the player's current place, and there are bound to be objects in + that place that still reference gobs. I'm checking this in so I can continue + to debug it on another machine. + +2004-09-29 Gordon McNutt + + * src/kern.c, src/scheme.c, src/scheme.h, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm: + o Added gc protection to various places in kern.c where it's necessary to + allocate more than one cell before returning to scheme. This fixes the + annoying "*** script error ***" messages that appeared intermittently. + +2004-09-28 Gordon McNutt + + * worlds/haxima-1.001/abandoned-cellar.scm: + New place file + +2004-09-27 Gordon McNutt + + * Attic/Makefile.in, Attic/aclocal.m4, Attic/configure, src/Being.h, src/Party.h, src/cmd.c, src/kern.c, src/object.c, src/place.c, src/play.c, src/vmask.c, src/vmask.h, worlds/Attic/Makefile.in, worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/spider.scm: + o Bugfix: 'evade' now checks terrain for passability before trying to move + there. This prevents spiders from killing themselves on wall torches. + + o Performance: spider eggs now use kern-fold-rect when searching for + disturbances. + + o Bugfix: the vmask cache was not keeping count of its entries. + + o Added vmask_flush_all() + + o Bugfix: some destructors were not declared virtual as they should have been. + +2004-09-26 Gordon McNutt + + * src/kern.c, src/scheme.c, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/troll.scm: + Various experiments with improving AI performance + +2004-09-25 Gordon McNutt + + * src/Being.cpp, src/Being.h, src/Party.cpp, src/character.cpp, src/combat.c, src/node.c, src/node.h, src/object.c, src/object.h, src/place.c, src/player.cpp: + o Converted the Party class's member list field from an embedded list to a + wrapper list; likewise for the hook in the Character class + + * src/character.cpp, src/kern.c, src/map.c, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/spells.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm, worlds/haxima-1.001/yellow-slime.scm: + o Fixed a couple of places where a callback function was not initialized + properly. This is a bug introduced *after* 0.3.0. + + o Various fixes to get session.scm working again. + + * src/ctrl.c, src/event.c, src/kern.c, src/map.c, src/place.c: + Added kern_place_get_beings, a kernel filter for kern_place_get_objects, which speeds up the ai's noticeably + + * src/kern.c, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm: + Improving performance. Added kern-being-get-visible-hostiles, which is a kernel + implementation of the all-visible-hostiles scheme procedure. The scheme version + ran in about 27 ms on my machine, the kernel version takes less than 1 + ms. Virtually every AI uses this procedure on every turn. + +2004-09-24 Gordon McNutt + + * src/event.c: + Numeric keypad now returns numbers when NUMLOCK enabled + +2004-09-23 Gordon McNutt + + * Makefile.am, Attic/Makefile.in: + Bugfix: removed examples as a source directory for make + + * src/Field.cpp, src/Field.h, src/Makefile.am, src/Attic/Makefile.in, src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/combat.c, src/ctrl.c, src/node.c, src/node.h, src/object.c, src/object.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/player.h: + Replaced embedded turn_list with wrapper node list + + * src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/node.h, src/player.cpp: + o Converted the Party class's member list field from an embedded list to a + wrapper list; likewise for the hook in the Character class + + * src/character.cpp, src/character.h: + Removed an obsolete list field from the Character class + + * src/combat.c, src/ctrl.c, src/node.c, src/object.c, src/object.h, src/place.c, src/place.h: + o Fixed a few bugs in the new turn_list code and enabled it. + + * src/place.c, src/place.h: + Removed some obsolete lists from the place structure + + * worlds/haxima-1.001/spider.scm: + Turned off debug spew from spider.scm + +2004-09-22 Gordon McNutt + + * src/combat.c, src/ctrl.c, src/node.c, src/node.h, src/place.c, src/place.h: + More invisible changes to fix the offset warnings + + * src/combat.c: + Added yet more unused functions to combat (preparing to fix the list warnings) + + * src/ctrl.c, src/event.c: + o Bugfix: NUMLOCK prevents ctrl key from working properly. This was due to use + of an '==' operator where an '&' operator belonged. + + o Added debug output to help debug problems with other people's keyboards. + +2004-09-21 Gordon McNutt + + * src/combat.c: + Added new (unused) function + + * src/list.h: + Removed some dead code + + * src/object.c, src/object.h: + Removed the obsolete list field from the ObjectType class + +2004-09-20 Gordon McNutt + + * worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/spider.scm: + o Trolls now pick up boulder ammo dropped on the ground. + o Fixed a script error causing an invalid location. + + * worlds/haxima-1.001/ilya.scm: + Fixed some minor bugs in Ilya's conversation. + +2004-09-19 Gordon McNutt + + * Attic/RELEASE_NOTES, scripts/RELEASE_CHECKOFF, src/character.cpp, src/kern.c, src/object.h, src/species.c, src/species.h, worlds/haxima-1.001/reagents.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/troll.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + o Added a field to species: on_death which is a script closure that expects the + character as a parm + o Fixued up kern_mk_species to expect the other parm. + o character::kill() calls the species on_death closure _before_ removing the + object (so the on-death proc can get the final coordinates of the character) + o Modified all the kern-mk-species calls to specify nil (by default) for their + death closure + o Createed an on-death proc for spiders which creates a corpse container and + puts a random amount of spider silk in it + o Modified the spider kern-mk-species call to specify the on-death proc + o Changed the sprites for the spider corpse and the spider silk reagent. + + * src/kern.c, src/vmask.c, worlds/haxima-1.001/spells.scm: + o Bugfix: kern_in_los was computing the y-component of the vmask coordinates + incorrectly due to a typo. + + * worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + o Queen spider animation fixed up a bit + o Added a queen spider corpse + +2004-09-18 Gordon McNutt + + * BUGS, INSTALL, Makefile.am, Attic/Makefile.in, Attic/RELEASE_NOTES, Attic/configure, Attic/configure.in, scripts/RELEASE_CHECKOFF, scripts/ghul-test-install, src/Makefile.am, src/Attic/Makefile.in, src/kern.c, src/nazghul.c, src/object.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + Pre-release tweaks and changes + + * worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + Added a queen spider + + * worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/naz.scm: + Paralysis prevents struggling against ensnare + +2004-09-16 Gordon McNutt + + * src/character.cpp, src/object.c, worlds/haxima-1.001/loc.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/spells.scm, worlds/haxima-1.001/spider.scm: + o Spiders now use a vampiric melee attack which drains hp from their targets + and heals them of damage. + o Added a web-spew skill for spiders. They can shoot webs similar to a wind + spell for a limited range. With these two changes spiders are almost an even + match for trolls. + o Bugfix: effects added to the keystroke-hook were not being removed properly + for NPC's. + + * worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spider.scm: + Added a paralysis skill for spiders. Interaction with ensnare not optimal yet. + +2004-09-15 Gordon McNutt + + * src/dtable.c, src/kern.c: + dtable defaults now set in dtable_new(), not kern_mk_dtable() + + * src/effect.h, src/kern.c, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/loc.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm: + o Added kern-obj-get-effects + o Spiders now attack foes that are disabled (sleeping or ensnared) + + * worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/troll.scm: + Webs break when somebody struggles free + +2004-09-13 Gordon McNutt + + * src/character.cpp, src/kern.c, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/scrolls.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spells.scm: + o Spiders now immune to the ensnare effect (caused by webs) + o Using scrolls no longer consumes the scroll if the usage method + returns nil (so a user can ESC out of some usages) + + * src/ctrl.c, src/kern.c, src/object.c, src/object.h, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/scrolls.scm, worlds/haxima-1.001/spider.scm: + o Added kern-obj-get-name + o Added a new hook that runs while processing a user keystroke in character + mode. + o Modified the web ensnare effect to use the keystroke hook. Now when a user + character is ensnared it works like Adom: the user has to keep hitting a key + to "struggle" against the web until he finally breaks free. + + * src/kern.c, src/object.c, src/object.h, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/fields.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/reagents.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/troll.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + Added spider webs + +2004-09-12 Gordon McNutt + + * src/Arms.cpp, src/Arms.h, src/Missile.cpp, src/kern.c, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/session.scm: + Kernel arms types no longer refer to field types. Cases where arms create fields are now all handled in the script. + + * src/Missile.cpp, src/kern.c, src/object.c, src/object.h, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/items.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/scrolls.scm: + Changed missile interface + + * src/ctrl.c: + Added base 1d20 for to-hit on all attacks (as per new combat system rules) + + * src/map.c: + Bugfix: missiles with off-screen targets were animating wrong + + * worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/loc.scm, worlds/haxima-1.001/shard.scm, worlds/haxima-1.001/troll.scm: + Bugfix for troll picking up boulder + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + Added a sprite to distinguish between loose boulders (objects) and terrain boulders + + * worlds/haxima-1.001/arms.scm: + Thrown boulders now convert back to boulder terrain when they hit + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/ifc.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/scrolls.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spells.scm, worlds/haxima-1.001/troll.scm, worlds/haxima-1.001/images/dgervais/dg_readable-32x32.png: + Added our first usable spell scroll and put a few in the startup warchest + + * worlds/haxima-1.001/ifc.scm, worlds/haxima-1.001/scrolls.scm: + Cleanup of scroll code. Trivial now to add spell scrolls. + + * worlds/haxima-1.001/troll.scm: + Trolls pay 2 turns worth of action points for ripping up boulders + +2004-09-11 Gordon McNutt + + * src/character.cpp, src/kern.c, worlds/haxima-1.001/loc.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/troll.scm: + o More refactoring around the troll AI. + + * worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/af-entry.scm, worlds/haxima-1.001/shard.scm: + Moved the abandoned farm + + * worlds/haxima-1.001/af-entry.scm, worlds/haxima-1.001/naz.scm: + Changed spider spawn points in the abandoned farm + +2004-09-10 Gordon McNutt + + * src/character.cpp, src/kern.c, src/place.c, src/place.h: + o Fixed a bug related to NPC characters exiting the map via a kern-obj-move + call. + + * worlds/haxima-1.001/loc.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/troll.scm: + o Trolls now pick up boulder ammo dropped on the ground. + o Fixed a script error causing an invalid location. + +2004-09-09 Sam Glasby + + * src/cmd.c, src/event.h: + Working on polish and new features for the Terraform UI. + + * src/terrain.c: + Fixed palette_print() and palette_entry_print() to emit Scheme. + Also keeping track of palette->widest_glyph again. + + * src/terrain.h: + Minor cleanup (removed some junk). + + * src/terrain_map.c: + Changed terrain_map_print() to emit Scheme maps. + + * src/terrain_map.c: + Fixed an ASCII diagram which got screwed up + by an automatic code indenter or similar. + + * worlds/haxima-1.001/palette.scm: + Re-generated palette with palette_print(). + Works great, with added comments. + +2004-09-08 Gordon McNutt + + * src/Container.cpp, src/Container.h, src/character.cpp, src/character.h, src/kern.c, src/player.cpp: + Characters now save/load their personal containers + + * worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/gregor.scm, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/loc.scm, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/shard.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm: + Trolls cannot evade diagonally now + + * worlds/haxima-1.001/troll.scm: + Started a refactor of troll ammo-hunting alg to accomodate loose boulder objects lying on the ground (their fellow trolls usually drop a few when they die + +2004-09-07 Gordon McNutt + + * src/Container.cpp, src/character.cpp, src/character.h, src/kern.c, worlds/haxima-1.001/loc.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/troll.scm: + o Created a specialized AI for trolls. This one prefers to fight at range and + will pick up nearby boulders and use them as ammo. It will also flee (using + the braindead legacy flee code in the kernel). + +2004-09-04 Gordon McNutt + + * src/character.cpp, src/character.h, src/kern.c, src/object.c, src/object.h, src/player.cpp, src/player.h, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/troll.scm: + o Translated the original C combat AI into Scheme. Tested it with trolls. This + is supposed to offer a reasonable starting point for making custom combat + AI's in scheme. + +2004-09-02 Sam Glasby + + * doc/world_building/advancement.rogue.txt, doc/world_building/advancement.warrior.txt, doc/world_building/advancement.wizard.txt, doc/world_building/advancement.wright.txt, doc/world_building/being_tile_media.txt, doc/world_building/music_loop_media.txt, doc/world_building/sound_sample_media.txt, doc/world_building/town_scale_tile_media.txt, doc/world_building/wilderness_scale_tile_media.txt: + Transcribing various notes. + +2004-09-02 Gordon McNutt + + * src/ctrl.c, src/location.h, src/player.cpp, src/Attic/tile.c, src/Attic/tile.h, worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/af-entry.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spider.scm, worlds/haxima-1.001/troll.scm: + o Added a spider "class" in scheme + o Added a monster generator in the Abandoned Farm to keep it populated with + warring trolls and spiders + +2004-09-01 Sam Glasby + + * doc/world_building/being_tile_media.txt, doc/world_building/being_tile_media.txt, doc/world_building/music_loop_media.txt, doc/world_building/sound_sample_media.txt, doc/world_building/town_scale_tile_media.txt, doc/world_building/wilderness_scale_tile_media.txt: + Added some files. + + * worlds/haxima-1.001/P_terrain_test.scm: + Added end-of-line comments to map lines with the Y coordinate. + +2004-09-01 Gordon McNutt + + * src/character.cpp, src/player.cpp: + Forcing the player to follow mode when a single-member party wants to exit a small-scale place and it isn't in follow mode. Convenience feature. + + * worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/shard.scm, worlds/haxima-1.001/sprites.scm: + Expanded world map to alpha release size + + * worlds/haxima-1.001/shard.scm: + *** empty log message *** + +2004-08-28 Gordon McNutt + + * BUGS, src/Container.cpp, src/cmd.c, src/object.c, src/place.c, src/place.h: + o Bugfix: getting certain items like a poison bolt would lock/crash the engine + o Bugfix: getting piles of items was emitting one message per item in the pile + +2004-08-26 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/arms.scm: + Changed various sprites to new hi-res sprites. + Added some objects to the Terrain Test. + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/food.scm, worlds/haxima-1.001/objs.scm: + Replacing ss_angband sprites with the new higher resolution sprites. + + * worlds/haxima-1.001/images/kgabbert/new_terrains.png: + Added a boulder-on-grass sprite (for use as a terrain) + in addition to the boulder sprite (with FF00FF for a terrain feature). + +2004-08-26 Gordon McNutt + + * src/kern.c, src/status.c, src/status.h: + Added kern-ui-select-from-list + + * src/place.c: + Fixed some item count reporting when examing around + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/food.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/items.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/troll.scm: + Added more stuff to the start place + + * worlds/haxima-1.001/gregor.scm: + Tweaked gregor's conv + + * worlds/haxima-1.001/gregor.scm: + Fixed a bug in gregor's conv + + * worlds/haxima-1.001/items.scm: + Added to the in-game user's manual + + * worlds/haxima-1.001/session.scm: + Renamed a potion type + +2004-08-25 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/scenery.scm, worlds/haxima-1.001/sprite-sets.scm, worlds/haxima-1.001/sprites.scm: + Added ss_kg_potions_1 and ss_kg_potions_2 to the Sprite Gallery. + +2004-08-25 Gordon McNutt + + * src/common.h, src/play.c: + Reduced rate of time + + * worlds/haxima-1.001/gregor.scm: + Added a bit more to Gregor's conversation + + * worlds/haxima-1.001/gregor.scm: + New file + + * worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/session.scm: + Added Gregor to the start place + +2004-08-24 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/scenery.scm, worlds/haxima-1.001/sprites.scm: + Added ss_dg_commodities to the sprite gallery. + + * worlds/haxima-1.001/haxima.scm: + Added the Terrain Test and the Sprite Gallery to the shard surface + for test purposes. + +2004-08-24 Gordon McNutt + + * worlds/haxima-1.001/haxima.scm: + Simplified startup script for development + + * worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm: + More changes to moongate clearing + + * worlds/haxima-1.001/images/sglasby/rune_font_8x16.png: + Fattening up the run sprites + +2004-08-23 Gordon McNutt + + * Attic/Makefile.in, examples/Makefile.in, examples/data/images/frame_pieces.png, src/kern.c, src/place.c, src/place.h, src/play.c, src/player.cpp, src/session.c, src/sprite.c, src/sprite.h, worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/session.scm: + You can now specify coordinates for edge entrances to places + + * src/character.cpp, src/kern.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/gmcnutt/features2.png: + Tweaked the startup scene a bit + + * src/character.cpp, src/kern.c, src/nazghul.c, src/play.c, src/player.cpp, src/session.c, src/session.h, src/sprite.c, src/terrain_map.c, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm: + Added a startup scene + + * src/kern.c, src/Attic/moongate.c, src/Attic/moongate.h, src/nazghul.c, src/play.c, src/play.h, src/player.cpp, src/player.h, src/session.c, src/session.h, src/wq.c, src/wq.h: + o Cleaned up the work queues a bit. + + * worlds/haxima-1.001/haxima.scm: + Added an optional startup script + + * worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/session.scm: + Polishing up the maps a bit + + * worlds/haxima-1.001/moongate-clearing.scm: + Tweaks to Moongate Clearing map + +2004-08-21 Gordon McNutt + + * src/cmd.c, src/log.c, src/log.h: + o Added log_flush() + + * src/ctrl.c: + Setting Follow mode will not end the party leader's turn + + * worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/troll.scm: + Added a basic no-frills troll + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/troll.scm: + o Increased troll vision radius + o Changed default action points required by weapons to be the number of action + points per turn for humans + o Bugfix: needed to kern-load ilya.scm from gregors-hut.scm + +2004-08-20 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/scenery.scm, worlds/haxima-1.001/sprites.scm: + Added sprites, scenery objects, and sprite gallery chambers for: + - ss_dg_tools + - ss_dg_readable + +2004-08-19 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/scenery.scm, worlds/haxima-1.001/sprites.scm: + Fixing some arrow/bolt sprites. + One arrow and two bolts are still glowing the wrong color + (plus wrong fletching) + Two bolts are moving 1 px Left/Right as they animate. + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/scenery.scm, worlds/haxima-1.001/sprites.scm: + Fixed numbering of some arrow/bolt sprites. + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/scenery.scm: + Added weapon sprites, put them in the Sprite Gallery. + + * worlds/haxima-1.001/images/dgervais/dg_weapons.trans.png: + Fixed the top-left magic arrow (red glowing, was blue glowing) + +2004-08-19 Gordon McNutt + + * src/character.cpp, src/character.h, src/kern.c, src/species.c, src/species.h, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/tests/basic-party.scm, worlds/haxima-1.001/tests/char-enter.save.mstr, worlds/haxima-1.001/tests/char-enter.scm, worlds/haxima-1.001/tests/char-get.save.mstr, worlds/haxima-1.001/tests/char-get.scm, worlds/haxima-1.001/tests/char-handle.save.mstr, worlds/haxima-1.001/tests/char-handle.scm, worlds/haxima-1.001/tests/char-kamp.save.mstr, worlds/haxima-1.001/tests/char-kamp.scm, worlds/haxima-1.001/tests/char-new-order-1.save.mstr, worlds/haxima-1.001/tests/char-new-order-1.scm, worlds/haxima-1.001/tests/char-new-order-2.save.mstr, worlds/haxima-1.001/tests/char-new-order-2.scm, worlds/haxima-1.001/tests/char-new-order-3.save.mstr, worlds/haxima-1.001/tests/char-new-order-3.scm, worlds/haxima-1.001/tests/char-open.console.mstr, worlds/haxima-1.001/tests/char-open.save.mstr, worlds/haxima-1.001/tests/char-open.scm, worlds/haxima-1.001/tests/char-ready.save.mstr, worlds/haxima-1.001/tests/char-ready.scm, worlds/haxima-1.001/tests/char-search.console.mstr, worlds/haxima-1.001/tests/char-search.save.mstr, worlds/haxima-1.001/tests/char-search.scm, worlds/haxima-1.001/tests/char-talk.save.mstr, worlds/haxima-1.001/tests/char-talk.scm, worlds/haxima-1.001/tests/char-use.save.mstr, worlds/haxima-1.001/tests/char-use.scm, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.save.mstr, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.scm, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/console-at.save.mstr, worlds/haxima-1.001/tests/console-board.save.mstr, worlds/haxima-1.001/tests/console-examine.console.mstr, worlds/haxima-1.001/tests/console-examine.save.mstr, worlds/haxima-1.001/tests/console-party-attack.save.mstr, worlds/haxima-1.001/tests/console-party-cast.console.mstr, worlds/haxima-1.001/tests/console-party-cast.save.mstr, worlds/haxima-1.001/tests/console-party-fire.save.mstr, worlds/haxima-1.001/tests/console-party-get.save.mstr, worlds/haxima-1.001/tests/console-party-handle.save.mstr, worlds/haxima-1.001/tests/console-party-mix.save.mstr, worlds/haxima-1.001/tests/console-pass.save.mstr, worlds/haxima-1.001/tests/console-terraform.console.mstr, worlds/haxima-1.001/tests/console-terraform.save.mstr, worlds/haxima-1.001/tests/dtable-1.save.mstr, worlds/haxima-1.001/tests/dtable-1.scm, worlds/haxima-1.001/tests/dtable-2.save.mstr, worlds/haxima-1.001/tests/dtable-2.scm, worlds/haxima-1.001/tests/eternal-sleep.save.mstr, worlds/haxima-1.001/tests/eternal-sleep.scm, worlds/haxima-1.001/tests/factions-1.save.mstr, worlds/haxima-1.001/tests/factions-1.scm, worlds/haxima-1.001/tests/mech-1.save.mstr, worlds/haxima-1.001/tests/mech-1.scm, worlds/haxima-1.001/tests/mech-2.scm, worlds/haxima-1.001/tests/party-at.scm, worlds/haxima-1.001/tests/party-new-order-2.scm, worlds/haxima-1.001/tests/party-new-order-3.scm, worlds/haxima-1.001/tests/party-open.scm, worlds/haxima-1.001/tests/party-ready.scm, worlds/haxima-1.001/tests/party-search.scm, worlds/haxima-1.001/tests/party-talk.scm, worlds/haxima-1.001/tests/place-to-place-1.scm, worlds/haxima-1.001/tests/rendezvous-ap-lag.scm, worlds/haxima-1.001/tests/session.scm, worlds/haxima-1.001/tests/test-map-1.scm, worlds/haxima-1.001/tests/tfeat-1.save.mstr, worlds/haxima-1.001/tests/tfeat-1.scm, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-2.save.mstr: + o Removed the damage, defend, armor and (I forgot the other one) mod fields in + the character class and species struct. They've never been used and I doubt + we'll miss them. Simplifies character and species creation to remove them. + +2004-08-18 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/sprites.scm: + Fixed some mis-numbered sprites in ss_dg_wearable. + + * worlds/haxima-1.001/P_terrain_test.scm: + Some polish on the wearable items gallery. + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/scenery.scm: + Added scenery objects for all tiles in ss_dg_wearable + and placed them in a new chamber in the Sprite Gallery. + + * worlds/haxima-1.001/moongate-clearing.scm: + Added a sprite for the moongate-clearing. + + * worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/kgabbert/new_terrains.png: + Added new s_deep and s_shoals. + +2004-08-18 Gordon McNutt + + * src/cmd.c, src/cmd.h, src/kern.c, src/log.c, worlds/haxima-1.001/ilya.scm: + o Added kern-conv-get-reply to directly query the player in a conversation. + + * src/kern.c, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/gregors-hut-zones.scm, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/ilya.scm, worlds/haxima-1.001/shroom.scm: + o kern-mk-sched now expects the "zone" rectangle of a schedule entry to be a + list. + o Gave Ilya a schedule that demonstrates how to use named zones to fill out the + place for a schedule entry. Reference gregors-hut-zones.scm. + + * worlds/haxima-1.001/abandoned-farm.scm, worlds/haxima-1.001/haxima.scm: + Added Ilya's abandoned homestead + +2004-08-17 Sam Glasby + + * worlds/haxima-1.001/sprite-sets.scm: + Added various sprite sheets containing tiles + from David Gervais and Kevin Gabbert. + + * worlds/haxima-1.001/sprites.scm: + Added some notes (arrow/bolt tiles to fix) + + * worlds/haxima-1.001/sprites.scm: + Finished ss_dg_weapons. + + * worlds/haxima-1.001/sprites.scm: + Fixed amulets + + * worlds/haxima-1.001/sprites.scm: + Adding weapon sprites. + + * worlds/haxima-1.001/sprites.scm: + Adding sprites for ss_dg_weapons. + + * worlds/haxima-1.001/sprites.scm: + Added sprite bindings for ss_dg_wearable. + +2004-08-17 Gordon McNutt + + * src/cmd.c, src/scheme-private.h, src/scheme.c, src/scheme.h, src/session.c: + Added file and line number reporting to scheme errors + + * src/factions.h: + Added missing file. + + * worlds/haxima-1.001/game.scm, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/ilya.scm: + Added Ilya to Gregor's Hut + + * worlds/haxima-1.001/session.scm: + Removed references to Gregor's Hut. + +2004-08-16 Gordon McNutt + + * worlds/haxima-1.001/game.scm, worlds/haxima-1.001/haxima.scm, worlds/haxima-1.001/moon.scm, worlds/haxima-1.001/moongate-clearing.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/pre-entry-hooks.scm, worlds/haxima-1.001/session.scm: + Added some script files for haxima + +2004-08-15 Gordon McNutt + + * src/Being.cpp, src/Being.h, src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/common.h, src/conv.c, src/conv.h, src/ctrl.c, src/dtable.h, src/kern.c, src/object.c, src/object.h, src/place.c, src/place.h, src/player.cpp, src/player.h, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/tests/basic-party.scm, worlds/haxima-1.001/tests/char-enter.save.mstr, worlds/haxima-1.001/tests/char-enter.scm, worlds/haxima-1.001/tests/char-get.save.mstr, worlds/haxima-1.001/tests/char-get.scm, worlds/haxima-1.001/tests/char-handle.save.mstr, worlds/haxima-1.001/tests/char-handle.scm, worlds/haxima-1.001/tests/char-kamp.save.mstr, worlds/haxima-1.001/tests/char-kamp.scm, worlds/haxima-1.001/tests/char-new-order-1.save.mstr, worlds/haxima-1.001/tests/char-new-order-1.scm, worlds/haxima-1.001/tests/char-new-order-2.save.mstr, worlds/haxima-1.001/tests/char-new-order-2.scm, worlds/haxima-1.001/tests/char-new-order-3.save.mstr, worlds/haxima-1.001/tests/char-new-order-3.scm, worlds/haxima-1.001/tests/char-open.save.mstr, worlds/haxima-1.001/tests/char-open.scm, worlds/haxima-1.001/tests/char-ready.save.mstr, worlds/haxima-1.001/tests/char-ready.scm, worlds/haxima-1.001/tests/char-search.save.mstr, worlds/haxima-1.001/tests/char-search.scm, worlds/haxima-1.001/tests/char-talk.save.mstr, worlds/haxima-1.001/tests/char-talk.scm, worlds/haxima-1.001/tests/char-use.save.mstr, worlds/haxima-1.001/tests/char-use.scm, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.save.mstr, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.scm, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/console-at.save.mstr, worlds/haxima-1.001/tests/console-attack.save.mstr, worlds/haxima-1.001/tests/console-board.save.mstr, worlds/haxima-1.001/tests/console-examine.save.mstr, worlds/haxima-1.001/tests/console-exit.save.mstr, worlds/haxima-1.001/tests/console-party-attack.save.mstr, worlds/haxima-1.001/tests/console-party-cast.save.mstr, worlds/haxima-1.001/tests/console-party-fire.save.mstr, worlds/haxima-1.001/tests/console-party-get.save.mstr, worlds/haxima-1.001/tests/console-party-handle.save.mstr, worlds/haxima-1.001/tests/console-party-kamp.save.mstr, worlds/haxima-1.001/tests/console-party-mix.save.mstr, worlds/haxima-1.001/tests/console-pass.save.mstr, worlds/haxima-1.001/tests/console-terraform.save.mstr, worlds/haxima-1.001/tests/dtable-1.save.mstr, worlds/haxima-1.001/tests/dtable-1.scm, worlds/haxima-1.001/tests/dtable-2.save.mstr, worlds/haxima-1.001/tests/dtable-2.scm, worlds/haxima-1.001/tests/empty-party.scm, worlds/haxima-1.001/tests/eternal-sleep.save.mstr, worlds/haxima-1.001/tests/eternal-sleep.scm, worlds/haxima-1.001/tests/factions-1.save.mstr, worlds/haxima-1.001/tests/factions-1.scm, worlds/haxima-1.001/tests/mech-1.save.mstr, worlds/haxima-1.001/tests/mech-1.scm, worlds/haxima-1.001/tests/mech-2.save.mstr, worlds/haxima-1.001/tests/mech-2.scm, worlds/haxima-1.001/tests/party-at.save.mstr, worlds/haxima-1.001/tests/party-at.scm, worlds/haxima-1.001/tests/party-new-order-1.save.mstr, worlds/haxima-1.001/tests/party-new-order-1.scm, worlds/haxima-1.001/tests/party-new-order-2.save.mstr, worlds/haxima-1.001/tests/party-new-order-2.scm, worlds/haxima-1.001/tests/party-new-order-3.save.mstr, worlds/haxima-1.001/tests/party-new-order-3.scm, worlds/haxima-1.001/tests/party-open.save.mstr, worlds/haxima-1.001/tests/party-open.scm, worlds/haxima-1.001/tests/party-ready.save.mstr, worlds/haxima-1.001/tests/party-ready.scm, worlds/haxima-1.001/tests/party-search.save.mstr, worlds/haxima-1.001/tests/party-search.scm, worlds/haxima-1.001/tests/party-talk.save.mstr, worlds/haxima-1.001/tests/party-talk.scm, worlds/haxima-1.001/tests/place-to-place-1.console.mstr, worlds/haxima-1.001/tests/place-to-place-1.save.mstr, worlds/haxima-1.001/tests/place-to-place-1.scm, worlds/haxima-1.001/tests/rendezvous-ap-lag.save.mstr, worlds/haxima-1.001/tests/rendezvous-ap-lag.scm, worlds/haxima-1.001/tests/session.scm, worlds/haxima-1.001/tests/tfeat-1.save.mstr, worlds/haxima-1.001/tests/tfeat-1.scm, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-2.save.mstr: + + o Removed all references to the obsolete alignment system. Converted everything + to use factions. + + o Tore out all the faction stack stuff related to characters (if any managed to + get checked in). Parties have a base faction that is set when they are + created and never changed after that. Characters have a base faction and a + temporary faction which is used by the charm effect. It's very much the same + as before, but a bug was fixed where if a charm effect expired it would + remove a different, currently active charm effect. + + o Cleaned up old obsolete structures in conv.h + + o Character::useAmmo is now non-virtual and it takes the weapon as an + argument. Fixes a bug found when yellow slimes tried to use their acid spray. + + * src/character.cpp, src/cmd.c, src/ctrl.c, src/kern.c, src/log.c, src/log.h, src/object.c, src/object.h, src/result.h, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/Attic/player.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spells.scm: + o Charm and confuse now seem to be functioning normally again. This concludes + the implementation of the new diplomacy system. + + * worlds/haxima-1.001/session.scm: + Updated kern-mk-player to be compatible with recent changes + +2004-08-13 Gordon McNutt + + * src/Being.cpp, src/Being.h, src/Party.cpp, src/character.cpp, src/common.h, src/kern.c, src/player.cpp, src/player.h, src/session.c, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/tests/basic-party.scm, worlds/haxima-1.001/tests/char-enter.save.mstr, worlds/haxima-1.001/tests/char-enter.scm, worlds/haxima-1.001/tests/char-get.save.mstr, worlds/haxima-1.001/tests/char-get.scm, worlds/haxima-1.001/tests/char-handle.save.mstr, worlds/haxima-1.001/tests/char-handle.scm, worlds/haxima-1.001/tests/char-kamp.save.mstr, worlds/haxima-1.001/tests/char-kamp.scm, worlds/haxima-1.001/tests/char-new-order-1.save.mstr, worlds/haxima-1.001/tests/char-new-order-1.scm, worlds/haxima-1.001/tests/char-new-order-2.save.mstr, worlds/haxima-1.001/tests/char-new-order-2.scm, worlds/haxima-1.001/tests/char-new-order-3.save.mstr, worlds/haxima-1.001/tests/char-new-order-3.scm, worlds/haxima-1.001/tests/char-open.save.mstr, worlds/haxima-1.001/tests/char-open.scm, worlds/haxima-1.001/tests/char-ready.save.mstr, worlds/haxima-1.001/tests/char-ready.scm, worlds/haxima-1.001/tests/char-search.save.mstr, worlds/haxima-1.001/tests/char-search.scm, worlds/haxima-1.001/tests/char-talk.save.mstr, worlds/haxima-1.001/tests/char-talk.scm, worlds/haxima-1.001/tests/char-use.save.mstr, worlds/haxima-1.001/tests/char-use.scm, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.save.mstr, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.scm, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/console-at.save.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-attack.save.mstr, worlds/haxima-1.001/tests/console-board.save.mstr, worlds/haxima-1.001/tests/console-examine.save.mstr, worlds/haxima-1.001/tests/console-exit.save.mstr, worlds/haxima-1.001/tests/console-party-attack.save.mstr, worlds/haxima-1.001/tests/console-party-cast.save.mstr, worlds/haxima-1.001/tests/console-party-fire.save.mstr, worlds/haxima-1.001/tests/console-party-get.save.mstr, worlds/haxima-1.001/tests/console-party-handle.save.mstr, worlds/haxima-1.001/tests/console-party-kamp.save.mstr, worlds/haxima-1.001/tests/console-party-mix.save.mstr, worlds/haxima-1.001/tests/console-pass.save.mstr, worlds/haxima-1.001/tests/console-terraform.save.mstr, worlds/haxima-1.001/tests/dtable-1.save.mstr, worlds/haxima-1.001/tests/dtable-1.scm, worlds/haxima-1.001/tests/dtable-2.save.mstr, worlds/haxima-1.001/tests/dtable-2.scm, worlds/haxima-1.001/tests/eternal-sleep.save.mstr, worlds/haxima-1.001/tests/eternal-sleep.scm, worlds/haxima-1.001/tests/mech-1.save.mstr, worlds/haxima-1.001/tests/mech-1.scm, worlds/haxima-1.001/tests/mech-2.save.mstr, worlds/haxima-1.001/tests/mech-2.scm, worlds/haxima-1.001/tests/party-at.save.mstr, worlds/haxima-1.001/tests/party-at.scm, worlds/haxima-1.001/tests/party-new-order-1.save.mstr, worlds/haxima-1.001/tests/party-new-order-1.scm, worlds/haxima-1.001/tests/party-new-order-2.save.mstr, worlds/haxima-1.001/tests/party-new-order-2.scm, worlds/haxima-1.001/tests/party-new-order-3.save.mstr, worlds/haxima-1.001/tests/party-new-order-3.scm, worlds/haxima-1.001/tests/party-open.save.mstr, worlds/haxima-1.001/tests/party-open.scm, worlds/haxima-1.001/tests/party-ready.save.mstr, worlds/haxima-1.001/tests/party-ready.scm, worlds/haxima-1.001/tests/party-search.save.mstr, worlds/haxima-1.001/tests/party-search.scm, worlds/haxima-1.001/tests/party-talk.save.mstr, worlds/haxima-1.001/tests/party-talk.scm, worlds/haxima-1.001/tests/place-to-place-1.save.mstr, worlds/haxima-1.001/tests/place-to-place-1.scm, worlds/haxima-1.001/tests/rendezvous-ap-lag.save.mstr, worlds/haxima-1.001/tests/rendezvous-ap-lag.scm, worlds/haxima-1.001/tests/session.scm, worlds/haxima-1.001/tests/tfeat-1.save.mstr, worlds/haxima-1.001/tests/tfeat-1.scm, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-2.save.mstr: + o Adding a new party member automatically pushes the party's faction onto the + new member's faction stack. + + o Added kern-party-add-member to the script API; in the initial load-file it's + best to use this instead of listing the members within the player party + declaration since it automatically updates each member's faction stack. + + * src/common.h, src/kern.c, worlds/haxima-1.001/tests/factions-1.cmdwin.mstr, worlds/haxima-1.001/tests/factions-1.console.mstr, worlds/haxima-1.001/tests/factions-1.rec, worlds/haxima-1.001/tests/factions-1.save.mstr, worlds/haxima-1.001/tests/factions-1.scm, worlds/haxima-1.001/tests/list: + o Exported all the being faction methods to the script + (kern-being-push-faction, etc). + +2004-08-12 Gordon McNutt + + * src/Being.cpp, src/Being.h, src/Makefile.am, src/Attic/Makefile.in, src/Party.cpp, src/Party.h, src/character.h, src/dtable.c, src/dtable.h, src/hstack.c, src/hstack.h, src/kern.c, src/session.c, src/session.h, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/tests/basic-time.scm, worlds/haxima-1.001/tests/char-enter.save.mstr, worlds/haxima-1.001/tests/char-get.save.mstr, worlds/haxima-1.001/tests/char-handle.save.mstr, worlds/haxima-1.001/tests/char-kamp.save.mstr, worlds/haxima-1.001/tests/char-new-order-1.save.mstr, worlds/haxima-1.001/tests/char-new-order-2.save.mstr, worlds/haxima-1.001/tests/char-new-order-3.save.mstr, worlds/haxima-1.001/tests/char-open.save.mstr, worlds/haxima-1.001/tests/char-ready.save.mstr, worlds/haxima-1.001/tests/char-search.save.mstr, worlds/haxima-1.001/tests/char-talk.save.mstr, worlds/haxima-1.001/tests/char-use.save.mstr, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.save.mstr, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/console-at.save.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-attack.save.mstr, worlds/haxima-1.001/tests/console-board.save.mstr, worlds/haxima-1.001/tests/console-examine.save.mstr, worlds/haxima-1.001/tests/console-exit.save.mstr, worlds/haxima-1.001/tests/console-party-attack.save.mstr, worlds/haxima-1.001/tests/console-party-cast.save.mstr, worlds/haxima-1.001/tests/console-party-fire.save.mstr, worlds/haxima-1.001/tests/console-party-get.save.mstr, worlds/haxima-1.001/tests/console-party-handle.save.mstr, worlds/haxima-1.001/tests/console-party-kamp.save.mstr, worlds/haxima-1.001/tests/console-party-mix.save.mstr, worlds/haxima-1.001/tests/console-pass.save.mstr, worlds/haxima-1.001/tests/console-terraform.save.mstr, worlds/haxima-1.001/tests/dtable-1.save.mstr, worlds/haxima-1.001/tests/dtable-1.scm, worlds/haxima-1.001/tests/dtable-2.save.mstr, worlds/haxima-1.001/tests/dtable-2.scm, worlds/haxima-1.001/tests/eternal-sleep.save.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/mech-1.save.mstr, worlds/haxima-1.001/tests/mech-2.save.mstr, worlds/haxima-1.001/tests/mech-2.scm, worlds/haxima-1.001/tests/party-at.save.mstr, worlds/haxima-1.001/tests/party-new-order-1.save.mstr, worlds/haxima-1.001/tests/party-new-order-2.save.mstr, worlds/haxima-1.001/tests/party-new-order-3.save.mstr, worlds/haxima-1.001/tests/party-open.save.mstr, worlds/haxima-1.001/tests/party-ready.save.mstr, worlds/haxima-1.001/tests/party-search.save.mstr, worlds/haxima-1.001/tests/party-talk.save.mstr, worlds/haxima-1.001/tests/place-to-place-1.save.mstr, worlds/haxima-1.001/tests/rendezvous-ap-lag.save.mstr, worlds/haxima-1.001/tests/session.scm, worlds/haxima-1.001/tests/tfeat-1.save.mstr, worlds/haxima-1.001/tests/tfeat-1.scm, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-2.save.mstr: + o Handles are now saved and loaded with elements of an hstack. + +2004-08-11 Gordon McNutt + + * src/dtable.c, src/dtable.h, src/hstack.c, src/hstack.h, src/kern.c, src/macros.h, src/session.c, worlds/haxima-1.001/tests/dtable-1.save.mstr, worlds/haxima-1.001/tests/dtable-1.scm, worlds/haxima-1.001/tests/dtable-2.cmdwin.mstr, worlds/haxima-1.001/tests/dtable-2.console.mstr, worlds/haxima-1.001/tests/dtable-2.rec, worlds/haxima-1.001/tests/dtable-2.save.mstr, worlds/haxima-1.001/tests/dtable-2.scm: + o Saving/loading stack-based diplomacy table. + o Added kern_dtable_push/pop to the script API. + o Consolidated the kern_dtable_* functions into a common function to eliminate + redundant error-checking. + +2004-08-10 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/dtable.c, src/dtable.h, src/hstack.c, src/hstack.h: + Converted diplomacy table to be a table of stacks instead of a table of integers + + * src/Makefile.am, src/Attic/Makefile.in, src/dtable.c, src/dtable.h, src/kern.c, src/place.c, src/session.c, src/session.h, worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/scenery.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/tests/basic-time.scm, worlds/haxima-1.001/tests/char-enter.save.mstr, worlds/haxima-1.001/tests/char-enter.scm, worlds/haxima-1.001/tests/char-get.save.mstr, worlds/haxima-1.001/tests/char-handle.save.mstr, worlds/haxima-1.001/tests/char-kamp.save.mstr, worlds/haxima-1.001/tests/char-new-order-1.save.mstr, worlds/haxima-1.001/tests/char-new-order-2.save.mstr, worlds/haxima-1.001/tests/char-new-order-3.save.mstr, worlds/haxima-1.001/tests/char-open.save.mstr, worlds/haxima-1.001/tests/char-ready.save.mstr, worlds/haxima-1.001/tests/char-search.save.mstr, worlds/haxima-1.001/tests/char-talk.save.mstr, worlds/haxima-1.001/tests/char-use.save.mstr, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.save.mstr, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/console-at.save.mstr, worlds/haxima-1.001/tests/console-attack.save.mstr, worlds/haxima-1.001/tests/console-board.save.mstr, worlds/haxima-1.001/tests/console-examine.save.mstr, worlds/haxima-1.001/tests/console-exit.save.mstr, worlds/haxima-1.001/tests/console-party-attack.save.mstr, worlds/haxima-1.001/tests/console-party-cast.save.mstr, worlds/haxima-1.001/tests/console-party-fire.save.mstr, worlds/haxima-1.001/tests/console-party-get.save.mstr, worlds/haxima-1.001/tests/console-party-handle.save.mstr, worlds/haxima-1.001/tests/console-party-kamp.save.mstr, worlds/haxima-1.001/tests/console-party-mix.save.mstr, worlds/haxima-1.001/tests/console-pass.save.mstr, worlds/haxima-1.001/tests/console-terraform.save.mstr, worlds/haxima-1.001/tests/eternal-sleep.save.mstr, worlds/haxima-1.001/tests/mech-1.save.mstr, worlds/haxima-1.001/tests/mech-2.save.mstr, worlds/haxima-1.001/tests/mech-2.scm, worlds/haxima-1.001/tests/party-at.save.mstr, worlds/haxima-1.001/tests/party-new-order-1.save.mstr, worlds/haxima-1.001/tests/party-new-order-2.save.mstr, worlds/haxima-1.001/tests/party-new-order-3.save.mstr, worlds/haxima-1.001/tests/party-open.save.mstr, worlds/haxima-1.001/tests/party-ready.save.mstr, worlds/haxima-1.001/tests/party-search.save.mstr, worlds/haxima-1.001/tests/party-talk.save.mstr, worlds/haxima-1.001/tests/place-to-place-1.cmdwin.mstr, worlds/haxima-1.001/tests/place-to-place-1.console.mstr, worlds/haxima-1.001/tests/place-to-place-1.rec, worlds/haxima-1.001/tests/place-to-place-1.save.mstr, worlds/haxima-1.001/tests/place-to-place-1.scm, worlds/haxima-1.001/tests/place-to-place-1.scm.cmdwin.mstr, worlds/haxima-1.001/tests/place-to-place-1.scm.console.mstr, worlds/haxima-1.001/tests/place-to-place-1.scm.rec, worlds/haxima-1.001/tests/place-to-place-1.scm.save.mstr, worlds/haxima-1.001/tests/rendezvous-ap-lag.save.mstr, worlds/haxima-1.001/tests/session.scm, worlds/haxima-1.001/tests/tfeat-1.save.mstr, worlds/haxima-1.001/tests/tfeat-1.scm, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-2.save.mstr: + o Bugfix: in party mode exit to another small-scale place with no coordinates + matching those you just came from. Causes an assert. Problem was place_exec() + was assuming that if the object was still on-map after its turn it was on the + SAME map as before its turn. Removed the assumption, added a regression test + to catch this again (place-to-place-1). + o Added the new dtable (diplomacy table) implementation and the ability to + load/save it. Otherwise not used for anything yet. + o Moved the scenery definitions in P_terrain_test to a file loaded by + game.scm. Needed this to fix a save/reload problem. + + * src/dtable.c, src/dtable.h, src/kern.c, worlds/haxima-1.001/tests/dtable-1.cmdwin.mstr, worlds/haxima-1.001/tests/dtable-1.console.mstr, worlds/haxima-1.001/tests/dtable-1.rec, worlds/haxima-1.001/tests/dtable-1.save.mstr, worlds/haxima-1.001/tests/dtable-1.scm, worlds/haxima-1.001/tests/list: + Exported dtable API to script and added tests + +2004-08-07 Gordon McNutt + + * src/combat.c, src/vmask.h: + Bugfix: LOS in wilderness combat or zoom-in was sometimes wrong because of stale entries in the vmask cache. Solution was to invalidate all vmasks for the combat place upon exit from wilderness combat. + + * src/object.c, src/object.h, src/player.cpp, src/vmask.c, worlds/haxima-1.001/tests/char-enter.console.mstr, worlds/haxima-1.001/tests/char-enter.save.mstr, worlds/haxima-1.001/tests/char-use.save.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-party-kamp.console.mstr, worlds/haxima-1.001/tests/console-party-kamp.save.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/rendezvous-ap-lag.cmdwin.mstr, worlds/haxima-1.001/tests/rendezvous-ap-lag.console.mstr, worlds/haxima-1.001/tests/rendezvous-ap-lag.rec, worlds/haxima-1.001/tests/rendezvous-ap-lag.save.mstr, worlds/haxima-1.001/tests/rendezvous-ap-lag.scm: + o Bugfix: after a rendezvous exit party members would be immobile for a few + turns upon entry to another place. This was due to an action point debt + incurred during the rendezvous. Fixed this by zeroing out the action point + debt during a rendezvous so it doesn't carry over to new places. + + * src/place.c, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/tests/eternal-sleep.cmdwin.mstr, worlds/haxima-1.001/tests/eternal-sleep.console.mstr, worlds/haxima-1.001/tests/eternal-sleep.rec, worlds/haxima-1.001/tests/eternal-sleep.save.mstr, worlds/haxima-1.001/tests/eternal-sleep.scm, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/mech-2.save.mstr: + o Bugfix: if your only party member steps on a permanent sleep field at town + scale then they will never wake up. The fix was to apply per-tile effects to + objects _after_ they have a chance to take their turn. + +2004-08-06 Gordon McNutt + + * src/character.cpp, src/cmd.c, src/cmd.h, src/ctrl.c, src/player.cpp, worlds/haxima-1.001/tests/char-kamp.cmdwin.mstr, worlds/haxima-1.001/tests/char-kamp.console.mstr, worlds/haxima-1.001/tests/char-kamp.rec, worlds/haxima-1.001/tests/char-kamp.save.mstr, worlds/haxima-1.001/tests/char-kamp.scm, worlds/haxima-1.001/tests/list: + o Added character-mode M)ix command + o Cleaned up console messages for character K)amp command + o Bugfix: party now wakes up in follow mode after kamping in town; must be in + follow mode before kamping. + + * src/cmd.c, src/ctrl.c, src/player.h, worlds/haxima-1.001/tests/char-new-order-1.cmdwin.mstr, worlds/haxima-1.001/tests/char-new-order-1.console.mstr, worlds/haxima-1.001/tests/char-new-order-1.rec, worlds/haxima-1.001/tests/char-new-order-1.save.mstr, worlds/haxima-1.001/tests/char-new-order-1.scm, worlds/haxima-1.001/tests/char-new-order-2.cmdwin.mstr, worlds/haxima-1.001/tests/char-new-order-2.console.mstr, worlds/haxima-1.001/tests/char-new-order-2.rec, worlds/haxima-1.001/tests/char-new-order-2.save.mstr, worlds/haxima-1.001/tests/char-new-order-2.scm, worlds/haxima-1.001/tests/char-new-order-3.cmdwin.mstr, worlds/haxima-1.001/tests/char-new-order-3.console.mstr, worlds/haxima-1.001/tests/char-new-order-3.rec, worlds/haxima-1.001/tests/char-new-order-3.save.mstr, worlds/haxima-1.001/tests/char-new-order-3.scm, worlds/haxima-1.001/tests/char-use.scm, worlds/haxima-1.001/tests/list: + Added N)ew Order command to character mode + + * src/cmd.c, src/ctrl.c, worlds/haxima-1.001/tests/char-open.cmdwin.mstr, worlds/haxima-1.001/tests/char-open.console.mstr, worlds/haxima-1.001/tests/char-open.rec, worlds/haxima-1.001/tests/char-open.save.mstr, worlds/haxima-1.001/tests/char-open.scm, worlds/haxima-1.001/tests/char-search.cmdwin.mstr, worlds/haxima-1.001/tests/char-search.console.mstr, worlds/haxima-1.001/tests/char-search.rec, worlds/haxima-1.001/tests/char-search.save.mstr, worlds/haxima-1.001/tests/char-search.scm, worlds/haxima-1.001/tests/char-talk.cmdwin.mstr, worlds/haxima-1.001/tests/char-talk.console.mstr, worlds/haxima-1.001/tests/char-talk.rec, worlds/haxima-1.001/tests/char-talk.save.mstr, worlds/haxima-1.001/tests/char-talk.scm, worlds/haxima-1.001/tests/char-use.cmdwin.mstr, worlds/haxima-1.001/tests/char-use.console.mstr, worlds/haxima-1.001/tests/char-use.rec, worlds/haxima-1.001/tests/char-use.save.mstr, worlds/haxima-1.001/tests/char-use.scm, worlds/haxima-1.001/tests/char-use.scm.cmdwin.mstr, worlds/haxima-1.001/tests/char-use.scm.console.mstr, worlds/haxima-1.001/tests/char-use.scm.rec, worlds/haxima-1.001/tests/list: + Cleaned up console messages for character search, talk, open and use commands + +2004-08-05 Sam Glasby + + * doc/engine_extension_and_design/README, doc/engine_extension_and_design/Attic/README~, doc/engine_extension_and_design/my_TODO.2004.05.05.txt: + Added a dir engine_extension_and_design. + Added a README for that dir. + Added some documents therein. + + * doc/engine_extension_and_design/Attic/README~: + Backup file got added by mistake. + + * worlds/haxima-1.001/terrains.scm: + Added a dir for world_building_notes. + Added a README in that directory. + Added various documents therein. + + * worlds/haxima-1.001/world_building_notes/2004.02.19.design_notes.various.txt, worlds/haxima-1.001/world_building_notes/2004.03.28.character_advancement.txt, worlds/haxima-1.001/world_building_notes/2004.05.27.world_building.txt, worlds/haxima-1.001/world_building_notes/2004.06.02.world_building.txt, worlds/haxima-1.001/world_building_notes/2004.06.30.design_notes.conversations_and_NPCs.txt, worlds/haxima-1.001/world_building_notes/2004.07.08.design_notes.various.txt, worlds/haxima-1.001/world_building_notes/2004.07.08.terrain_palettes.txt: + Added variout files to world_building_notes/. + + * worlds/haxima-1.001/world_building_notes/README: + Added a README for the world_building_notes dir. + +2004-08-05 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/cmd.c, src/conv.c, src/conv.h, src/ctrl.c, src/kern.c, src/object.c, src/object.h, src/status.c, src/status.h, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/party-talk.cmdwin.mstr, worlds/haxima-1.001/tests/party-talk.console.mstr, worlds/haxima-1.001/tests/party-talk.rec, worlds/haxima-1.001/tests/party-talk.save.mstr, worlds/haxima-1.001/tests/party-talk.scm, worlds/haxima-1.001/tests/party-talk.scm.cmdwin.mstr, worlds/haxima-1.001/tests/party-talk.scm.console.mstr, worlds/haxima-1.001/tests/party-talk.scm.rec, worlds/haxima-1.001/tests/party-talk.scm.save.mstr: + o Extended status api to support selecting from a generic list + o Rearranged the impl of conversation a bit + o Party::getConversation() now prompts the player with a list of members who + have conversations. + o Talking to a party in the wilderness now works with the above + changes. Currently, however, the only party with members who might have + conversations is the player's own party. + + * src/character.cpp, src/cmd.c, src/ctrl.c, src/player.cpp, worlds/haxima-1.001/tests/char-enter.cmdwin.mstr, worlds/haxima-1.001/tests/char-enter.console.mstr, worlds/haxima-1.001/tests/char-enter.rec, worlds/haxima-1.001/tests/char-enter.save.mstr, worlds/haxima-1.001/tests/char-enter.scm, worlds/haxima-1.001/tests/char-get.cmdwin.mstr, worlds/haxima-1.001/tests/char-get.console.mstr, worlds/haxima-1.001/tests/char-get.rec, worlds/haxima-1.001/tests/char-get.save.mstr, worlds/haxima-1.001/tests/char-get.scm, worlds/haxima-1.001/tests/char-handle.cmdwin.mstr, worlds/haxima-1.001/tests/char-handle.console.mstr, worlds/haxima-1.001/tests/char-handle.rec, worlds/haxima-1.001/tests/char-handle.save.mstr, worlds/haxima-1.001/tests/char-handle.scm, worlds/haxima-1.001/tests/char-ready.cmdwin.mstr, worlds/haxima-1.001/tests/char-ready.console.mstr, worlds/haxima-1.001/tests/char-ready.rec, worlds/haxima-1.001/tests/char-ready.save.mstr, worlds/haxima-1.001/tests/char-ready.scm, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.cmdwin.mstr, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.console.mstr, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.rec, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.save.mstr, worlds/haxima-1.001/tests/char-xamine-ztats-at-pass.scm, worlds/haxima-1.001/tests/cmdwin-1.console.mstr, worlds/haxima-1.001/tests/console-at.console.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-examine.console.mstr, worlds/haxima-1.001/tests/console-exit.console.mstr, worlds/haxima-1.001/tests/console-party-get.console.mstr, worlds/haxima-1.001/tests/console-party-kamp.console.mstr, worlds/haxima-1.001/tests/console-terraform.console.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/mech-1.console.mstr, worlds/haxima-1.001/tests/mech-2.console.mstr, worlds/haxima-1.001/tests/tfeat-1.console.mstr: + Cleaned up console messages for a bunch of character commands + + * src/cmd.c, src/status.c, worlds/haxima-1.001/tests/console-at.console.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/party-at.cmdwin.mstr, worlds/haxima-1.001/tests/party-at.console.mstr, worlds/haxima-1.001/tests/party-at.rec, worlds/haxima-1.001/tests/party-at.save.mstr, worlds/haxima-1.001/tests/party-at.scm: + Cleaned up console messages for party U)se and @ commands + + * src/ctrl.c, worlds/haxima-1.001/tests/console-party-attack.console.mstr, worlds/haxima-1.001/tests/console-party-fire.console.mstr, worlds/haxima-1.001/tests/console-pass.console.mstr, worlds/haxima-1.001/tests/party-at.console.mstr: + Removed an extra EOL for the party Pass command + +2004-08-04 Sam Glasby + + * src/images.c: + Added improved error logging on IMG_Load() in response to a Mac OS X bug. + + * worlds/haxima-1.001/images/kgabbert/kg_potions_1.trans.png, worlds/haxima-1.001/images/kgabbert/kg_potions_2.trans.png: + Added 2 tilesheets of potions from Kevin. + Potion artwork based on art from David Gervais. + Some arrangement by Sam Glasby. + +2004-08-04 Gordon McNutt + + * src/Party.cpp, src/cmd.c, src/kern.c, src/log.c, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/tests/console-party-get.console.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/mech-1.save.mstr, worlds/haxima-1.001/tests/mech-2.save.mstr, worlds/haxima-1.001/tests/party-new-order-1.save.mstr, worlds/haxima-1.001/tests/party-new-order-2.save.mstr, worlds/haxima-1.001/tests/party-new-order-3.save.mstr, worlds/haxima-1.001/tests/party-open.cmdwin.mstr, worlds/haxima-1.001/tests/party-open.console.mstr, worlds/haxima-1.001/tests/party-open.rec, worlds/haxima-1.001/tests/party-open.save.mstr, worlds/haxima-1.001/tests/party-open.scm, worlds/haxima-1.001/tests/test-map-1.scm, worlds/haxima-1.001/tests/tfeat-1.console.mstr: + o Added kern-log-msg + o Cleaned up console output related to party mode O)pen command + o Revisited console output related to party mode G)et command and reduced the + verbosity + + * src/Party.h, src/cmd.c, src/cmd.h, src/ctrl.c, src/status.c, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/party-open.console.mstr, worlds/haxima-1.001/tests/party-ready.cmdwin.mstr, worlds/haxima-1.001/tests/party-ready.console.mstr, worlds/haxima-1.001/tests/party-ready.rec, worlds/haxima-1.001/tests/party-ready.save.mstr, worlds/haxima-1.001/tests/party-ready.scm, worlds/haxima-1.001/tests/party-ready.scm.cmdwin.mstr, worlds/haxima-1.001/tests/party-ready.scm.console.mstr, worlds/haxima-1.001/tests/party-ready.scm.rec, worlds/haxima-1.001/tests/party-ready.scm.save.mstr: + o Bugfix: ready-arms stat window scrolled off-screen in some cases. + o Cleaned up console output related to party mode R)eady command + + * src/cmd.c, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/party-search.cmdwin.mstr, worlds/haxima-1.001/tests/party-search.console.mstr, worlds/haxima-1.001/tests/party-search.rec, worlds/haxima-1.001/tests/party-search.save.mstr, worlds/haxima-1.001/tests/party-search.scm: + Cleaned up console messages related to the party S)earch command + +2004-08-03 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm: + Tidied up the Sprite Gallery (chamber 1, missiles) + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/sprite-sets.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/dgervais/dg_missiles.trans.png: + Arranged the arrows in ss_dg_missiles, added them all to the Sprite Gallery. + + * worlds/haxima-1.001/sprite-sets.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/dgervais/dg_commodities.trans.png: + Added ss_dg_commodities. + + * worlds/haxima-1.001/images/dgervais/dg_commodities.trans.png, worlds/haxima-1.001/images/dgervais/dg_missiles.trans.png, worlds/haxima-1.001/images/dgervais/dg_potions.trans.png, worlds/haxima-1.001/images/dgervais/dg_readable.trans.png, worlds/haxima-1.001/images/dgervais/dg_tools.trans.png, worlds/haxima-1.001/images/dgervais/dg_weapons.trans.png, worlds/haxima-1.001/images/dgervais/dg_wearable_items.trans.png: + Added various transparency-containing tile sheets. + Original tiles by David Gervais. + Tile sheet organization by Sam Glasby. + Transparency and animation frames by Kevin Gabbert. + + * worlds/haxima-1.001/images/dgervais/dg_tools.trans.png: + Torches slightly misaligned, moved them into their frames. + + * worlds/haxima-1.001/images/dgervais/dg_weapons.trans.png: + Added black to inside whip loop. + +2004-08-03 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/cmd.c, src/list.h, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/party-new-order-1.cmdwin.mstr, worlds/haxima-1.001/tests/party-new-order-1.console.mstr, worlds/haxima-1.001/tests/party-new-order-1.rec, worlds/haxima-1.001/tests/party-new-order-1.save.mstr, worlds/haxima-1.001/tests/party-new-order-1.scm, worlds/haxima-1.001/tests/party-new-order-2.cmdwin.mstr, worlds/haxima-1.001/tests/party-new-order-2.console.mstr, worlds/haxima-1.001/tests/party-new-order-2.rec, worlds/haxima-1.001/tests/party-new-order-2.save.mstr, worlds/haxima-1.001/tests/party-new-order-2.scm, worlds/haxima-1.001/tests/party-new-order-3.cmdwin.mstr, worlds/haxima-1.001/tests/party-new-order-3.console.mstr, worlds/haxima-1.001/tests/party-new-order-3.rec, worlds/haxima-1.001/tests/party-new-order-3.save.mstr, worlds/haxima-1.001/tests/party-new-order-3.scm: + o Bugfix: New Order didn't work for parties with more than 2 members + o Cleaned up console output related to party mode N)ew Order command. + + * src/character.cpp, src/cmd.c, src/ctrl.c, worlds/haxima-1.001/tests/cmdwin-2.console.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-exit.console.mstr, worlds/haxima-1.001/tests/console-party-get.console.mstr, worlds/haxima-1.001/tests/console-party-kamp.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-kamp.console.mstr, worlds/haxima-1.001/tests/console-party-kamp.rec, worlds/haxima-1.001/tests/console-party-kamp.save.mstr, worlds/haxima-1.001/tests/console-party-kamp.scm, worlds/haxima-1.001/tests/console-party-kamp.scm.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-kamp.scm.console.mstr, worlds/haxima-1.001/tests/console-party-kamp.scm.rec, worlds/haxima-1.001/tests/console-party-kamp.scm.save.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/mech-1.console.mstr, worlds/haxima-1.001/tests/mech-2.console.mstr, worlds/haxima-1.001/tests/tfeat-1.console.mstr: + Cleaned up console messages for party mode K)amp command + + * src/cmd.c, worlds/haxima-1.001/tests/console-party-cast.console.mstr, worlds/haxima-1.001/tests/console-party-mix.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-mix.console.mstr, worlds/haxima-1.001/tests/console-party-mix.rec, worlds/haxima-1.001/tests/console-party-mix.save.mstr, worlds/haxima-1.001/tests/console-party-mix.scm, worlds/haxima-1.001/tests/list: + Cleaned up console messages for party mode M)ix command + + * src/place.c, src/ptable.h, worlds/haxima-1.001/bim.scm, worlds/haxima-1.001/drawbridge.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/lever.scm, worlds/haxima-1.001/portcullis.scm, worlds/haxima-1.001/stone-lantern.scm, worlds/haxima-1.001/tests/cmdwin-1.console.mstr, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/console-at.save.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-attack.save.mstr, worlds/haxima-1.001/tests/console-board.save.mstr, worlds/haxima-1.001/tests/console-examine.console.mstr, worlds/haxima-1.001/tests/console-examine.save.mstr, worlds/haxima-1.001/tests/console-exit.save.mstr, worlds/haxima-1.001/tests/console-party-attack.save.mstr, worlds/haxima-1.001/tests/console-party-fire.save.mstr, worlds/haxima-1.001/tests/console-party-handle.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-handle.console.mstr, worlds/haxima-1.001/tests/console-party-handle.rec, worlds/haxima-1.001/tests/console-party-handle.save.mstr, worlds/haxima-1.001/tests/console-party-handle.scm, worlds/haxima-1.001/tests/console-party-handle.scm.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-handle.scm.console.mstr, worlds/haxima-1.001/tests/console-party-handle.scm.rec, worlds/haxima-1.001/tests/console-pass.save.mstr, worlds/haxima-1.001/tests/console-terraform.save.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/mech-1.save.mstr, worlds/haxima-1.001/tests/mech-2.save.mstr, worlds/haxima-1.001/tests/session.scm: + o Bugfix: the (new) drawbridge terrain feature was always passable. + o Cleaned up console output related to party mode H)andle command. + + * worlds/haxima-1.001/tests/console-party-cast.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-cast.console.mstr, worlds/haxima-1.001/tests/console-party-cast.save.mstr, worlds/haxima-1.001/tests/console-party-cast.scm.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-cast.scm.console.mstr, worlds/haxima-1.001/tests/console-party-cast.scm.save.mstr, worlds/haxima-1.001/tests/console-party-get.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-get.console.mstr, worlds/haxima-1.001/tests/console-party-get.save.mstr: + Adding missing master files + + * worlds/haxima-1.001/tests/console-party-cast.rec, worlds/haxima-1.001/tests/console-party-cast.scm, worlds/haxima-1.001/tests/console-party-get.rec, worlds/haxima-1.001/tests/console-party-get.scm, worlds/haxima-1.001/tests/test-map-1.scm: + More missing test files + +2004-08-02 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Party.cpp, src/Party.h, src/Attic/Portal.cpp, src/Attic/Portal.h, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/ctrl.c, src/kern.c, src/object.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/player.h, src/session.c: + o Removed the obsolete Portal class. + o Removed the E)nter command in party mode because + 1. It's implementation was obsolete + 2. It's usefulness is questionable + 3. It will be easy to add back when we need it + + * src/Party.cpp, src/cmd.c, worlds/haxima-1.001/tests/console-party-fire.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-fire.console.mstr, worlds/haxima-1.001/tests/console-party-fire.rec, worlds/haxima-1.001/tests/console-party-fire.save.mstr, worlds/haxima-1.001/tests/console-party-fire.scm, worlds/haxima-1.001/tests/list: + Cleaned up the F)ire command + + * src/cmd.c, src/player.cpp, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/console-at.save.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-attack.save.mstr, worlds/haxima-1.001/tests/console-board.save.mstr, worlds/haxima-1.001/tests/console-examine.save.mstr, worlds/haxima-1.001/tests/console-exit.save.mstr, worlds/haxima-1.001/tests/console-party-attack.save.mstr, worlds/haxima-1.001/tests/console-party-fire.save.mstr, worlds/haxima-1.001/tests/console-pass.save.mstr, worlds/haxima-1.001/tests/console-terraform.save.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/session.scm: + Cleaned up console messages for party G)et command + +2004-08-01 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm: + Rearranged some missiles. + + * worlds/haxima-1.001/P_terrain_test.scm: + Added all missile sprites to the Sprite Gallery. + + * worlds/haxima-1.001/images/dgervais/dg_commodities-32x32.png, worlds/haxima-1.001/images/dgervais/dg_readable-32x32.png, worlds/haxima-1.001/images/dgervais/dg_tools-32x32.png, worlds/haxima-1.001/images/dgervais/dg_weapons-32x32.png: + Various reorganizations, etc. + + * worlds/haxima-1.001/images/dgervais/dg_potions-32x32.png: + Fixed a draggo. + + * worlds/haxima-1.001/images/dgervais/dg_weapons-32x32.png: + Added a blank tile for the "magic mace with red glow" animation frame. + +2004-08-01 Gordon McNutt + + * src/Arms.cpp, src/character.cpp, src/cmd.c, src/combat.c, src/ctrl.c, src/magic.c, src/magic.h, src/player.cpp, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/spells.scm, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.console.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.console.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/console-at.save.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-attack.save.mstr, worlds/haxima-1.001/tests/console-board.cmdwin.mstr, worlds/haxima-1.001/tests/console-board.console.mstr, worlds/haxima-1.001/tests/console-board.rec, worlds/haxima-1.001/tests/console-board.save.mstr, worlds/haxima-1.001/tests/console-board.scm, worlds/haxima-1.001/tests/console-examine.save.mstr, worlds/haxima-1.001/tests/console-exit.console.mstr, worlds/haxima-1.001/tests/console-exit.save.mstr, worlds/haxima-1.001/tests/console-party-attack.cmdwin.mstr, worlds/haxima-1.001/tests/console-party-attack.console.mstr, worlds/haxima-1.001/tests/console-party-attack.rec, worlds/haxima-1.001/tests/console-party-attack.save.mstr, worlds/haxima-1.001/tests/console-party-attack.scm, worlds/haxima-1.001/tests/console-pass.save.mstr, worlds/haxima-1.001/tests/console-terraform.save.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/mech-1.save.mstr, worlds/haxima-1.001/tests/mech-2.save.mstr, worlds/haxima-1.001/tests/session.scm, worlds/haxima-1.001/tests/tfeat-1.save.mstr, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-2.save.mstr: + Updated console messages on all party spells up through C)ast + + * src/log.h: + Adding missing file + +2004-07-31 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm: + Added a Sprite Gallery place, accessible via a portal + in the Terrain Test. + + * worlds/haxima-1.001/portals.scm: + Revised some documentation. + Added a new portal type t_perm_gate and a constructor mk-perm-gate. + + * worlds/haxima-1.001/portals.scm: + Added documentation. + + * worlds/haxima-1.001/portals.scm: + Indentation. + + * worlds/haxima-1.001/sprite-sets.scm: + Added ss_dg_missiles. + + * worlds/haxima-1.001/sprites.scm: + Temporarily changed multi-facing missiles to multi-frame, + so that the graphics can be seen in context in the sprite gallery. + + * worlds/haxima-1.001/images/dgervais/dg_commodities-32x32.png, worlds/haxima-1.001/images/dgervais/dg_missiles-32x32.png, worlds/haxima-1.001/images/dgervais/dg_potions-32x32.png, worlds/haxima-1.001/images/dgervais/dg_readable-32x32.png, worlds/haxima-1.001/images/dgervais/dg_tools-32x32.png, worlds/haxima-1.001/images/dgervais/dg_weapons-32x32.png: + Adding various tilesheets (tiles courtesy of David Gervais). + + * worlds/haxima-1.001/images/dgervais/dg_missiles-32x32.png: + Re-arranged the arrows slightly. + + * worlds/haxima-1.001/images/dgervais/dg_missiles-32x32.png: + Re-organized, added animation frames. + +2004-07-31 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/character.cpp, src/cmd.c, src/cmdwin.c, src/ctrl.c, src/log.c, src/nazghul.c, src/object.c, src/place.c, src/player.cpp, src/sky.h, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/tests/cmdwin-1.cmdwin.mstr, worlds/haxima-1.001/tests/cmdwin-1.console.mstr, worlds/haxima-1.001/tests/cmdwin-2.cmdwin.mstr, worlds/haxima-1.001/tests/cmdwin-2.console.mstr, worlds/haxima-1.001/tests/cmdwin-3.cmdwin.mstr, worlds/haxima-1.001/tests/cmdwin-3.console.mstr, worlds/haxima-1.001/tests/console-at.cmdwin.mstr, worlds/haxima-1.001/tests/console-at.console.mstr, worlds/haxima-1.001/tests/console-at.rec, worlds/haxima-1.001/tests/console-at.save.mstr, worlds/haxima-1.001/tests/console-at.scm, worlds/haxima-1.001/tests/console-attack.cmdwin.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-attack.rec, worlds/haxima-1.001/tests/console-attack.save.mstr, worlds/haxima-1.001/tests/console-attack.scm, worlds/haxima-1.001/tests/console-attack.scm.cmdwin.mstr, worlds/haxima-1.001/tests/console-attack.scm.console.mstr, worlds/haxima-1.001/tests/console-attack.scm.rec, worlds/haxima-1.001/tests/console-examine.cmdwin.mstr, worlds/haxima-1.001/tests/console-examine.console.mstr, worlds/haxima-1.001/tests/console-examine.rec, worlds/haxima-1.001/tests/console-examine.save.mstr, worlds/haxima-1.001/tests/console-examine.scm, worlds/haxima-1.001/tests/console-exit.cmdwin.mstr, worlds/haxima-1.001/tests/console-exit.console.mstr, worlds/haxima-1.001/tests/console-exit.rec, worlds/haxima-1.001/tests/console-exit.save.mstr, worlds/haxima-1.001/tests/console-exit.scm, worlds/haxima-1.001/tests/console-pass.cmdwin.mstr, worlds/haxima-1.001/tests/console-pass.console.mstr, worlds/haxima-1.001/tests/console-pass.rec, worlds/haxima-1.001/tests/console-pass.save.mstr, worlds/haxima-1.001/tests/console-pass.scm, worlds/haxima-1.001/tests/console-terraform.cmdwin.mstr, worlds/haxima-1.001/tests/console-terraform.console.mstr, worlds/haxima-1.001/tests/console-terraform.rec, worlds/haxima-1.001/tests/console-terraform.save.mstr, worlds/haxima-1.001/tests/console-terraform.scm, worlds/haxima-1.001/tests/console-terraform.scm.cmdwin.mstr, worlds/haxima-1.001/tests/console-terraform.scm.console.mstr, worlds/haxima-1.001/tests/console-terraform.scm.rec, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/mech-1.console.mstr, worlds/haxima-1.001/tests/mech-2.console.mstr, worlds/haxima-1.001/tests/runall, worlds/haxima-1.001/tests/testexec, worlds/haxima-1.001/tests/tfeat-1.console.mstr, worlds/haxima-1.001/tests/wrap-1.cmdwin.mstr, worlds/haxima-1.001/tests/wrap-1.console.mstr, worlds/haxima-1.001/tests/wrap-2.cmdwin.mstr, worlds/haxima-1.001/tests/wrap-2.console.mstr: + Console rework started + + * src/cmd.c, src/console.c, src/log.c, src/play.c, src/player.cpp, worlds/haxima-1.001/tests/cmdwin-1.console.mstr, worlds/haxima-1.001/tests/cmdwin-2.console.mstr, worlds/haxima-1.001/tests/cmdwin-3.console.mstr, worlds/haxima-1.001/tests/console-at.console.mstr, worlds/haxima-1.001/tests/console-attack.console.mstr, worlds/haxima-1.001/tests/console-examine.console.mstr, worlds/haxima-1.001/tests/console-exit.console.mstr, worlds/haxima-1.001/tests/console-pass.console.mstr, worlds/haxima-1.001/tests/console-terraform.console.mstr, worlds/haxima-1.001/tests/mech-1.console.mstr, worlds/haxima-1.001/tests/mech-2.console.mstr, worlds/haxima-1.001/tests/tfeat-1.console.mstr, worlds/haxima-1.001/tests/wrap-1.console.mstr, worlds/haxima-1.001/tests/wrap-2.console.mstr: + o Cleaned up entrance messages + o Cleaned up saving/reloading messages in party mode + +2004-07-30 Gordon McNutt + + * worlds/haxima-1.001/stone-lantern.scm: + Added a missing file + +2004-07-29 Sam Glasby + + * worlds/haxima-1.001/sprite-sets.scm: + Added ss_dg_wearable tilesheet. + + * worlds/haxima-1.001/images/dgervais/dg_angband_enhanced-32x32.png: + Added the David Gervais enhanced 32x32 Angband tileset. + + * worlds/haxima-1.001/images/dgervais/dg_wearable_items-32x32.png: + A tile sheet containing tiles for wearable items: + - Hats, helms, crown + - Amulets + - Rings + - Cloaks + - Robes + - Shields + - Armor (leather, chain, plate) + +2004-07-28 Sam Glasby + + * worlds/haxima-1.001/P_terrain_test.scm: + Terrain test pattern for screenshots, etc. + + * worlds/haxima-1.001/P_terrain_test.scm, worlds/haxima-1.001/session.scm: + Added the Terrain Test place, preparatory for terrain/palette work. + + * worlds/haxima-1.001/sprites.scm: + Added sprites from ss_kg_terrain and ss_kg_roads. + Fixed some typos. + +2004-07-28 Gordon McNutt + + * worlds/Makefile.am: + Adding missing file + +2004-07-27 Gordon McNutt + + * src/astar.c, src/astar.h, src/ctrl.c, src/place.c, src/player.cpp: + o Fixed one bug related to death-in-ship-by-cannon. + + o Worked around another bug hiding behind it. I didn't root cause it, and + suspect it's related to double-deallocation or overwriting an allocated + buffer, because it asserts in malloc(). But I don't see any immediate cause + and don't want to spend a lot of time on it at this point. + + * worlds/haxima-1.001/tests/cmdwin-1.console.mstr, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr: + Remastered some tests to reflect a change in a sprite name + +2004-07-26 Sam Glasby + + * src/cmd.c: + Fixed a SIGSEGV on invocation of cmdTerraform(). + I think we fixed this one before. It must not have made it to CVS. + + * src/common.h: + Removed a duplicate #define for PLACE_ID. + + * worlds/haxima-1.001/sprite-sets.scm: + Added the kgabbert/ roads and terrains sprite sheets. + Added formatting + comments. + + * worlds/haxima-1.001/sprites.scm: + Updated formatting, added comments. + Merged with Gordon's new feature tiles and bridge re-labeling. + + * worlds/haxima-1.001/images/kgabbert/Attic/new_roads..png: + This should have been checked in as new_roads.png + but it was checked in as new_roads..png + which is one too many dots. + + * worlds/haxima-1.001/images/kgabbert/Attic/new_roads..png, worlds/haxima-1.001/images/kgabbert/new_terrains.png: + Added the new roads and terrains tile sheets. + + * worlds/haxima-1.001/images/kgabbert/new_roads.png: + Aarrgghh.... Checked this file in as new_roads..png + which is one too many dots. + +2004-07-25 Sam Glasby + + * worlds/haxima-1.001/images/gmcnutt/frame_pieces.16x16.plain_blue_bars.png: + Added the reorganized frames tile sheet. + +2004-07-25 Gordon McNutt + + * worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/gmcnutt/features.png: + Added a new hut sprite + + * worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/images/gmcnutt/features.png: + Added a mine and cave entrance sprite + +2004-07-24 Gordon McNutt + + * BUGS, COPYING, INSTALL, Makefile.am, Attic/Makefile.in, Attic/RELEASE_NOTES, Attic/configure, Attic/configure.in, doc/USERS_GUIDE, examples/Makefile.in, scripts/RELEASE_CHECKOFF, src/clock.c, src/cmd.c, src/Attic/game.h, src/play.c, src/sky.c: + Various fixups to make the release work + + * Attic/RELEASE_NOTES, src/object.h, src/place.c, src/place.h, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/palette.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/terrains.scm, worlds/haxima-1.001/tests/cmdwin-1.console.mstr, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/session.scm, worlds/haxima-1.001/tests/tfeat-1.cmdwin.mstr, worlds/haxima-1.001/tests/tfeat-1.console.mstr, worlds/haxima-1.001/tests/tfeat-1.rec, worlds/haxima-1.001/tests/tfeat-1.save.mstr, worlds/haxima-1.001/tests/tfeat-1.scm, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-1.scm: + o Added a layer for terrain features + + o Modified passability, movement cost and terrain effects to check for terrain + features. Terrain features always override terrain movement and hazard + effects. + + o Updated the scripts accordingly, added a bridge terrain feature as an + example. One may be found in Gregor's hut. + + o Added a test for terrain feature passability and hazard overrides. + + * src/character.cpp, src/ctrl.c, src/player.cpp: + Some initial console/cmdwin cleanup + + * src/cmd.c, src/map.c, worlds/haxima-1.001/bim.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/lever.scm, worlds/haxima-1.001/objs.scm, worlds/haxima-1.001/palette.scm, worlds/haxima-1.001/portcullis.scm, worlds/haxima-1.001/sprite-sets.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/terrains.scm, worlds/haxima-1.001/images/gmcnutt/features.png, worlds/haxima-1.001/tests/basic-night-time.scm, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/mech-1.cmdwin.mstr, worlds/haxima-1.001/tests/mech-1.console.mstr, worlds/haxima-1.001/tests/mech-1.rec, worlds/haxima-1.001/tests/mech-1.save.mstr, worlds/haxima-1.001/tests/mech-1.scm, worlds/haxima-1.001/tests/mech-1.scm.cmdwin.mstr, worlds/haxima-1.001/tests/mech-1.scm.console.mstr, worlds/haxima-1.001/tests/mech-1.scm.rec, worlds/haxima-1.001/tests/mech-1.scm.save.mstr, worlds/haxima-1.001/tests/mech-2.cmdwin.mstr, worlds/haxima-1.001/tests/mech-2.console.mstr, worlds/haxima-1.001/tests/mech-2.rec, worlds/haxima-1.001/tests/mech-2.save.mstr, worlds/haxima-1.001/tests/mech-2.scm, worlds/haxima-1.001/tests/tfeat-1.console.mstr, worlds/haxima-1.001/tests/tfeat-1.save.mstr: + o Modified bim.scm to expect a light value as part of the gob state for a + binary mechanism. + o Added stone-lantern.scm, our first new light-switch-style mechanism. + o I think there was a kernel bugfix in here but I forgot what it was. + + * worlds/Attic/Makefile.in: + *** empty log message *** + + * worlds/haxima-1.001/bridge.scm: + Forgot to add the new bridge file in my last checkin + + * worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/road.scm, worlds/haxima-1.001/session.scm: + Added road.scm, which includes a feature map translation function as an example of how to do that sort of thing + + * worlds/haxima-1.001/session.scm, worlds/haxima-1.001/Attic/test.scm: + Cleanup + + * worlds/haxima-1.001/tests/basic-party.scm, worlds/haxima-1.001/tests/basic-time.scm, worlds/haxima-1.001/tests/basic-wilderness-map.scm, worlds/haxima-1.001/tests/cmdwin-2.cmdwin.mstr, worlds/haxima-1.001/tests/cmdwin-2.console.mstr, worlds/haxima-1.001/tests/wrap-1.cmdwin.mstr, worlds/haxima-1.001/tests/wrap-1.console.mstr, worlds/haxima-1.001/tests/wrap-2.cmdwin.mstr, worlds/haxima-1.001/tests/wrap-2.console.mstr: + Updated some test files + +2004-07-23 Gordon McNutt + + * worlds/haxima-1.001/images/gmcnutt/features.png, worlds/haxima-1.001/images/gmcnutt/features2.png: + Added two more image sheets + +2004-07-20 Gordon McNutt + + * src/cmdwin.c, src/cmdwin.h, src/ctrl.c, src/player.cpp: + o Added a cmdwin log, .cmdwin, for regression testing. + + o Added cmdwin_flush() which writes to the cmdwin log, writes to the console, + clears the cmdwin and repaints it for another prompt. + + o Top of player party key handle uses cmdwin_flush() now. + + * src/common.h, src/screen.c, src/session.c: + Removed (faulty) timestamp from save files + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/objs.scm, worlds/haxima-1.001/palette.scm, worlds/haxima-1.001/sprite-sets.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/terrains.scm: + Filled out a bit more of Gregor's hut + + * worlds/haxima-1.001/tests/DESCRIPTIONS.TXT, worlds/haxima-1.001/tests/clean, worlds/haxima-1.001/tests/cmdwin-1.cmdwin.mstr, worlds/haxima-1.001/tests/cmdwin-1.console.mstr, worlds/haxima-1.001/tests/cmdwin-1.rec, worlds/haxima-1.001/tests/cmdwin-1.save.mstr, worlds/haxima-1.001/tests/cmdwin-1.scm, worlds/haxima-1.001/tests/cmdwin-2.cmdwin.mstr, worlds/haxima-1.001/tests/cmdwin-2.console.mstr, worlds/haxima-1.001/tests/cmdwin-2.rec, worlds/haxima-1.001/tests/cmdwin-2.save.mstr, worlds/haxima-1.001/tests/cmdwin-2.scm, worlds/haxima-1.001/tests/cmdwin-3.cmdwin.mstr, worlds/haxima-1.001/tests/cmdwin-3.console.mstr, worlds/haxima-1.001/tests/cmdwin-3.rec, worlds/haxima-1.001/tests/cmdwin-3.save.mstr, worlds/haxima-1.001/tests/cmdwin-3.scm, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/master, worlds/haxima-1.001/tests/remaster, worlds/haxima-1.001/tests/runall, worlds/haxima-1.001/tests/testexec, worlds/haxima-1.001/tests/wrap-1.rec, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-1.scm, worlds/haxima-1.001/tests/wrap-2.scm: + Added some cmdwin tests + + * worlds/haxima-1.001/tests/clean, worlds/haxima-1.001/tests/list, worlds/haxima-1.001/tests/master, worlds/haxima-1.001/tests/remaster, worlds/haxima-1.001/tests/testexec, worlds/haxima-1.001/tests/wrap-1.rec, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-1.scm, worlds/haxima-1.001/tests/wrap-2.rec, worlds/haxima-1.001/tests/wrap-2.save.mstr, worlds/haxima-1.001/tests/wrap-2.scm: + Adding regression test framework + + * worlds/haxima-1.001/tests/session.scm: + Made a copy of session.scm to insulate regression tests from world changes + + * worlds/haxima-1.001/tests/testexec, worlds/haxima-1.001/tests/wrap-1.save.mstr, worlds/haxima-1.001/tests/wrap-2.save.mstr: + Removed timestamps from master files; reduced playback delay + +2004-07-15 Gordon McNutt + + * src/cmd.c: + Refixed the terraform bug + + * src/map.c, src/place.c, src/screen.c: + o Bugfix: when zoomed out in a small-scale place, the selected character's + sprite would sometimes flash full-size at some place on the screen. This was + a bug in mapUpdateTile(), which didn't handle zoom-out properly. + + o Bugfix: when zoomed out and standing at the edge of a small-scale, + non-wrapping place the highlight box was painted wrong. Again, a bug (this + time in screenHighlight()) where the code was not written to handle zoom-out + properly. + + * src/place.c: + Bugfix: couldn't board a ship + + * worlds/haxima-1.001/gregors-hut.scm, worlds/haxima-1.001/session.scm: + Added initial hack at Gregor the Charcoal Burner's Hut + +2004-07-14 Gordon McNutt + + * src/character.cpp, src/kern.c, src/object.c, src/object.h, src/place.c, src/place.h, src/player.cpp, src/scheme.c, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/objs.scm, worlds/haxima-1.001/portals.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/yellow-slime.scm: + o Places now take an optional closure which is run when the party tries to + enter them as a subplace. As an example, I added one to GreenTower which + prompts the player if he wants to enter or not. + + o Fixed several bugs in the code which distributes party members. This was + visible if you tried to enter a place that didn't have any safe locations. + + o Not sure if I changed any kernel code for this, but I added an example of a + portal that prompts the player when he tries to step through. The prompt + occurs after the player is on the portal, which is not exactly what we + want. The example prompts and rechecks to make sure the player really wants + to step through the portal. If he says no he'll end up on top of the portal + without teleporting. + +2004-07-13 Gordon McNutt + + * src/Field.cpp, src/Field.h, src/Party.cpp, src/character.cpp, src/kern.c, src/object.c, src/object.h, src/place.c, src/place.h, src/player.cpp, src/terrain.c, src/terrain.h, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/fields.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/ifc.scm: + o Attempting to enter impassable but hazardous terrain now applies the + hazard. For example, attempting to enter lava (impassable to most) will burn + you. This reuses the existing terrain "effect" which is applied when a + terrain is stepped on. I could have added another effect just for this + feature, but for all the realistic terrains I can think of the effects of + entering and failing to enter would be the same, so until an important + counterexample surfaces I'll not pollute my data structures with more NULL + pointers. + + o Attempting to enter a tile with a blocking but dangerous object will apply + damage. For example, attempting to enter an energy field will shock you. This + uses a new well-known signal called "bump", as in you bumped into something + that didn't give way. The optional bump handler is in the script for an + object. + +2004-07-12 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/closure.c, src/kern.c, src/mmode.c, src/mmode.h, src/object.c, src/object.h, src/place.c, src/place.h, src/player.cpp, src/player.h, src/ptable.c, src/ptable.h, src/session.c, src/session.h, src/species.c, src/species.h, src/status.c, src/terrain.c, src/terrain.h, src/vehicle.cpp, src/vehicle.h, worlds/haxima-1.001/bim.scm, worlds/haxima-1.001/door.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/portcullis.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/terrains.scm, worlds/haxima-1.001/vehicles.scm: + o Replaced pmasks with movement modes and passability classes. + +2004-07-10 Gordon McNutt + + * src/Party.cpp, src/character.cpp, src/cmd.c, src/combat.c, src/ctrl.c, src/kern.c, src/object.c, src/pinfo.h, src/place.c, src/place.h, src/player.cpp, src/terrain.c, src/terrain.h: + o Replaced pmask argument to place_is_passable with the object trying to pass. + o Removed pmask argument to place_find_path (object seeking a path is already + passed in). + + * src/closure.c, src/cmd.c, src/cmd.h, src/ctrl.c, src/event.h, src/kern.c, src/place.c, src/place.h, src/terrain.c, src/terrain.h: + o Modified closure_exec to return integers as well as bools from scripts calls. + o Removed all the old placeFoo() functions that used the global Place variable + internally. Replaced them as necessary with place_foo(), which takes the + place as an argument. + + * src/closure.c, src/combat.c, src/nazghul.c, src/place.c, src/terrain.c, src/terrain.h: + o Removed the obsolete 'effects' bitmask from terrains + o Corrected some places to use 'effect' instead of 'effects'; this fixes some + of the party-member-walking-on-campfire bugs Sam pointed out. + + * worlds/haxima-1.001/game.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/terrains.scm: + Changed some hard-coded numeric values for pmasks to symbols + + * worlds/haxima-1.001/game.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/sprite-sets.scm, worlds/haxima-1.001/images/dbailey/lost_dragon.png, worlds/haxima-1.001/images/dgervais/angband-32x32.png, worlds/haxima-1.001/images/gmcnutt/frame_pieces.png, worlds/haxima-1.001/images/gmcnutt/moons-16x16.png, worlds/haxima-1.001/images/jsteele/charset-8x16.png, worlds/haxima-1.001/images/jsteele/shapes-32x32.png, worlds/haxima-1.001/images/mixed/mine-32x32.png, worlds/haxima-1.001/images/sglasby/mechanisms.png, worlds/haxima-1.001/images/sglasby/rune_font_32x32.png, worlds/haxima-1.001/images/sglasby/rune_font_8x16.png: + Populated sound and image directories + +2004-07-09 Gordon McNutt + + * src/Arms.cpp, src/Arms.h, src/Container.cpp, src/Container.h, src/Field.cpp, src/Field.h, src/Attic/Item.cpp, src/Attic/Item.h, src/Attic/Loader.cpp, src/Attic/Loader.h, src/Makefile.am, src/Attic/Makefile.in, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Missile.cpp, src/Missile.h, src/Party.cpp, src/Party.h, src/Attic/Portal.cpp, src/Attic/Portal.h, src/Reagent.cpp, src/Reagent.h, src/Attic/Spell.cpp, src/Attic/Spell.h, src/Attic/Trap.cpp, src/Attic/Trap.h, src/ascii.c, src/ascii.h, src/astar.c, src/character.cpp, src/character.h, src/clock.c, src/clock.h, src/closure.c, src/closure.h, src/cmd.c, src/cmd.h, src/cmdwin.c, src/combat.c, src/combat.h, src/common.c, src/common.h, src/conv.c, src/conv.h, src/ctrl.c, src/ctrl.h, src/cursor.cpp, src/cursor.h, src/debug.c, src/debug.h, src/dice.c, src/dice.h, src/effect.c, src/effect.h, src/event.c, src/event.h, src/foogod.c, src/foogod.h, src/Attic/game.c, src/gob.c, src/gob.h, src/hash.c, src/images.c, src/images.h, src/kern.c, src/kern.h, src/Attic/lexer.c, src/Attic/lexer.h, src/list.h, src/macros.h, src/magic.c, src/magic.h, src/map.c, src/map.h, src/Attic/moongate.c, src/Attic/moongate.h, src/nazghul.c, src/object.c, src/object.h, src/occ.c, src/occ.h, src/olist.c, src/opdefines.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/player.h, src/Attic/portal.h, src/sched.c, src/sched.h, src/scheme-private.h, src/scheme.c, src/scheme.h, src/screen.c, src/screen.h, src/session.c, src/session.h, src/sky.c, src/sky.h, src/species.c, src/species.h, src/sprite.c, src/sprite.h, src/status.c, src/status.h, src/terrain.c, src/terrain.h, src/terrain_map.c, src/terrain_map.h, src/Attic/util.c, src/Attic/util.h, src/vehicle.cpp, src/vehicle.h, src/vmask.c, src/vmask.h, src/wind.c, src/wq.c, src/wq.h: + Merged from branch gmcnutt_scheme + + * worlds/haxima-1.001/arms.scm, worlds/haxima-1.001/bakup.scm, worlds/haxima-1.001/bim.scm, worlds/haxima-1.001/Attic/class-bak.scm, worlds/haxima-1.001/class.scm, worlds/haxima-1.001/conv.scm, worlds/haxima-1.001/door.scm, worlds/haxima-1.001/effects.scm, worlds/haxima-1.001/fields.scm, worlds/haxima-1.001/food.scm, worlds/haxima-1.001/game.scm, worlds/haxima-1.001/gen.scm, worlds/haxima-1.001/generic-mech.scm, worlds/haxima-1.001/ifc.scm, worlds/haxima-1.001/init.scm, worlds/haxima-1.001/items.scm, worlds/haxima-1.001/kobj.scm, worlds/haxima-1.001/lever.scm, worlds/haxima-1.001/loc.scm, worlds/haxima-1.001/monster-generator.scm, worlds/haxima-1.001/moon.scm, worlds/haxima-1.001/moongate.scm, worlds/haxima-1.001/naz.scm, worlds/haxima-1.001/objs.scm, worlds/haxima-1.001/occs.scm, worlds/haxima-1.001/palette.scm, worlds/haxima-1.001/parties.scm, worlds/haxima-1.001/Attic/player.scm, worlds/haxima-1.001/portals.scm, worlds/haxima-1.001/portcullis.scm, worlds/haxima-1.001/reagents.scm, worlds/haxima-1.001/sched.scm, worlds/haxima-1.001/search.scm, worlds/haxima-1.001/session.scm, worlds/haxima-1.001/shroom.scm, worlds/haxima-1.001/species.scm, worlds/haxima-1.001/spells.scm, worlds/haxima-1.001/sprite-sets.scm, worlds/haxima-1.001/sprites.scm, worlds/haxima-1.001/tblit.scm, worlds/haxima-1.001/terrains.scm, worlds/haxima-1.001/Attic/test.scm, worlds/haxima-1.001/vehicles.scm, worlds/haxima-1.001/yellow-slime.scm: + Added all the new scripts + + * worlds/haxima-1.001/sounds/cannon.wav, worlds/haxima-1.001/sounds/damage.wav, worlds/haxima-1.001/sounds/enter_moongate.wav, worlds/haxima-1.001/sounds/horse.wav, worlds/haxima-1.001/sounds/rowing.wav, worlds/haxima-1.001/sounds/walk.wav: + Populated sounds subdir + +2004-07-08 Gordon McNutt + + * src/cmd.c, src/cmd.h, src/conv.c, src/ctrl.c, src/event.h, src/kern.c, src/status.h: + o Implemented kern-ui-handle-events but changed my mind about using it so it + remains untested (and unavailable to the script). + o Added kern-obj-remove-from-inventory & kern-obj-add-to-inventory. + o Added kern-ui-page-text for displaying scrolls and books in the status window. + o Modified cmdUse to NOT automatically remove items from inventory after they + are used. Instead items now remove themselves if they are consumable. + +2004-07-07 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/character.cpp, src/cmd.c, src/conv.c, src/kern.c, src/nazghul.c, src/play.c, src/session.c: + o Tried to eliminate conv.[ch], but we still use a few things in there. Cleaned + it up quite a bit, though, deleting 700 lines of code. + + * src/Makefile.am, src/Attic/Makefile.in, src/conv.c, src/kern.c, src/Attic/lexer.c, src/Attic/lexer.h, src/nazghul.c, src/session.c, src/terrain.c: + o Eliminated lexer.[ch] + + * src/Makefile.am, src/Attic/Makefile.in, src/Party.cpp, src/cmd.c, src/hash.c, src/images.c, src/kern.c, src/nazghul.c, src/object.c, src/olist.c, src/place.c, src/play.c, src/session.c, src/terrain.c, src/terrain_map.c, src/Attic/util.c, src/Attic/util.h, src/wq.c: + o Modified the interpreter to fix the script->kernel->script recursion + issue. Limited testing so far, but no problems noted yet. + + * src/conv.c, src/kern.c: + o Modified kern_conv_say to take a list of messages. This way we can break up + long strings in the script if we want to for easier-to-read formatting. + o Modified the kernel to always truncate player queries to the first four + characters. Conversation scripts should expect this, and only use keywords of + one to four characters. Because keywords are signal names they must match + exactly between kernel and script. The user can type extra, of course, but + only the first four characters will be used to make the signal name. + +2004-07-06 Gordon McNutt + + * src/kern.c, src/opdefines.h, src/scheme.c, src/scheme.h: + o Modified the interpreter to fix the script->kernel->script recursion + issue. Limited testing so far, but no problems noted yet. + +2004-07-05 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/ctrl.c, src/ctrl.h, src/kern.c: + o Added kern-char-get-mana + o Added kern-char-dec-mana + o Added kern-obj-dec-ap + o Added kern-obj-wander + o Added kern-char-attack + o Added kern-get-distance + o Added kern-in-los? + o Modified characters to have an optional "ai" closure, which runs when they + are idle in automatic mode. The kern api calls which make characters + (including kern-mk-char, kern-mk-stock-char and kern-mk-party-type) all take + an additional parameter for the ai. + +2004-07-04 Gordon McNutt + + * src/character.cpp, src/character.h, src/cmd.c, src/cmd.h, src/ctrl.c, src/kern.c, src/object.c, src/object.h, src/scheme.c, src/species.c, src/species.h, src/status.c: + o Bugfix: needed to set the protection counter on sc->NIL, T and F to + zero. These special scheme cells are not obtained in the usual way, so + they're pref got out of synch and caused an assert when the invisibility + spell expired. + o Removed the startup closures from the kernel species struct and all related + code. These weren't working out with summoned creatures due to the SKS + recursion issue. Instead the equivalent thing is now done in the script. + +2004-07-03 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/character.cpp, src/effect.c, src/effect.h, src/gob.c, src/gob.h, src/kern.c, src/object.c, src/object.h: + o Bugfix: step on the sleep field then camp => crash in scheme. The problem is + using a NULL gob wrapper for NIL gobs (a recent change): if scheme needs to + run a garbage collection cycle with that NULL passed in as an arg it + crashes. The fix was to always use a non-NULL wrapper, even for NIL + gobs. Along with this I added ref-counting for gobs used in effects. The old + randomly-expiring protection spell showed that this is necessary for effects + applied to the entire party. + + o Bugfix: same steps to reproduce, once the above if fixed there was an assert + in Character::exec() because a resting character was not asleep as expected + (because the sleep effect wore off and woke him up). Fixed this by changing + Character::awaken() to not wake up resting characters. + + * src/clock.c, src/clock.h, src/cmd.c, src/kern.c, src/sky.c, src/sky.h: + o Put astronomy info back into the AT command. + o Added names for moon phases, now reported by AT. + + * src/effect.c, src/effect.h, src/kern.c, src/object.c, src/status.c: + o Added an optional "on-removal" procedure to effects so they can clean up + after themselves when they expire. + o Added a guard flag to prevent recursive status repaints + + * src/kern.c, src/map.c, src/nazghul.c, src/sky.c, src/vmask.c, src/vmask.h: + o Bugfix: option-parsing wasn't working with options passed-in. Not sure why, + though this used to work. Added another option_index separate from optind as + indicated by the example in the man page. + o Bugfix: strange LOS artifacts. This happened because the lightmap was + operating directly on the cached vmask, which should only be altered by + vmask_los(). The fix was to use a temporary lightmap buffer instead. + + * src/kern.c, src/object.c: + Bugfix: crash when "In Sanct" wears off the second party member. Problem was + double-deallocation of a kernel gob wrapper. Fixed this for this case by + getting rid of nil gobs. If it's common for a gob to be shared by an effect + applied to multiple party members then we'll need to add ref-counting to the + kernel gob wrapper. + +2004-07-02 Gordon McNutt + + * src/clock.h, src/effect.h, src/kern.c, src/object.c, src/object.h: + o Added a duration field to effects. duration <= 0 means "forever" + o Added an expiration alarm to the effect entry struct. When a new entry is + created, if the effect has a finite duration this alarm is set. When the alarm + expires the effect is automatically removed. + + * src/sprite.c: + o Bugfix: unmanned ship turns itself when hostile ship near. The cause of this + was an improper value for the "facing" when the vehicle was created. The + script was using 0, but it should have used a valid direction code like + "north". As a result, wheneve the ship with the bad facing tried to set the + srprite facing it silently failed, and thereby inherited the last valid + facing, which was set by the NPC ship underway. Added a debug warning in case + this ever happens again. + +2004-06-30 Gordon McNutt + + * src/character.cpp, src/combat.c, src/place.c, src/place.h, src/player.h: + o Finally fixed all the gate spell scenarios I can test with current scripts. + +2004-06-29 Gordon McNutt + + * src/combat.c, src/combat.h, src/player.cpp: + o Backing out recent changes. Need to try something else. + +2004-06-28 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Attic/Spell.cpp, src/Attic/Spell.h, src/character.cpp, src/combat.c, src/ctrl.c, src/kern.c, src/nazghul.c, src/play.c, src/session.c, src/status.c: + o Removed Spell.h & Spell.cpp + + * src/combat.c, src/combat.h, src/player.cpp: + o Removed combatAddParty + o Bugfix: wilderness combat cleans up properly now the player exits via a gate + spell (the shipboard case still handled improperly, though) + +2004-06-27 Gordon McNutt + + * src/Party.cpp, src/Attic/Spell.cpp, src/character.cpp, src/character.h, src/dice.c, src/kern.c: + o Bugfix: dice_valid should have checked for a null format pointer + o Bugfix: character destructor needed to remove char from party + o Bugfix: Party::createMembers() needed to use addMember() to inc ref count + o Added kern-char-kill + o Added kern-char-resurrect + o Added kern-obj-clone + + * src/kern.c, src/object.c, src/place.c, src/sky.c, src/sky.h: + o Bugfix: putOnMap was not using the "no-step-signal" flag when calling + relocate(), causing some mild moongate recursion. + + * src/kern.c, src/map.c: + o Added kern-map-set-peering + o Added kern-ui-waitkey + + * src/kern.c: + o Added kern-place-get-width + o Added kern-place-get-height + + * src/place.c, src/player.cpp, src/player.h: + o Bugfixes for time stop. + +2004-06-26 Gordon McNutt + + * src/character.cpp, src/common.c, src/kern.c: + o Added kern-char-is-asleep? + o Added kern-map-set-jitter (for tremor/earthquake effects) + + * src/kern.c: + o Added kern-char-set-alignment + +2004-06-25 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/character.cpp, src/cmd.c, src/gob.c, src/gob.h, src/kern.c, src/object.c, src/object.h, src/scheme-private.h, src/scheme.c: + o Added kern-add-xray-vision + o Added a "reveal all" status character to the foogod window + o Bugfix: foogod wasn't updating status for "quicken" & friends in a timely + manner. + o Added gobs to effects + +2004-06-23 Gordon McNutt + + * src/cmd.c, src/foogod.c, src/kern.c, src/map.c, src/play.c, src/session.c, src/session.h: + o Added kern-add-xray-vision + o Added a "reveal all" status character to the foogod window + o Bugfix: foogod wasn't updating status for "quicken" & friends in a timely + manner. + + * src/dice.c, src/kern.c: + o Added kern-char-is-hostile + o Bugfix: dice_parse missing a 'break' statement in a switch, caused an assert + on some valid dice expressions like "2d20+20" + +2004-06-22 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/closure.c, src/kern.c, src/object.c, src/object.h: + o Added kern-char-get-party + o Added kern-char-add-defense to change the defense bonus by an integral amount + + * src/Attic/Spell.cpp, src/common.c, src/common.h, src/foogod.c, src/kern.c, src/magic.h, src/object.c, src/play.c, src/player.cpp, src/session.c, src/session.h: + o Moved the old global Reveal, Quicken, TimeStop and MagicNegated flags into + the session structure so they can be more conveniently saved/loaded + o Added kern-add-reveal, kern-add-quicken, kern-add-time-stop and + kern-add-magic-negated + +2004-06-21 Gordon McNutt + + * src/kern.c, src/place.c: + o Modified kern-mk-place to expect a list of neighboring places. Currently only + above and below places are supported. + o Added kern-place-get-neighbor to lookup the neighboring place in a given + direction + +2004-06-20 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/kern.c, src/object.c, src/object.h, src/species.c, src/species.h: + o Modified kern-mk-arms-type to use the same gifc solution as + kern-mk-obj-type. It now expects a gifc cap as well as the gifc. + o Modified kern-fire-missile to check the missile for an 'exec' handler and to + run it on the target when it scores a hit + o Bugfix: status not being reflected immediately when an effect takes hold; was + waiting for next animation cycle. + o species now have a list of startup procedures + o Modified Character::start() to run all the species startup closures on the + character + + * src/foogod.c, src/kern.c, src/wind.c: + o Added kern-set-wind to set the wind direction and minimal duration + o Added kern-ui-direction to prompt the player for a direction + o Bugfix: ship's hull hp not being painted in the correct place + +2004-06-19 Gordon McNutt + + * src/Party.cpp, src/character.cpp, src/kern.c: + o Added kern-mk-stock-char + o Added kern-place-is-passable + o Bugfix: if a character had a null tag in the script, it's kernel object tag + was not initialized, sometimes causing a crash on the subsequent save. + o Bugfix: if a character did not have an occupation the game would crash while + saving the character. + o Bugfix: npc parties were being saved with random alignment, causing them to + appear non-hostile on reload. + o Bugfix: the speed for ship types was not being loaded properly. This caused + the infinite loop when the npc ship attacks the player with cannons. + + * src/character.cpp, src/kern.c, src/object.c, src/object.h, src/place.c, src/place.h: + o Added kern-obj-set-temporary + o Added Object::setTemporary() and Object::isTemporary() + o Added place_exit() which destroys all temporary objects in the place + o Modified Character::groupExitTo() to call place_exit() as the party leaves a + place + +2004-06-18 Gordon McNutt + + * src/kern.c: + o Added kern-place-get-objects to return a list of all objects in a place. + o Added kern-char-set-fleeing to make a character flee from combat. + o Added kern-char-get-species to return the species of a character. + +2004-06-15 Gordon McNutt + + * src/Party.cpp, src/Attic/Spell.cpp, src/character.cpp, src/character.h, src/effect.c, src/effect.h, src/kern.c, src/object.c, src/object.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/session.c, src/session.h: + o Added a "start" method for places, Objects and effects. The specific purpose + was so that the luminance effect imparted by "In Lor" would properly + initialize the effected object's luminosity at start-of-session. I expect the + support added will come in handy for other things as well later on. + + * src/kern.c, src/place.c, src/place.h: + o Added kern-obj-is-char? to test if an object is a character + o Added kern-get-objects-at to return a list of objects at a location + o Added kern-obj-heal to heal hit points + o These new calls allowed me to implement a "Mani" spell which targets party + members from a list in the wilderness and characters on a tile in town + +2004-06-08 Gordon McNutt + + * src/Arms.cpp, src/Missile.cpp, src/Missile.h, src/kern.c, src/object.c: + o Added kern-ui-target and kern-fire-missile to support the Grav Por (magic + missile) spell. + + * src/effect.h, src/kern.c, src/object.c: + o Added a cumulative flag to the effects structure. Only cumulative effects may + be attached more than once to an object. + +2004-06-07 Gordon McNutt + + * src/Field.cpp, src/Field.h, src/magic.c, src/object.c: + o A duration of < 0 on the field type makes it permanent + o Bugfix in spell tree + o An Zu now works + +2004-06-06 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/closure.c, src/effect.c, src/effect.h, src/kern.c, src/macros.h, src/object.c, src/object.h, src/scheme-private.h, src/scheme.c, src/session.c: + o Changed effects, fixed some nasty bugs and some minor ones. + + * src/effect.c: + file effect.c was initially added on branch gmcnutt_scheme. + + * src/effect.h: + file effect.h was initially added on branch gmcnutt_scheme. + +2004-06-03 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Attic/Spell.cpp, src/Attic/Spell.h, src/cmd.c, src/kern.c, src/magic.c, src/magic.h, src/object.c, src/session.c, src/session.h: + o Added kern-set-magic-words + + o Added kern-add-spell + + o Added files magic.[ch]. These will replace Spell.[hcpp] which is being phased + out. + + o Moved spell words and spell tree out of Spell.h/Spell.cpp into the new + magic.h/magic.c + + o At this point I can mix an "An Nox" but I can't cast it yet. + + * src/Party.cpp, src/Party.h, src/Attic/Spell.cpp, src/character.cpp, src/character.h, src/cmd.c, src/conv.c, src/kern.c, src/object.c, src/object.h, src/player.cpp, src/player.h: + o Removed all traces of the old poison effect from the kernel. + + * src/Attic/Spell.cpp, src/character.cpp, src/cmd.c, src/common.h, src/ctrl.c, src/kern.c, src/magic.c, src/magic.h, src/object.c, src/object.h, src/player.cpp, src/species.c, src/species.h: + o Added more fields to the spell structure so that I can reuse more of the + existing kernel code related to spellcasting. + + o The "an nox" test spell now works. + + * src/magic.c: + file magic.c was initially added on branch gmcnutt_scheme. + + * src/magic.h: + file magic.h was initially added on branch gmcnutt_scheme. + +2004-06-02 Gordon McNutt + + * src/Party.cpp, src/Attic/Spell.cpp, src/cmd.c, src/combat.c, src/ctrl.c, src/player.cpp, src/player.h: + o Fixed the crash when sinking an NPC ship. + + o Fixed wilderness combat to always exit back to the player party's location + (found a case where it exited to the NPC party location, which I don't want + to allow). + +2004-05-31 Gordon McNutt + + * src/Field.cpp, src/kern.c, src/place.c, src/player.cpp, src/vehicle.cpp, src/vehicle.h: + o Added vehicles (wilderness only). Tested with a ship. Cannons not working + yet. + + * src/Party.cpp, src/Party.h, src/kern.c, src/session.c: + o Fixed the bug that crashed when firing a cannon. + + o Added support for NPC's in ships (it crashes when you sink them with you + cannon's, though) + +2004-05-30 Gordon McNutt + + * src/character.cpp, src/character.h, src/closure.c, src/cursor.cpp, src/cursor.h, src/kern.c, src/object.c, src/object.h, src/place.c, src/place.h, src/player.h, src/wq.c: + o Moongates now show their closing/operning animations when the player steps + through. + + * src/character.cpp, src/kern.c, src/map.c, src/map.h, src/sky.c, src/sky.h: + o Tweaked the map viewer to recenter on character's off-screen in round-robin + mode. Could still use a few more enhancements, but somewhat better now. + + * src/ctrl.c, src/event.c, src/kern.c, src/play.c, src/session.c, src/terrain_map.c, src/terrain_map.h, src/wq.c: + o Fixed a very worrisome bug related to memory corruption. + +2004-05-29 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Party.cpp, src/Party.h, src/clock.c, src/cmd.c, src/kern.c, src/nazghul.c, src/place.c, src/play.c, src/player.cpp, src/session.c, src/sky.c, src/sky.h: + o Astronomy partly working. Got a sun up. Not saving yet. + + * src/kern.c, src/sky.c, src/sky.h: + o Added a distance to astral bodies to make the rendering order always + correct. So now the moons always pass before the sun, etc. + + * src/kern.c, src/map.c, src/nazghul.c, src/play.c, src/player.cpp, src/session.c, src/session.h, src/sky.c, src/sky.h: + o Sky now associated with the session so it can save/load. + +2004-05-28 Gordon McNutt + + * src/play.c, src/sky.c, src/sky.h: + More preliminary changes to astronomy. + + * src/sky.c: + o Started in on the astronomy system. Half-torn apart right now but I need to + switch machines so I'm checking in. + +2004-05-27 Gordon McNutt + + * src/cmd.c, src/kern.c, src/wq.c, src/wq.h: + o Added most of the support needed for rudimentary moongates. + + * src/gob.c: + file gob.c was initially added on branch gmcnutt_scheme. + + * src/gob.c, src/gob.h: + Added missing files. + + * src/gob.h: + file gob.h was initially added on branch gmcnutt_scheme. + + * src/place.c: + o Bugfix: infrequent crash caused by not locking a tile in + place_for_each_tile(). + +2004-05-26 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/Attic/Portal.cpp, src/Attic/Portal.h, src/Attic/Spell.cpp, src/character.cpp, src/character.h, src/ctrl.c, src/cursor.cpp, src/cursor.h, src/kern.c, src/object.c, src/object.h, src/place.c, src/player.cpp, src/player.h: + o Implemented portals as mechs. Tested on a ladder and a trap door. + +2004-05-25 Gordon McNutt + + * src/Container.cpp, src/character.cpp, src/object.h, src/place.c, src/place.h, src/session.c, src/session.h, src/terrain_map.c, src/terrain_map.h: + o Bugfix: saving twice without an intervening reload was hitting an assert. + +2004-05-24 Gordon McNutt + + * src/character.cpp, src/character.h, src/cmd.c, src/cmd.h, src/conv.c, src/conv.h, src/ctrl.c, src/kern.c, src/object.c, src/object.h, src/player.cpp, src/session.c, src/status.h: + o Fixed a few things to support character gobs. + +2004-05-23 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Party.cpp, src/Attic/Spell.cpp, src/character.cpp, src/clock.c, src/cmd.c, src/combat.c, src/conv.c, src/conv.h, src/ctrl.c, src/kern.c, src/object.c, src/object.h, src/place.c, src/play.c, src/player.cpp, src/session.c, src/sky.c: + o Removed the Mech C++ class. No longer needed now that mechs are completely + implemented in the script. + + * src/Party.cpp, src/character.cpp, src/character.h, src/cmd.c, src/common.h, src/ctrl.c, src/kern.c, src/occ.c, src/occ.h, src/sched.c, src/sched.h, src/session.c: + o Added character schedules. + + * src/character.cpp, src/character.h, src/kern.c, src/object.c, src/object.h, src/place.c: + o Added support for terrain-blitting mechs. + +2004-05-22 Gordon McNutt + + * src/cmd.c, src/kern.c, src/object.c, src/object.h, src/scheme.c, src/session.c, src/session.h: + o Added support for connecting mechs. Tested with basic + lever-and-portculis. Saving them works, too. + + * src/kern.c, src/session.c, src/session.h: + o Eliminated kern-connect (no longer necessary with saved tags) + + * src/scheme.c: + o Symbols now saved; might make "kern-connect" obsolete. + +2004-05-21 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/closure.c, src/cmd.c, src/kern.c, src/object.c, src/object.h, src/scheme.c, src/scheme.h: + o Added gob.c and gob.h to encapsulate gobs. Gobs now stored in a struct with + their corresponding scheme pointer. Automatically protected/unprotected on + creation/deletion, and they appear to correctly save + themselves and reinitialize their kernel objects on load. + + * src/debug.c, src/kern.c, src/object.c, src/object.h, src/session.c: + o Cleaned up kobj initialization by adding a procedure to bind kobjs to gobs. + +2004-05-20 Gordon McNutt + + * src/character.cpp, src/cmd.c, src/ctrl.c, src/kern.c, src/map.c, src/object.c, src/object.h, src/place.c, src/scheme-private.h, src/scheme.c, src/scheme.h: + o Got enough support in to make a door mech work. Saving them doesn't work yet. + +2004-05-19 Gordon McNutt + + * src/closure.c, src/closure.h, src/cmd.c, src/kern.c, src/object.c, src/object.h, src/scheme.c, src/scheme.h: + o Implemented support for ghulscript-interfaces (gifcs), which are bound to + kernel ObjectTypes. This has been tested with the existing types, excluding + ArmsTypes. + + o Added support for ghulscript-objects (gobs), which are bounded to kernel + Objects. Not tested yet. + +2004-05-17 Gordon McNutt + + * src/closure.c, src/kern.c, src/object.c, src/object.h: + o Added a monster-generator but now what I've been waiting for has come to + pass: the interpreter appears to be gc'ing a pointer referenced by the + kernel. Not immediately obvious why. Probably have to dig into the gc code. + + * src/closure.c, src/closure.h, src/kern.c: + o Closures can now be either symbolic or raw procedures. Object type handlers + are now of the latter type since they never need to be saved. + + * src/kern.c, src/object.c, src/object.h: + o Added an exec-handler to the ObjectType class. + +2004-05-16 Gordon McNutt + + * src/Container.cpp, src/Container.h, src/character.cpp, src/character.h, src/cmd.c, src/conv.c, src/kern.c, src/object.c, src/object.h, src/occ.h, src/player.cpp, src/player.h, src/species.h: + o Pulled some of the Container methods (add, takeOut) and one of the Character + methods (addFood) up to the Object base class. Now, kern-obj-put-into and + kern-obj-add-food are safe on any object type. + + * src/Container.cpp, src/Container.h, src/character.cpp, src/character.h, src/cmd.c, src/conv.c, src/kern.c, src/object.c, src/object.h, src/player.cpp, src/player.h, src/status.c: + o Pulled use_handler up from ItemType to base ObjectType (next step will be to + get rid of ItemType) + + o Changed the player_party inventory from a bare linked list to a + Container. For some reason this was necessary to the previous step, but I've + lost track of why by now. + + o Changed status viewer code appropriately. + + o Enhanced Container class with new methods to make it "browsable" by the + status viewer. + + * src/Attic/Item.cpp, src/Attic/Item.h, src/Makefile.am, src/Attic/Makefile.in, src/character.cpp, src/cmd.c, src/conv.c, src/kern.c, src/play.c, src/player.cpp, src/player.h, src/session.c, src/status.c: + o Got rid of the ItemType subclass. + + o Bugfix: had to make the player_party's Container inventory be a pointer to + allow saving/loading using existing Container save/load code. + +2004-05-15 Gordon McNutt + + * src/Container.cpp, src/Attic/Loader.cpp, src/Attic/Loader.h, src/Attic/Makefile.in, src/Party.cpp, src/Reagent.cpp, src/character.cpp, src/character.h, src/conv.c, src/images.c, src/kern.c, src/object.c, src/sched.c, src/screen.c, src/session.c, src/sprite.c: + o Removed obsolete Loader class + + * src/Container.cpp, src/Container.h, src/character.cpp, src/closure.c, src/closure.h, src/cmd.c, src/kern.c, src/occ.c: + o Container traps now script procedures. + o Containers save themselves (including traps and contents) + o Added kern-mk-container + + * src/Makefile.am, src/Attic/Makefile.in, src/Attic/Trap.cpp, src/Attic/Trap.h, src/character.cpp, src/cmd.c, src/combat.c, src/kern.c, src/play.c, src/session.c: + o Removed obsolete Trap class + + * src/character.cpp, src/character.h, src/cmd.c, src/kern.c, src/object.c, src/object.h, src/player.cpp, src/player.h: + o Added a get-handler for all object types. + o Implemented food via the get-handler. + + * src/occ.h: + o Changed container traps to be script procedures. + o Containers now saved (including traps and contents) + o Added kern-mk-container to load saved containers + +2004-05-14 Gordon McNutt + + * src/Field.cpp, src/Missile.cpp, src/kern.c, src/object.c, src/occ.c, src/terrain.h: + o Bugfix: fields left by missiles (like flaming oil) did not have their initial + duration setup right + + o Added/debugged container types in occupations + + * src/kern.c: + o Bugfix: sleep sprites not properly setup in the species + + o Added new parm to kern-mk-terrain: the effect procedure (nil for none). This + replaces the original, ambiguous kern-attach-script as a way to create + effects for terrains. + + o Eliminated obsolete kern-attach-script + +2004-05-13 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/character.cpp, src/combat.c, src/kern.c, src/object.c: + o Changed kern-mk-party to kern-mk-party-type + o Added kern-mk-party + o A coupld of bugfixes related to NPC parties + + * src/character.cpp, src/character.h, src/kern.c: + + o Bugfix: when saving in combat character alignments were not getting saved, so + on reload the npc's would attack each other + + * src/combat.c, src/kern.c: + + o Added checks when positioning characters in combat to see if the terrain is + hazardous or if the tile contains a field. + +2004-05-12 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/kern.c: + Added kern-mk-party for prefab npc party types. + + * src/kern.c, src/object.c, src/object.h: + Bugfix: objects were not saving their count. + + Cleanup: removed obsolete kern-mk-wilderness-combat + +2004-05-10 Gordon McNutt + + * src/Arms.cpp, src/Arms.h, src/Makefile.am, src/Attic/Makefile.in, src/character.cpp, src/combat.c, src/common.c, src/common.h, src/ctrl.c, src/dice.c, src/dice.h, src/kern.c: + Added support for dice-roll notation in the script. Updated existing armament + type declarations to use it. + + * src/dice.c: + file dice.c was initially added on branch gmcnutt_scheme. + + * src/dice.h: + file dice.h was initially added on branch gmcnutt_scheme. + +2004-05-09 Gordon McNutt + + * src/Arms.cpp: + Bugfix: thrown weapon types not initialized properly, caused a crash when used. + + * src/Arms.cpp, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/cmd.c, src/kern.c, src/object.c, src/object.h, src/place.c, src/player.cpp, src/player.h: + Added a count parameter to kern-mk-obj. This allows you to make a batch of + objects with one call. The count is stored in the object itself, so it only + creates one object in memory, but that object represents a "pile" of objects of + the same type. (Note: this does not affect how objects are stored in inventory, + that will require more significant changes later). + + * src/kern.c: + Bugfix: natural weapons weren't being setup properly in the species structure. + +2004-05-02 Gordon McNutt + + * src/character.cpp, src/kern.c, src/object.c, src/object.h, src/status.c: + Poison now shows up in character stats. Changed the way stats are reported. + + * src/kern.c, src/list.h: + Damage effects now print console messages if the damaged object is + player-controlled. + + Fixed a bug in changing party order. + +2004-05-01 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/kern.c, src/object.c, src/object.h, src/place.c, src/species.c, src/species.h: + Added simple immunity to damage types. Currently only the species can specify + any type of immunity. Added kern-obj-get-immunities so the script can check for + immunities. + +2004-04-28 Gordon McNutt + + * src/Field.cpp, src/Field.h, src/kern.c, src/object.c: + o Changed kern-mk-obj to use the type as a factory, so not it will work for any + object with a type. + + o Added a duration parameter to kern-mk-field. + + * src/Attic/Item.cpp, src/Attic/Item.h, src/closure.c, src/closure.h, src/kern.c, src/object.c, src/object.h, src/terrain.c: + o Added kern-ui-select-party-member. Scripts can now prompt the player to + select a party member. + + o Added kern-obj-remove-hook to remove effects like poison. + + o Added kern-mk-usable-item-type to create objects that can be (u)sed. + + o With these new commands I created and tested a cure-poison potion. + +2004-04-26 Gordon McNutt + + * src/Field.cpp, src/Field.h: + Field class needed to override the save() method to generate kern-mk-field + instead of kern-mk-obj. + + * src/Field.cpp, src/Attic/Mech.cpp, src/Party.cpp, src/kern.c, src/object.c, src/object.h, src/player.cpp: + Started adding a poison field. Currently it poisons the party. This is the + initial checkin: it does not poison member, there is no way to cure the poison, + and the poisoned state is not saved. + + Added kern-obj-add-hook, which can be used to attach a closure to an object + when a specific hook fires. Currently the only hook is start-of-turn, which + runs at the start of the object's turn right after its assigned its action + points. The hook closure takes the object as its only parameter. + + * src/Field.cpp, src/Field.h, src/kern.c: + Added kern-mk-field for instantiating Field objects. + + * src/Field.cpp, src/Field.h, src/Attic/Spell.cpp, src/closure.c, src/kern.c, src/object.c, src/session.c, src/terrain.c: + Added saving/loading of field types. The new FieldType constructor takes a + closure as an argument and uses this to apply the effects of objects which are + placed on the field. This replaces the old effect-mask technique as it applied + to fields. + + Field objects currently have a bug in that they do not expire. I'll attempt to + fix this with my next checking. + + * src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/object.c, src/object.h, src/player.cpp, src/player.h: + Poison applied to the party is now applied to its members instead. + + Removed obsolete applyExistingEffects() methods. This has been replaced by the + start-of-turn hook. + + * src/character.cpp, src/closure.c, src/closure.h, src/kern.c, src/object.c, src/object.h, src/place.c, src/scheme.c: + Added ability to save hooks attached to objects. + + * src/character.h: + Removed some commented-out code. + + * src/combat.c: + Removed some dead code. + + * src/kern.c: + file kern.c was initially added on branch gmcnutt_scheme. + + * src/kern.c: + New file. + + * src/kern.h: + file kern.h was initially added on branch gmcnutt_scheme. + + * src/kern.h: + New files. + +2004-04-24 Gordon McNutt + + * src/Makefile.am: + Pulled the kernel API out of session.c to the new kern.c. + + * src/Attic/Makefile.in: + Added kern.c. + + * src/object.c: + Bugfix: Object constructor needed to set it's container link key to its object + type layer. It was defaulting to the null layer. + + * src/player.cpp: + Bugfix: items in player inventory that were also readied by party members were + being saved twice. + + * src/session.c: + Pulled kernel API out of session.c to the new kern.c. + + * src/session.c: + Removed dead code. + + * src/session.h: + Pulled kernel API implementation out of session.c over to kern.c. + +2004-03-25 Gordon McNutt + + * src/Party.cpp, src/object.c, src/object.h, src/place.c, src/player.cpp, src/session.c: + o All containers now recursively remove and destroy their contents on session + teardown. + + o Added ref-counting to avoid double-deletion of party members during session + teardown. + + * src/character.cpp, src/cmd.c, src/cmd.h, src/ctrl.c, src/place.c, src/play.c, src/player.cpp, src/session.c, src/session.h: + o Added CTRL-Q)uicksave and CTRL-R)eload. Quicksave saves the current session + but does not quit the game. Reload reloads the session from the save file + while the game is still running. + +2004-03-22 Gordon McNutt + + * src/Container.cpp, src/Container.h, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Party.cpp, src/Party.h, src/Attic/Portal.cpp, src/Reagent.cpp, src/Reagent.h, src/Attic/Spell.cpp, src/Attic/Spell.h, src/character.cpp, src/character.h, src/object.c, src/object.h, src/place.c, src/player.cpp, src/player.h, src/session.c, src/vehicle.cpp, src/vehicle.h: + + o The player is now loaded like any other object. When starting from the + wilderness, the player party is loaded as an object in the wilderness. When + starting in non-wilderness, the party members are loaded as objects; then, + after loading but before starting the session, the starting place is + determined by checking the location of the party members. + + * src/combat.c, src/place.c, src/place.h: + + o When saving in combat the combat place is saved recursively in the wilderness + place. This gets rid of the special-case hacks necessary to make saving in + combat work. + +2004-03-21 Gordon McNutt + + * src/Attic/Mech.cpp, src/Attic/Mech.h, src/session.c: + o All of the kern_mk functions now return a pointer to the defined scheme + object (or nil if an error occurred) + + o Consolidated some of the scm_define macros + + * src/Attic/Portal.cpp, src/cmd.c, src/combat.c, src/common.h, src/place.c, src/place.h, src/player.cpp, src/player.h, src/session.c, src/terrain_map.c: + o Places can now contain subplaces, which are saved recursively within them. + + o Saving in combat temporarily broken in conjunction with the above. + + * src/combat.c, src/combat.h, src/place.c, src/place.h, src/session.c, src/session.h, src/terrain_map.c, src/terrain_map.h: + o Added a 'struct save' which is passed to all the saving routines. It includes + a callback table for writing out save code that is reasonably indented. + + * src/place.c, src/session.c, src/terrain_map.c, src/terrain_map.h: + o Terrain maps associated with places are now saved recursively within + them. Terrain maps not associated with places (combat and overlay maps) are + still saved standalone. + +2004-03-17 Gordon McNutt + + * src/object.c, src/object.h, src/session.c: + o kern-mk-place now looks for an optional list of contents. Each entry in the + list is an object followed by its x, y coordinates in the place. Content + lists are not yet saved. That's next, and it will require fiddling with how I + load/save the player party. + + o Added kern-mk-obj for creating simple objects. + + o Added kern-put-obj for locating objects that aren't created as part of a + place. + +2004-03-16 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/object.c, src/scheme.c, src/scheme.h, src/session.c, src/terrain.c, src/terrain.h: + o Added burning effect to lava terrain. + + * src/closure.c: + file closure.c was initially added on branch gmcnutt_scheme. + + * src/closure.c, src/closure.h, src/object.c: + o Invoking scheme closures from C now uses varargs (like printf). + + * src/closure.c, src/closure.h: + Two files that belonged in the last checkin + + * src/closure.h: + file closure.h was initially added on branch gmcnutt_scheme. + +2004-03-15 Gordon McNutt + + * src/combat.c, src/session.c: + o Bugfix: save in combat, reload, save again without leaving combat => crash + because Combat.place not set. Relying on Place->is_wilderness_combat now + instead. + + * src/nazghul.c: + o The command-line now expects the load file as a non-option argument (it used + to be the --file option). + +2004-03-14 Gordon McNutt + + * src/astar.c, src/character.cpp, src/combat.c, src/combat.h, src/list.h, src/place.c, src/place.h, src/player.cpp, src/session.c, src/session.h, src/terrain_map.c, src/terrain_map.h: + Almost saving/loading from combat + + * src/combat.c, src/place.h, src/session.c, src/terrain_map.h: + o Can save/load from the temporary wilderness combat place now. Surprisingly + difficult, required some hacks which can hopefully be removed once places + save/load their own contents. + +2004-03-13 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/combat.c, src/object.c, src/object.h, src/player.cpp, src/player.h, src/session.c: + o At last saving/loading from towns works. + +2004-03-12 Gordon McNutt + + * src/character.cpp, src/object.c, src/place.c, src/play.c, src/player.cpp, src/session.c: + o The player party constructor now relocates the party if the place is not + null. + + o Bugfix: object relocate() always called updateView(), even if the object was + removed from the map during relocation. + + o Bugfix: place destructor would assert if any objects were still sitting on + any tiles. Added a call to remove all objects before proceeding to tile + destruction. + + * src/foogod.c, src/foogod.h, src/map.c, src/Attic/moongate.c, src/nazghul.c, src/object.c, src/play.c, src/player.cpp, src/session.c, src/session.h, src/sky.c, src/sky.h, src/status.c, src/status.h: + o Cleaned up the startup code a bit. Moved most of the game start code to + nazghul.c and the session start code to session.c. + + o Hacked ambient light to be a fixed value until I can reorg the astronomy + stuff. + + * src/session.c, src/sky.c: + o More changes related to getting the game to save/reload in a town. + +2004-03-11 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Party.cpp, src/Attic/Portal.cpp, src/Attic/Portal.h, src/character.cpp, src/cmd.c, src/combat.c, src/ctrl.c, src/Attic/game.c, src/place.c, src/play.c, src/player.cpp, src/Attic/portal.h, src/session.c: + o Changed 'portal.h' to Portal.h, added Portal.cpp and cleaned up the .h file. + + * src/Attic/Portal.cpp: + file Portal.cpp was initially added on branch gmcnutt_scheme. + + * src/Attic/Portal.cpp, src/Attic/Portal.h, src/object.c, src/object.h, src/session.c: + o More cleanup in Poral. + + o Added a new object constructor similar to the new one for object types. All + the other constructors and the init() routines are now obsolescent and need + to be phased out. + + o Noticed a new bug: saving in towns records the player party coordinates, not + the party member coordinates. So reloading after saving in towns is not + correct. + + * src/Attic/Portal.h: + file Portal.h was initially added on branch gmcnutt_scheme. + + * src/cmd.c, src/terrain.c: + o Bugfix: terrain_new not properly zeroing out its structure, caused obsolete + 'effects' field to be uninitialized, so crossing a bridge might burn and + poison the party! + + o Loading the wilderness map (sans all the towns) with the expanded palette. No + other issues found. + + * src/cmd.c, src/images.c, src/images.h, src/session.c: + o Save/restore of limited games now works. At long, long last. Much still to be + done to get the full complement of features loading and saving, however. + + * src/place.c, src/place.h, src/Attic/portal.h, src/session.c: + o Added 'kern-mk-town' procedure. This replaces the old "inference" technique + where the loader would make a place a town by inferring this from certain + fields. + + o You can now enter GreenTower from the Wild. Saving in GreenTower and + reloading works fine. + +2004-03-10 Gordon McNutt + + * src/ascii.c, src/ascii.h, src/cmd.c, src/cmdwin.c, src/combat.c, src/common.h, src/cursor.cpp, src/cursor.h, src/map.c, src/play.c, src/screen.c, src/screen.h, src/session.c, src/session.h: + o Can now walk around. Sprites are mismatched, not sure what else is wrong yet. + + o Consolidated some globals into a new Session global. + + o Set NUM_MOONS to zero to turn off the moons until I can rewrite the MoonInfo + cruft - I don't want to propogate that any more if I can help it. + + * src/character.cpp, src/clock.c, src/clock.h, src/cmd.c, src/combat.c, src/session.c, src/session.h, src/sky.c, src/sky.h: + o The LOS screw-up was more errors in script translation. It's just fine now. + + o Fixed some stuff related to the global clock. Decided it's reasonable to + require a clock in every game. + + o Fixed a bug where we crash if we have no Sun (don't see why a sun should be + required). + + * src/sprite.c, src/sprite.h: + o Sprites have been fixed, this was a script-upgrade error. + + o Sprite animation needed to be reworked. The loader no longer pushes sprites + onto a list in the sprite lib, so I can't advance frames by incrementing each + individual sprite's frame counter anymore. Instead I use a single static + sprite_tick counter in the sprite lib and have all sprites % off of + that. This is more efficient anyway, as now I no longer have to walk the + sprite list touching every multi-frame sprite every animation tick, and I no + longer have to keep a per-sprite frame or wavecrest. The counter is an + unsigned int so rollover should happen naturally. + + o LOS is totally hosed, but other than that I've found no other problems so + far. + +2004-03-09 Gordon McNutt + + * src/character.cpp, src/character.h, src/session.c: + o Loading and saving CHARs. + + * src/player.cpp, src/player.h, src/session.c: + o Loading and saving the player party. Not actually walking around yet - that + will be next. + + * src/session.c: + o Discovered that with -O2 turned on the c++ compiler appears to incorrectly + handle some cases of call-by-reference. That's it. No more c++. All new code + is hereby forbidden to make use of ANY c++ features. It must be phased out. + + o Ripped out all the unpack_ functions (which were using the cursed + call-by-reference) and replaced them with a scanf-like unpacker which uses + explicit pointers as its args. Cleans up a lot of boilerplate, too. + +2004-03-08 Gordon McNutt + + * src/Arms.cpp, src/Arms.h, src/Container.cpp, src/Field.cpp, src/Field.h, src/Reagent.cpp, src/Reagent.h, src/Attic/Trap.cpp, src/Attic/Trap.h, src/Attic/moongate.c, src/Attic/moongate.h, src/object.c, src/object.h, src/occ.c, src/occ.h, src/session.c, src/vehicle.cpp, src/vehicle.h: + o Loading arms types + + * src/character.cpp, src/character.h, src/session.c, src/species.c, src/species.h: + o Loading species + + * src/occ.c, src/occ.h, src/session.c: + o Loading occupation types + +2004-03-07 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/combat.c, src/Attic/load.c, src/Attic/load.h, src/map.h, src/place.c, src/play.c, src/session.c, src/session.h, src/terrain_map.c, src/terrain_map.h: + o Moved loading code to session.c and got rid of load.[ch]. + + o Added loading of terrain maps. + + * src/Makefile.am, src/Makefile.am, src/Attic/Makefile.in, src/Attic/Makefile.in, src/astar.c, src/conv.c, src/debug.c, src/debug.h, src/Attic/game.c, src/images.c, src/images.h, src/Attic/load.c, src/Attic/load.h, src/macros.h, src/opdefines.h, src/play.c, src/play.c, src/scheme-private.h, src/scheme.c, src/scheme.h, src/session.c, src/session.h, src/sky.c: + *** empty log message *** + + * src/Party.cpp, src/cmd.c, src/combat.c, src/place.c, src/place.h, src/play.c, src/player.cpp, src/session.c: + o Loading and saving simple places (no objects in them yet). + + * src/combat.c, src/play.c, src/session.c, src/session.h, src/terrain_map.c, src/terrain_map.h: + o Added a 'kern-include' proc. This is so the engine can save the session such + that when the save-file is reloaded all the necessary "include" files are + loaded with it. + + o Added saving of maps in the session file. + + * src/Attic/load.c: + file load.c was initially added on branch gmcnutt_scheme. + + * src/Attic/load.c, src/play.c, src/terrain.c, src/terrain.h, src/terrain_map.c: + Loading palettes + + * src/Attic/load.c, src/place.c, src/scheme.c, src/scheme.h, src/sprite.c, src/sprite.h, src/terrain.c, src/terrain.h, src/terrain_map.c, src/terrain_map.h: + Terrain loading + + * src/Attic/load.c, src/session.c, src/session.h: + Made the interpreter part of the session + + * src/Attic/load.h: + file load.h was initially added on branch gmcnutt_scheme. + + * src/opdefines.h: + file opdefines.h was initially added on branch gmcnutt_scheme. + + * src/scheme-private.h: + file scheme-private.h was initially added on branch gmcnutt_scheme. + + * src/scheme.c: + file scheme.c was initially added on branch gmcnutt_scheme. + + * src/scheme.h: + file scheme.h was initially added on branch gmcnutt_scheme. + + * src/session.c: + file session.c was initially added on branch gmcnutt_scheme. + + * src/session.c, src/session.h: + o Include files now treated like regular session objects instead of a special + case. Cleans things up a bit. + + * src/session.h: + file session.h was initially added on branch gmcnutt_scheme. + +2004-03-04 Gordon McNutt + + * src/Attic/loader.cpp, src/Attic/loader.h, src/species.c, src/species.h: + o Loading SPECIES. + +2004-03-03 Gordon McNutt + + * src/Attic/loader.cpp, src/Attic/loader.h, src/occ.c, src/occ.h: + o Loading OCCs now. + + o Added a templates for binding lists of tags into arrays of pointers. + + o Added a template to bind a single tag to a pointer. + +2004-03-02 Gordon McNutt + + * src/Reagent.cpp, src/Reagent.h, src/Attic/loader.cpp, src/Attic/loader.h: + o Loading REAGENTS + + * src/Attic/Spell.cpp, src/Attic/Spell.h, src/Attic/loader.cpp, src/Attic/loader.h: + o Loading SPELLS + + o Fixed a nasty bug related to double-deallocating a string in the parsed + sprite destructor. + + * src/Attic/loader.cpp, src/Attic/loader.h: + o Loading MAGIC WORDS. + +2004-03-01 Gordon McNutt + + * examples/data/def_macros.ghul, examples/data/types.ghul, examples/data/player/party.ghul, examples/data/types/chest_traps.ghul, examples/data/types/furniture.ghul, examples/data/types/magical_fields.ghul, examples/data/types/npc_party_defs.ghul, examples/data/types/portal_types.ghul, examples/data/types/useable_items.ghul, examples/data/types/vehicles.ghul, examples/data/types/weapons.ghul, examples/data/world/characters/Gen.ghul, src/Arms.cpp, src/Arms.h, src/Container.cpp, src/Field.cpp, src/Field.h, src/Attic/Item.cpp, src/Attic/Item.h, src/Reagent.cpp, src/Attic/Trap.cpp, src/Attic/Trap.h, src/Attic/lexer.c, src/Attic/lexer.l, src/Attic/loader.cpp, src/Attic/loader.h, src/Attic/moongate.c, src/Attic/moongate.h, src/nazghul.c, src/object.c, src/object.h, src/occ.c, src/Attic/parser.y, src/Attic/parser_cb.h, src/terrain.c, src/vehicle.cpp, src/vehicle.h: + o Loading objects types. + + o Split object types into OBJ_TYPE, TRAP_TYPE, FIELD_TYPE, ITEM_TYPE, + MOONGATE_TYPE and ARMS_TYPE. + + o Added new constructor calls to object type classes as necessary. + +2004-02-29 Gordon McNutt + + * src/Attic/loader.cpp: + More formatting changes + + * src/Attic/loader.cpp: + Formatting changes + + * src/Attic/loader.cpp, src/Attic/loader.cpp, src/terrain.c: + *** empty log message *** + +2004-02-28 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Attic/loader.c, src/Attic/loader.cpp: + Moved loader.c to loader.cpp + + * src/Attic/loader.cpp: + file loader.cpp was initially added on branch gmcnutt_loader. + + * src/Attic/loader.cpp, src/Attic/loader.cpp, src/Attic/loader.cpp, src/Attic/loader.cpp, src/Attic/loader.cpp: + *** empty log message *** + +2004-02-24 Gordon McNutt + + * src/Attic/loader.c, src/Attic/loader.h, src/terrain.c, src/terrain.h, src/terrain_map.c: + o Loading PALETTE constructs now. + +2004-02-23 Gordon McNutt + + * examples/data/world.ghul, examples/data/types/terrains.ghul, src/Attic/lexer.c, src/Attic/lexer.l, src/Attic/loader.c, src/Attic/parser.y, src/Attic/parser_cb.h, src/terrain.c, src/terrain.h, src/terrain_map.h: + o Converted all the loader errors to warnings so that the game continues on a + load error. I forgot that errors would exit the program. + + o Eliminated the old 'combat_map' construct and replaced it with a field in the + terrain construct for specifying a map. In the old system this was impossible + because tags usually had to be resolved right away at parse time, so maps and + terrains had a chicken-and-egg problem. With the new loader binding is done + as a second pass so this is no longer an issue. Right now terrains with no + defined combat map emit a warning at bind time. + +2004-02-22 Gordon McNutt + + * examples/Makefile.am, examples/Makefile.in, examples/data/Makefile, examples/data/def_constants.ghul, examples/data/def_macros.ghul, examples/data/types.ghul, examples/data/world.ghul, examples/data/types/portal_types.ghul, examples/data/types/readable_items.ghul, src/Attic/lexer.c, src/Attic/lexer.l, src/Attic/loader.c, src/Attic/loader.h, src/Attic/parser.y, src/play.c: + o Split the load file into two files: a game file (examples/game.ghul) and a + session file (examples/mapfile). The game file contains read-only game data + (or it will when all is said and done) and the session file contains all the + data used to save the state of a game (again, eventually). Right now the two + are fairly well split but lots of crossover still exists. This will be sorted + out in checking to follow. + + o Added the new GAME keyword to the script. This keyword goes in the saved + session file and specified the file from which to load the read-only game + data. + + o The loader now returns a session data structure which contains all the + per-session data and a pointer to the read-only game data. When a new session + is loaded the loader will attempt to reuse the existing game data unless the + session specifies it wants to use a different game file than the old + session. A session MUST specify a game file via the new GAME keyword or the + loader will abort. + + o When a session fails to load the loader will return the old session if it + exists or NULL otherwise. + + * examples/data/types.ghul, examples/data/world.ghul, src/Attic/game.c, src/Attic/lexer.c, src/Attic/lexer.l, src/Attic/loader.c, src/Attic/loader.h, src/Attic/parser.y, src/Attic/parser_cb.h: + o Congregated the CURSOR and CROSSHAIR constructs into a MISC construct which + has them as fields. + + o Added file-name information to the parsing structures so that error messages + can show the file as well as the line (game file vs session file). + + * src/ascii.c, src/ascii.h, src/Attic/loader.c, src/Attic/loader.h, src/play.c, src/screen.c, src/screen.h: + o Trivial change to the way I set the frame sprites and ascii sprite + to make things simpler to load. + + o Loading is now a separate step from actually changing the game state. The + loader returns - on success - a completely parsed and loaded structure which + the caller will then use to update the game state. This way we don't get + partway through changing the game state before we encounter a bind error, for + instance, which would cause the operation to fail. + + * src/cmd.c, src/Attic/loader.c, src/sprite.c, src/sprite.h, src/terrain.c, src/terrain.h: + o Reverted terrain and sprite permanent structures to remember their + tags. Although I don't need them for lookups with the new loader, I will need + them for saving some objects to the session file (e.g., altered MAPS). + + * src/cmd.c, src/combat.c, src/conv.c, src/Attic/game.c, src/Attic/loader.c, src/Attic/loader.h, src/Attic/parser.y, src/Attic/parser_cb.h, src/place.c, src/place.h, src/terrain.c, src/terrain.h: + o Parsing & loading terrains. + + * src/Attic/loader.c: + o The loader now blows away its temporary data structures prior to + exit. This addresses the inefficiency problem I noted in an earlier checkin. + + * src/Attic/parser_cb.h: + file parser_cb.h was initially added on branch gmcnutt_loader. + +2004-02-21 Gordon McNutt + + * src/Attic/Mech.cpp, src/astar.c, src/debug.h, src/Attic/game.c, src/images.c, src/images.h, src/Attic/loader.c, src/play.c, src/sprite.c, src/sprite.h: + o Loading FRAME and ASCII constructs. + + o Removed tags from sprite and image structs. These tags are only required + while loading and it is sufficient to store them in the temporary data + structures used by the loader. + + o Currently the temporary loader structures will remain until a reload, at + which point everything will be torn down. Although convenient, this is + wasteful. I'll try to address this in my next checkin. + + * src/Attic/game.c, src/images.c, src/Attic/loader.c, src/screen.c, src/screen.h, src/sprite.c: + Added loading and binding of frame elements + + * src/Attic/game.c, src/images.c, src/images.h, src/Attic/lexer.c, src/Attic/loader.c, src/Attic/loader.h, src/Attic/parser.y, src/sprite.c, src/sprite.h: + Loading of sprites, binding implemented but untested + + * src/Attic/loader.c, src/sprite.c, src/sprite.h: + Added an allocation pass and a binding pass to the loader + +2004-02-19 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/debug.c, src/debug.h, src/Attic/game.c, src/Attic/lexer.c, src/Attic/loader.c, src/Attic/mmap.c, src/Attic/mmap.h, src/nazghul.c, src/Attic/util.c, src/Attic/util.h: + o Moved the mmap utility wrappers from util.h/c to mmap.h/c. The problem with + util.h is that it includes common.h, which is too much for some clients. I'm + going to try a finer-grained approach with these little utility functions. + + o Converted the old (broken) debug macros to functions and put them in the new + debug.c. + + * src/debug.c: + file debug.c was initially added on branch gmcnutt_loader. + + * src/Attic/lexer.c, src/Attic/lexer.l, src/macros.h, src/Attic/parser.y, src/Attic/util.h: + Added macros.h for generic, c-safe macros. Cleaned up lexer.l and parser.y with this change. + + * src/macros.h: + file macros.h was initially added on branch gmcnutt_loader. + + * src/Attic/mmap.c: + file mmap.c was initially added on branch gmcnutt_loader. + + * src/Attic/mmap.h: + file mmap.h was initially added on branch gmcnutt_loader. + +2004-02-18 Gordon McNutt + + * Attic/lexer.h: + file lexer.h was initially added on branch gmcnutt_loader. + + * Attic/lexer.h, examples/data/def_macros.ghul, examples/data/world.ghul, examples/data/player/party.ghul, examples/data/types/npc_party_defs.ghul, examples/data/types/occupations.ghul, examples/data/types/portal_types.ghul, examples/data/types/readable_items.ghul, examples/data/types/species.ghul, examples/data/types/useable_items.ghul, examples/data/types/vehicles.ghul, examples/data/world/characters/BlackBart_the_Shipwright.ghul, examples/data/world/characters/Deric.ghul, examples/data/world/characters/Doris.ghul, examples/data/world/characters/Gen.ghul, examples/data/world/characters/Olin_the_Ghast.ghul, examples/data/world/characters/Shroom_the_Hag.ghul, examples/data/world/characters/party_members.ghul, examples/data/world/conversations/C_green_tower.ghul, examples/data/world/conversations/C_misc_npcs.ghul, examples/data/world/conversations/conversations.ghul, examples/data/world/places/Glasdrin.ghul, examples/data/world/places/GoblinCaves.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/GreenTowerLower.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul, examples/data/world/places/P_rom_camp.ghul, examples/data/world/places/P_slime_cave.ghul, examples/data/world/places/P_terrain_test.ghul, examples/data/world/places/P_wilderness.ghul, src/Makefile.am, src/Attic/Makefile.in, src/Attic/lexer.c, src/Attic/lexer.l, src/Attic/loader.c, src/Attic/loader.h, src/Attic/parser.y, src/play.c, src/Attic/util.c, src/Attic/util.h: + o parser.o and lexer.o must be compiled using gcc (instead of g++) or I get + parser stack overflows. No idea why. + + o Updated the scripts to reflect some tweaks I made to the syntax while writing + the new parser. + + * src/play.c: + Removed the obolete 'play' struct in play.c + +2004-02-17 Gordon McNutt + + * Attic/Makefile.in, Attic/configure, Attic/configure.in, examples/Makefile.in, src/Makefile.am, src/Attic/Makefile.in, src/Attic/lexer.c, src/Attic/lexer.h, src/Attic/lexer.l, src/Attic/loader.c, src/Attic/loader.h, src/Attic/old_lexer.c, src/Attic/parser.y, src/Attic/util.h: + o Brought in new flex/bison parser and got it to build. + + * src/Attic/lexer.h: + Adding back in the old lexer.h (for now) + + * src/Attic/lexer.l: + file lexer.l was initially added on branch gmcnutt_loader. + + * src/Attic/loader.c: + file loader.c was initially added on branch gmcnutt_loader. + + * src/Attic/loader.h: + file loader.h was initially added on branch gmcnutt_loader. + + * src/Attic/old_lexer.c: + file old_lexer.c was initially added on branch gmcnutt_loader. + + * src/Attic/parser.y: + file parser.y was initially added on branch gmcnutt_loader. + +2003-11-15 Gordon McNutt + + * src/player.cpp, src/player.h: + Factored out the private try_to_enter_portal method in the player class + +2003-11-08 Gordon McNutt + + * src/foogod.c, src/player.cpp, src/player.h: + Removed the turn counter. + +2003-11-07 Sam Glasby + + * src/common.h, src/console.c, src/foogod.c, src/screen.c, src/status.c: + new feature: resizing status window -- DANGER: known to be broken right now. + + * src/object.c: + Fixed a crash bug upon entering a place with at least one object stack + created via the multiple-objects construct, such as: + t_arrow 2 27 50; + + Apparently, the place field was not being initialized, and when + the game loop checked for effects (such as fire) on the (place,x,y) + of these objects, a SIGSEGV was thrown. + +2003-11-07 Gordon McNutt + + * examples/data/types/vehicles.ghul, examples/data/world/places/P_wilderness.ghul, src/Arms.cpp, src/Party.cpp, src/Party.h, src/player.cpp, src/player.h, src/vehicle.cpp, src/vehicle.h: + Bugfix: sinking a horse killed the party + + * src/console.c, src/console.h, src/foogod.c, src/foogod.h, src/status.c: + Bugfix: console/foogod clobbering each other + +2003-11-05 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/combat.c, src/ctrl.c, src/ctrl.h, src/player.cpp, src/player.h: + Moved most remaining fields exclusive to player over to Party; noticed that S)witch command causes a hang + + * src/Party.cpp, src/common.h, src/list.h, src/player.cpp, src/player.h: + Removed duplicate applyExistingEffects code between player and Party classes + +2003-11-04 Sam Glasby + + * examples/data/player/party.ghul, examples/data/world/characters/party_members.ghul: + Added new party members, the better to examine UI issues with party sizes greater than 3. + +2003-11-04 Gordon McNutt + + * src/Party.cpp, src/Party.h, src/cmd.c, src/combat.c, src/ctrl.c, src/Attic/game.c, src/player.cpp, src/player.h, src/status.c: + Moved more fields from player to Party, removed more duplicates + + * src/Party.h, src/player.h: + Removed redundant 'vehicle' field in player class + + * src/Party.h, src/player.h, src/screen.c: + Moved 'gold' from player to Party class + + * src/player.cpp, src/player.h: + Removed obsolete 'turns' field from player class + + * src/screen.c: + Bugfix: highlighting box rendered improperly in zoom mode + +2003-11-03 Sam Glasby + + * examples/data/world/mechanisms/all_mechanisms.ghul, src/Attic/Mech.cpp, src/Attic/Mech.h: + Added support for any_event_among keyword in transitions {} block for MECH_TYPE. + + * src/Attic/Mech.cpp, src/Attic/Mech.h, src/conv.c, src/conv.h: + Added functions/methods to dump state for Mech objects and structs, and for struct response. + +2003-11-03 Gordon McNutt + + * examples/data/player/party.ghul, examples/data/types/Attic/formation.ghul, examples/data/types/npc_party_defs.ghul, examples/data/world/places/P_wilderness.ghul, src/Party.cpp, src/Party.h, src/combat.c, src/Attic/game.c, src/player.cpp, src/player.h: + More work towards integrating the player and Party class. + o Moved some fields from the player class to the PartyType class. + o Moved some fields from the player ghulscript construct to be optional fields + in the PARTY construct. + + * examples/data/types/Attic/formation.ghul: + file formation.ghul was initially added on branch gmcnutt_party2_br. + +2003-11-02 Gordon McNutt + + * examples/data/world/places/Glasdrin.ghul, examples/data/world/places/GoblinCaves.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_rom_camp.ghul, examples/data/world/places/P_wilderness.ghul, src/Party.cpp, src/Attic/game.c: + Eliminated the 'home' field in the ghulscript npc constructor + + * src/Party.cpp, src/Party.h, src/character.cpp, src/character.h, src/cmd.c, src/conv.c, src/Attic/game.c, src/object.c, src/object.h, src/player.cpp, src/player.h: + Moved the inventory from the player_party class to its parent Party class + +2003-11-01 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Missile.cpp, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Party.cpp, src/Party.h, src/Attic/Spell.cpp, src/astar.c, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/combat.h, src/common.h, src/conv.c, src/ctrl.c, src/ctrl.h, src/cursor.cpp, src/cursor.h, src/Attic/game.c, src/list.h, src/object.c, src/object.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/player.h, src/status.c: + Cleaned up Party.h + + * src/Party.cpp, src/Party.h, src/place.c, src/player.h: + Got rid of two obsolete methods in Party.h + + * src/Party.cpp, src/Party.h, src/combat.c: + Made all Party.h members protected + +2003-10-27 Gordon McNutt + + * src/Party.cpp, src/Attic/Spell.cpp, src/astar.c, src/character.cpp, src/cmd.c, src/ctrl.c, src/place.c, src/player.cpp, src/player.h: + Bugfix: corner-case hang in pathfinding code + +2003-10-25 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Missile.cpp, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Party.cpp, src/Party.h, src/Attic/Spell.cpp, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/combat.h, src/common.h, src/conv.c, src/ctrl.c, src/ctrl.h, src/Attic/game.c, src/place.c, src/place.h, src/play.c, src/player.cpp, src/player.h: + Renamed NpcParty as Party to prepare for merging player party code with npc party code + + * src/Party.cpp: + file Party.cpp was initially added on branch gmcnutt_ctrl_br. + + * src/Party.cpp, src/Party.h, src/Attic/Spell.cpp, src/character.cpp, src/cmd.c, src/combat.c, src/conv.c, src/ctrl.c, src/list.h, src/player.cpp, src/player.h, src/status.c: + Made player party a subclass of Party, got rid of fixed-size pc array + + * src/Party.h: + file Party.h was initially added on branch gmcnutt_ctrl_br. + +2003-10-18 Gordon McNutt + + * src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Attic/Spell.cpp, src/character.cpp, src/character.h, src/ctrl.c, src/cursor.cpp, src/cursor.h, src/object.c, src/object.h, src/player.cpp, src/player.h: + Hooked up all the controllers + + * src/character.cpp, src/ctrl.c: + Partly hooked up character ai contrroller + +2003-10-17 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Attic/NpcParty.h, src/character.h, src/ctrl.c, src/ctrl.h, src/player.cpp, src/player.h: + Hooked up player party ui controller + + * src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/cmd.c, src/ctrl.c, src/object.c, src/object.h, src/player.h: + Hooked up ai party controller + + * src/character.cpp, src/ctrl.c: + Hooked up character ui controller + + * src/ctrl.c: + file ctrl.c was initially added on branch gmcnutt_ctrl_br. + + * src/ctrl.h: + file ctrl.h was initially added on branch gmcnutt_ctrl_br. + +2003-10-12 Gordon McNutt + + * src/Attic/AiPartyController.cpp: + file AiPartyController.cpp was initially added on branch gmcnutt_controller_br. + + * src/Attic/AiPartyController.cpp, src/Attic/AiPartyController.h, src/Makefile.am, src/Attic/Makefile.in, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/cmd.c, src/object.c, src/object.h, src/player.h: + Added the AiPartyController + + * src/Attic/AiPartyController.h: + file AiPartyController.h was initially added on branch gmcnutt_controller_br. + + * src/Attic/Controller.h: + file Controller.h was initially added on branch gmcnutt_controller_br. + + * src/Attic/Controller.h, src/Makefile.am, src/Attic/Makefile.in, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Attic/Spell.cpp, src/Attic/UiPartyController.cpp, src/Attic/UiPartyController.h, src/character.cpp, src/character.h, src/cmd.c, src/cursor.cpp, src/cursor.h, src/object.c, src/object.h, src/place.c, src/player.cpp, src/player.h: + Added the UiPartyController + + * src/Attic/UiPartyController.cpp: + file UiPartyController.cpp was initially added on branch gmcnutt_controller_br. + + * src/Attic/UiPartyController.h: + file UiPartyController.h was initially added on branch gmcnutt_controller_br. + +2003-10-06 Gordon McNutt + + * Attic/Makefile.in, Attic/aclocal.m4, Attic/config.guess, Attic/config.sub, Attic/configure, Attic/install-sh, Attic/ltmain.sh, Attic/missing, Attic/mkinstalldirs, examples/Makefile.in, src/Attic/Makefile.in, src/los.c: + Build changes for RedHat + + * Attic/Makefile.in, Attic/acinclude.m4, Attic/aclocal.m4, Attic/config.guess, Attic/config.sub, Attic/configure, Attic/install-sh, Attic/ltmain.sh, Attic/missing, Attic/mkinstalldirs, examples/Makefile.in, src/Attic/Makefile.in, src/los.c: + Knoppix build changes + + * Attic/Makefile.in, Attic/PRESS_RELEASE, Attic/RELEASE_NOTES, Attic/acinclude.m4, Attic/aclocal.m4, Attic/config.guess, Attic/config.sub, Attic/configure, Attic/configure.in, Attic/ltconfig, Attic/missing, Attic/mkinstalldirs, examples/Makefile.in, scripts/ghul-test-install, src/Attic/Makefile.in: + More build config changes + + * Attic/configure.in: + Changed required SDL version from 1.2.4 back to 1.2.3. + +2003-10-05 Gordon McNutt + + * src/character.cpp, src/play.c, src/player.cpp: + o Bugfix: with animation off, npc's sometimes appeared to "jump" a + space. Needed to add conditional repaints of the map before prompting the + user for input, this way the user is always looking at an up-to-date map when + they decide what to do next. + + * src/combat.c: + o Bugfix: with animation off, after fleeing from wilderness combat the screen + remained blank until the user pressed a key to cause a map repaint. (Thanks + to Sam for finding this). + + * src/combat.c: + o Bugfix: with animation off, on entry to wilderness combat the map was not + being updated properly. + + * src/place.c: + o Bugfix: with animation off, in Character Mode, if the current character quits + the game then in some cases the game will not quit, and will prompt the + player to move the next character, until the turn is over. + +2003-10-04 Gordon McNutt + + * BUGS, INSTALL, README, doc/USERS_GUIDE, src/nazghul.c: + o Updated some of the docs + + * Attic/Makefile.in, Attic/configure, Attic/configure.in, Attic/ltconfig, examples/Makefile.in, src/Attic/Makefile.in: + Fixed the LIBTOOL problem + + * Attic/PRESS_RELEASE, Attic/RELEASE_NOTES, scripts/ghul-test-install: + Added a PRESS_RELEASE file + + * Attic/configure, Attic/configure.in, examples/data/world/places/Glasdrin.ghul, examples/data/world/places/P_wilderness.ghul, src/Attic/NpcParty.cpp, src/character.cpp, src/nazghul.c, src/place.c: + o Bugfix: stepping on a tile that contained an inactive moongate would invoke + the moongate in town. + o Tweeks to the sample world + + * Attic/ltmain.sh: + Added ltmain.sh + + * examples/data/player/party.ghul, examples/data/world/astronomy.ghul, examples/data/world/places/P_wilderness.ghul, src/player.cpp: + Removed some printf dbg + + * examples/data/player/party.ghul, src/character.cpp, src/cmd.c, src/place.c, src/play.c: + Party can enter moongates in town (or dungeons) now + + * examples/data/world/characters/Doris.ghul, examples/data/world/characters/Shroom_the_Hag.ghul, examples/data/world/conversations/conversations.ghul: + Added some dialog + + * examples/data/world/characters/Doris.ghul, examples/data/world/characters/Attic/char_doris.ghul, examples/data/world/places/GreenTower.ghul: + Changed char_doris.ghul to Doris.ghul + +2003-10-03 Gordon McNutt + + * src/astar.c: + Pathfinding now aborts immediately if the target destination is invalid. This helps when you're in a ship in a wilderness with hostile npc's and your machine is slow. + + * src/cmd.c, src/vmask.c: + Bugfix: vmask_invalidate was calculating the wrong region on wrapping maps + +2003-10-02 Gordon McNutt + + * src/event.c, src/map.c, src/play.c: + More profiling + +2003-09-30 Gordon McNutt + + * src/character.cpp, src/event.c, src/map.c, src/play.c, src/player.cpp: + Replaced the pseudo-fps counter with a latency and turnaround indicator. They're still a little quirky for the first turn or two but after that they seem ok (I haven't tested them a whole lot, though) + + * src/event.c, src/map.c: + Mouse events can no longer cause a repaint. + +2003-09-28 Gordon McNutt + + * Attic/Makefile.in, Attic/aclocal.m4, Attic/configure, examples/Makefile.in, examples/data/player/party.ghul, examples/data/world/astronomy.ghul, src/Makefile.am, src/Attic/Makefile.in, src/Attic/Mech.cpp, src/astar.c, src/character.cpp, src/character.h, src/cmd.c, src/conv.c, src/map.c, src/map.h, src/nazghul.c, src/object.c, src/terrain_map.c, src/tree.c, src/tree.h, src/vmask.c, src/vmask.h: + Merged over vmask changes + + * src/character.cpp, src/character.h, src/map.c, src/object.c, src/vmask.c: + o Bugfix: selecteed character was sometimes blacked out near map edges + o Bugfix: town npc's were not properly going to sleep when they were scheduled + to. + o Bugfix: igniting a torch did not always take immediate affect in combat + o Bugfix: when a character exited combat it's sprite did not immediately + disappear + + * src/cmd.c, src/map.c, src/map.h, src/object.c: + Added mapUpdateTile to repaint a single tile. Used in Object::select() + + * src/map.c, src/vmask.c: + Bugfix: scrolling the camera was showing places that should have been masked out by the vmask. + + * src/vmask.c: + Bugfix: opening/closing doors now affects line-of-sight like it should again + +2003-09-26 Gordon McNutt + + * src/object.c: + Changed the forced update in Object::select() to a mapSetDirty + +2003-09-25 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/Attic/Mech.cpp, src/astar.c, src/character.cpp, src/conv.c, src/map.c, src/nazghul.c, src/object.c, src/terrain_map.c, src/tree.c, src/tree.h, src/vmask.c, src/vmask.h: + Added vmask caching + + * src/vmask.c: + file vmask.c was initially added on branch gmcnutt_vmask_br. + + * src/vmask.h: + file vmask.h was initially added on branch gmcnutt_vmask_br. + +2003-09-21 Gordon McNutt + + * src/Arms.cpp, src/Attic/Makefile.in, src/Attic/Spell.cpp, src/character.cpp, src/cmd.c, src/combat.c, src/map.c, src/nazghul.c, src/play.c, src/player.cpp: + Made some speedup modifications. + o In full sunlight we no longer need to build the lightmap, which otherwise + takes about 1/3 of the time spent rendering on my slow box. + o Replaced a lot of forced screen updates with a call to mark the screen as + dirty. + o If the user specifies --tick -1 then animation is disabled. + + With these changes, and by using the --bpp 8 option my slow box is playable in + the outdoors during the day... if there aren't too many npc's around. More + improvements to come. + + * src/map.c: + Modified mapMergeLightSource to only check tiles that are within the radius of + the light source. Doesn't seem to make any difference on my fast box, but it + might help on the slow box. + +2003-09-17 Gordon McNutt + + * src/character.cpp, src/map.c: + o Performance: missiles that are out of the player's LOS are no longer + painted. The game play pauses as each animation runs, and they run + much faster when they don't actually have to update the + display. Rendering them only when they are in the player's view speeds + things up in Glasdrin when things lots of skeletons and guards are + firing at each other. + + o Bugfix: yet another bug in the projectile animation. Firing arrows + at column zero of the display would make them fly in the opposite + direction. + +2003-09-15 Gordon McNutt + + * Attic/Makefile.in, Attic/acinclude.m4, Attic/aclocal.m4, Attic/configure, examples/Makefile.in, src/Attic/Makefile.in, src/ascii.c, src/ascii.h, src/character.cpp, src/common.h, src/Attic/game.c, src/images.c, src/images.h, src/map.c, src/nazghul.c, src/place.h, src/screen.c, src/screen.h, src/sprite.h: + Some changes to make it compile on Knoppix + + * examples/data/def_constants.ghul, examples/data/images/mine-32x32.png, examples/data/player/party.ghul, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/types/species.ghul, examples/data/types/spells.ghul, examples/data/types/terrains.ghul, examples/data/types/vehicles.ghul, examples/data/types/weapons.ghul, examples/data/world/astronomy.ghul, examples/data/world/portals.ghul, examples/data/world/characters/Deric.ghul, examples/data/world/characters/Gen.ghul, examples/data/world/characters/Shroom_the_Hag.ghul, examples/data/world/characters/Attic/char_doris.ghul, examples/data/world/characters/inhabitants_of_britain.ghul, examples/data/world/places/Glasdrin.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_rom_camp.ghul, examples/data/world/places/P_terrain_test.ghul, examples/data/world/places/P_wilderness.ghul, examples/data/world/places/all_places.ghul, src/Arms.cpp, src/Arms.h, src/Field.cpp, src/Field.h, src/Attic/Item.cpp, src/Makefile.am, src/Attic/Makefile.in, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Attic/Spell.cpp, src/Attic/Spell.h, src/astar.c, src/astar.h, src/character.cpp, src/character.h, src/clock.c, src/clock.h, src/cmd.c, src/cmd.h, src/combat.c, src/combat.h, src/common.c, src/common.h, src/console.c, src/console.h, src/conv.c, src/event.c, src/event.h, src/foogod.c, src/formation.c, src/formation.h, src/Attic/game.c, src/map.c, src/map.h, src/Attic/moongate.c, src/Attic/moongate.h, src/nazghul.c, src/object.c, src/object.h, src/pinfo.h, src/place.c, src/place.h, src/play.c, src/play.h, src/player.cpp, src/player.h, src/sched.c, src/screen.c, src/screen.h, src/sky.c, src/sky.h, src/sprite.c, src/sprite.h, src/vehicle.cpp, src/vehicle.h, src/wind.c, src/wind.h, src/wq.c, src/wq.h: + Merged in changes from gmcnutt-newcombat-br + +2003-09-14 Gordon McNutt + + * examples/data/player/party.ghul, examples/data/world/places/Glasdrin.ghul, src/character.cpp, src/map.c: + Added a monster generator and lots of guards in Glasdrin. I love trouble. Fixed a few bugs that were flushed out with this. + + * examples/data/player/party.ghul, examples/data/world/astronomy.ghul, src/Attic/NpcParty.cpp, src/Attic/Spell.cpp, src/astar.c, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/Attic/game.c, src/map.c, src/map.h, src/Attic/moongate.c, src/nazghul.c, src/object.c, src/object.h, src/play.c, src/player.cpp, src/player.h, src/sky.c: + Widespread changes because I decided to consolidate all the view-handling code + to the routines which place and remove objects from the map. A lot of #if 0's + remain to be cleaned up, but things appear to be working pretty smoothly + now. All the u5 spells have been tested (and work) at least in town. Some still + need to be tested in the wilderness. + + Numerous changes have been made while testing and debugging. The ones I can + remember include: + + o The party formation is now used only in wilderness combat. On entrance to + towns they just kind of pour out from the entrance point. This should fix + those odd remaining cases where one party member could be put on the other + side of a wall via a long path from the party's main position. + + o Gate travel now works again and damn is it slick. I added a full complement + of gates so now you can always cast Vas Rel Por and go somewhere. + + o Charmed npc's in town will be automatically uncharmed when the player exits. + + * src/character.cpp: + Npc's now avoid hazardous terrain while commuting and wandering. + + * src/console.c, src/nazghul.c, src/screen.h: + Removed obsolete references to SDL_ttf + +2003-09-13 Gordon McNutt + + * src/Attic/Spell.cpp: + Clone and Invisibility now update the map more snappily to show their effects. I tried to have clone put the clone under player control but this causes issues in town. Need to make clone nicer later when I redo spells and effects. + + * src/Attic/Spell.cpp, src/object.c, src/play.c, src/play.h: + Fixed Rel Tym and An Tym + + * src/character.cpp, src/object.c, src/object.h, src/place.c: + o Added a new placement algorithm for dropping characters on a map within a + specified area. So far I've only modified resurrection to use it. Later I'll + probably modify some of the other summoning spells (including clone) and + possibly general combat placement to use it. + + * src/character.cpp, src/foogod.c, src/play.c: + Fixed In An and added indicatord to the foogod window for the Time Stop, Quickness and Negate Magic global effects + +2003-09-12 Gordon McNutt + + * src/character.cpp: + Bugfix: npc's were not waking up when put to sleep with In Zu + +2003-09-10 Gordon McNutt + + * examples/data/world/characters/inhabitants_of_britain.ghul: + Bugfix: Hawknoz schedule had an out-of-order entry + + * src/cmd.c: + Bugfix: dead/sleeping members could cast spells in party mode + + * src/event.c: + Bugfix: playback mode was not working + +2003-09-09 Gordon McNutt + + * src/character.cpp, src/combat.c, src/object.c: + o Walking off the edge of a combat map no longer requires the party to be in + Follow Mode. This will allow the one character to escape without the + others. Exiting towns still requires follow mode. + + * src/character.cpp, src/character.h: + o Join: have Olin join, have him exits a town/dungeon through a wall, leaving + the other party members stranded. + +2003-09-08 Gordon McNutt + + * examples/data/player/party.ghul, examples/data/types/spells.ghul, examples/data/world/places/P_wilderness.ghul, examples/data/world/places/all_places.ghul, src/Attic/Spell.cpp, src/character.cpp, src/cmd.c, src/combat.c, src/combat.h, src/conv.c, src/Attic/game.c, src/map.c, src/object.c, src/place.c, src/player.cpp, src/player.h: + o Bugfixes: Misc stuff related to spellcasting. First three levels now tested + and working in town/dungeon. + + * src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/character.cpp, src/character.h, src/Attic/game.c, src/player.cpp, src/player.h: + o Bugfix: "Join" now works again. + + * src/place.c, src/screen.c, src/screen.h: + Made the highlighting rectangle a rectangle (it was an upside-down L) + +2003-09-07 Gordon McNutt + + * examples/data/player/party.ghul, examples/data/types/spells.ghul, examples/data/world/places/P_empire_city.ghul, src/cmd.c, src/common.h: + o Bugfix: Cast In Mani Corp (resurrect) in combat - you get a crosshair to + select the target. But, uh, the target is dead, so it's not on the map... + I fixed this by adding a new spell target type: SPELL_TARGET_PARTY_MEMBER. + + * src/Attic/Spell.cpp, src/character.cpp: + o Bugfix: Cast Uus Por in Green Tower Lower - looks like we hang. + + * src/character.cpp, src/Attic/game.c, src/play.c: + --Fixed a crash that occurred on startup if the --sound 0 option was + specified. + + * src/combat.c: + o Bugfix: attack a ship to the east - gangplanks don't meet the shore. + + * src/Attic/game.c: + o Bugfix: cannot board a ship in town. This is not a bugfix, but rather a + temporary workaround: I (mostly) disallow vehicles in town. See the + development log for my reasoning. + +2003-09-06 Gordon McNutt + + * src/character.cpp, src/cmd.c, src/cmd.h, src/object.c, src/object.h, src/player.cpp, src/player.h: + o Bugfix: Cannot rest in town (no (k)amp command in character mode). + + * src/character.cpp, src/cmd.c, src/combat.c, src/player.cpp: + o Bugfix: Camping in the wilderness is fixed again. + + o Bugfix: attacking in the wilderness was leaving the player party on the + enemy's tile after combat. + + * src/cmd.c: + o Pending a better policy on the issue of containers, I made all containers + delete themselves on open. + + o Fixed a bug in casting "An Sanct" in which the cursor did not appear. Tweaked + a few of the other spell-targeting routines to reflect changes made on the + branch. + +2003-09-04 Gordon McNutt + + * src/Attic/Spell.cpp, src/character.cpp, src/place.c: + Fixed two bugs relating to castin In Por (blink) which were reported by Sam. + + o The Spell::teleport_horizontally() code was using some old idioms, include + the global Place. I replaced this with a simple call to caster->move(), which + handles the details of deciding to move a single member or the entire party, + depending on what mode we're in. This also required adding some view/los + updating code to character::relocate(), which probably needed to be there + anyway. This fixed the In Por in the Slime Cave. + + o For the In Por bug on the map edge, what was happening is that the caster + ended up teleporting to his current square. Fine, the character::move() code + discovers that someone from the caster's party is already there (the caster) + and tried to "bump" them. But the real bug is in place_move_object(), which + would crash anytime you tried to move an object to it's current + location. That's because it looked up both source and destination tiles, then + removed the object from the source tile. If this was the only object on the + tile then it destroys the source tile. But that means we just destroyed the + destination tile, and we'are about to put something on it... easy fix once + found. + + * src/character.cpp: + o When synchronizing character schedules upon entry to a small-scale place, the + code now drops the character in the upper left corner of the roaming region + specified in the scheduled appointment. Before it would drop them in the + center. I decided that the corner was better because the engine makes no test + for passability, so it's up to the schedule designer, and since they have to + specify the ULC in the schedule it should make it more obvious when they are + specifying an impassable "drop point". Perhaps in the future I'll have the + engine do something smarter to avoid these kind of mistakes. + +2003-09-03 Gordon McNutt + + * examples/data/player/party.ghul, examples/data/world/portals.ghul, src/character.cpp, src/player.cpp: + o Consolidated some code in the player_party class when I noticed that + relocate() seemed to deal with place-to-place movement correctly. + + o Fixed a bug where changing places in the middle of a place_exec() loop caused + a crash for commuting NPC's. + + o Fixed a bug in un-charming a fellow party member with the charm spell. The + target was uncharmed but remained in auto mode. Kind of cool but not exactly + what the user would expect. + + o Reconnected the portals between Empire City, the dungeon and the dark + passage. + + * src/character.cpp: + Fixed a bug where town npc's would just wander off the edge of the map. Can't have that :-) + + * src/object.c: + Fixed a bug that cause the coordinate display to vanish after walking around a bit in Empire City + +2003-09-02 Gordon McNutt + + * examples/data/world/places/GoblinCaves.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_rom_camp.ghul, examples/data/world/places/P_wilderness.ghul, src/Attic/NpcParty.cpp, src/character.cpp, src/character.h, src/cmd.c, src/conv.c, src/Attic/game.c, src/object.c, src/object.h, src/player.cpp, src/player.h: + Guards can now speak again, and you can provoke them to a fight. + + * examples/data/world/places/P_empire_city.ghul: + Made the nixie and water elemental in Empire City both be aligned to the town. Otherwise they either attack each other or the townspeople, and they usually lose :-). + + * src/Attic/NpcParty.cpp, src/astar.h, src/character.cpp, src/character.h, src/combat.c, src/object.c, src/object.h, src/place.c, src/place.h: + Party members now pathfind through other members in follow mode. + + * src/console.c, src/console.h, src/nazghul.c, src/object.c, src/object.h, src/play.c: + Bugfix: destroying npc parties with ship cannons no longer makes them frop corpse loot. + +2003-09-01 Gordon McNutt + + * examples/data/player/party.ghul, examples/data/types/terrains.ghul: + Changed all fast terrain to be medium. + + * src/character.cpp, src/character.h, src/combat.c, src/combat.h, src/map.c, src/map.h, src/object.c, src/object.h, src/player.cpp, src/player.h: + More changes to support the unified game loop. + + o The player party can now exit from a town again. + + * src/formation.c: + file formation.c was initially added on branch gmcnutt-newcombat-br. + + * src/formation.c: + Adding formation.c + +2003-08-31 Gordon McNutt + + * examples/data/player/party.ghul, examples/data/world/places/GoblinCaves.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_rom_camp.ghul, examples/data/world/places/P_wilderness.ghul, src/Makefile.am, src/Attic/Makefile.in, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Attic/Spell.cpp, src/Attic/Spell.h, src/character.cpp, src/character.h, src/combat.c, src/combat.h, src/common.c, src/common.h, src/conv.c, src/formation.h, src/Attic/game.c, src/map.c, src/nazghul.c, src/object.c, src/pinfo.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/screen.c, src/screen.h, src/sprite.c, src/sprite.h, src/wind.c, src/wind.h, src/wq.c, src/wq.h: + More changes to support the unified game loop. + + o Moved conversations and schedules from the NpcParty class to the Character + class. Added an activity member and an appt member to the Character class to + support schedules. + + o When the loader puts a party in a non-wilderness place it automatically + distributes the party members. + + o Fixed a handful of minor bugs related to the above changes, as well as some + related to earlier changes in the way the party leader is managed. + + * src/Attic/NpcParty.cpp, src/player.cpp, src/player.h: + More changes to support the unified game loop. + + o The player party now breaks out into party mode on entrance to a town. + + o Bugfix: entering a ladder from a town or dungeon was throwing us back into + party mode. + +2003-08-23 Gordon McNutt + + * src/character.cpp, src/player.cpp: + Ok, now you can exit dungeons. But still no fighting\! + + * src/combat.c, src/combat.h, src/player.cpp, src/player.h: + Player can now enter a dungeon again. Combat is broken there, and so is exiting, but there you go. + +2003-08-22 Gordon McNutt + + * src/Attic/NpcParty.cpp, src/Attic/Spell.cpp, src/character.cpp, src/cmd.c, src/combat.c, src/combat.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/player.h: + Combat loop eliminated, looks like most entry/exit situations functional. Dungeons are, no doubt, seriously broken right now, though. + +2003-08-21 Sam Glasby + + * src/common.h, src/nazghul.c, src/play.c: + Change nazghul version number printing. + +2003-08-19 Gordon McNutt + + * src/character.cpp, src/character.h, src/foogod.c, src/object.c, src/object.h, src/vehicle.cpp, src/vehicle.h: + Fixed vehicle repair during camping + +2003-08-16 Gordon McNutt + + * src/Attic/NpcParty.cpp, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/player.cpp, src/player.h: + Most camping problems now fixed + + * src/combat.c: + Cleaned up some unused things in combat.c + +2003-08-15 Gordon McNutt + + * src/Attic/Spell.cpp, src/character.cpp, src/character.h, src/cmd.c, src/cmd.h, src/combat.c, src/combat.h, src/common.h, src/foogod.c, src/nazghul.c, src/object.c, src/object.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/player.h: + Bugfixes + + * src/character.cpp, src/play.c, src/player.cpp: + Fixed death, added sleep to charm recovery + +2003-08-14 Gordon McNutt + + * BUGS, Attic/RELEASE_NOTES: + Updated + + * Attic/configure, Attic/configure.in, scripts/RELEASE_CHECKOFF, scripts/ghul-test-install, src/nazghul.c: + Notes & such made while creating the 0.1.3 release + + * examples/data/world/places/all_places.ghul: + Re-inserted the "Terrain Test" map to aid novice map hackers + for a SourceForge file release. + +2003-08-13 Sam Glasby + + * INSTALL: + Added some notes to INSTALL about PATH settings needed. + +2003-08-11 Gordon McNutt + + * src/Arms.cpp, src/Attic/Spell.cpp, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/object.c, src/object.h, src/place.c, src/place.h, src/play.c, src/player.cpp: + Combat now lets place_exec run the npc character AI's + +2003-08-10 Gordon McNutt + + * examples/data/world/astronomy.ghul, examples/data/world/characters/Attic/char_doris.ghul: + Script changes mandated by engine changes + + * src/clock.c, src/clock.h, src/combat.c, src/foogod.c, src/play.c, src/player.cpp, src/player.h: + Time moves at wilderness scale in the wilderness once more + + * src/place.c, src/place.h: + Bufgix: program hanging in place_exec due to removing objects + +2003-08-09 Gordon McNutt + + * src/Makefile.am, src/Attic/Makefile.in, src/clock.c, src/clock.h, src/player.h, src/sky.c, src/sky.h: + Moved clock routines from sky.[ch] to clock.[ch] + + * src/clock.c: + file clock.c was initially added on branch gmcnutt-newcombat-br. + + * src/clock.c, src/clock.h, src/Attic/game.c, src/sky.c: + Added TIME to ghulscript, removed arc from same, sun initial position now derived from time + + * src/clock.c, src/clock.h, src/combat.c, src/common.h, src/event.c, src/event.h, src/Attic/moongate.c, src/Attic/moongate.h, src/play.c, src/sched.c, src/sky.c, src/sky.h: + Fixed the hang while repeatedly sleeping in the inn + + * src/clock.c, src/clock.h, src/combat.c, src/play.c: + Changed the way time keeps track of the clock + + * src/clock.c, src/clock.h, src/player.cpp, src/player.h: + Changed the way clock alarms work + + * src/clock.h: + file clock.h was initially added on branch gmcnutt-newcombat-br. + + * src/common.h, src/place.c, src/place.h, src/play.c: + Time goes by faster in the wilderness now + +2003-08-07 Gordon McNutt + + * examples/data/def_constants.ghul, examples/data/types/species.ghul, examples/data/types/terrains.ghul, examples/data/types/vehicles.ghul, examples/data/types/weapons.ghul, examples/data/world/places/P_wilderness.ghul, src/Arms.cpp, src/Arms.h, src/Attic/NpcParty.cpp, src/cmd.c, src/common.h, src/Attic/game.c, src/object.c, src/object.h, src/vehicle.cpp, src/vehicle.h: + Moved some action point values which were hard-coded in the game to the load file + + * src/cmd.c: + Bugfix: opening a closed door was printing 'Open an open door' as a console message + +2003-08-06 Gordon McNutt + + * examples/data/def_constants.ghul, examples/data/images/mine-32x32.png, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/types/terrains.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_wilderness.ghul, src/Attic/NpcParty.cpp, src/astar.c: + Added trails to Green Tower and the wilderness + + * src/Attic/NpcParty.cpp, src/common.h, src/player.cpp, src/player.h: + Bugfix: members were getting an hour of rest every turn while sleeping + +2003-08-05 Gordon McNutt + + * examples/data/def_constants.ghul, examples/data/player/party.ghul, examples/data/types/species.ghul, examples/data/types/terrains.ghul, examples/data/types/vehicles.ghul, examples/data/world/characters/Deric.ghul, examples/data/world/characters/Gen.ghul, examples/data/world/characters/Shroom_the_Hag.ghul, examples/data/world/places/P_wilderness.ghul, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/common.h, src/foogod.c, src/Attic/game.c, src/object.c, src/object.h, src/player.cpp, src/player.h, src/vehicle.cpp, src/vehicle.h: + Action points now distributed based on speed; updated all the speeds and passability costs in the example game + + * src/Attic/NpcParty.cpp, src/astar.c, src/astar.h, src/place.c: + Bugfix: characters don't seem to be taking optimal path through/around forest + + * src/combat.c: + Bugfix: party was placed off-center on the camping map + +2003-08-04 Gordon McNutt + + * src/Attic/NpcParty.cpp, src/combat.c, src/object.c, src/place.c, src/place.h, src/play.c, src/vehicle.cpp: + o Bugfix: characters seemed to be getting more than one turn. Problem was the + turn_list order depended on object locations. Moving an object could change + its turn list order. + + The turn list is now no longer built during every place_exec(). Instead it is + maintained by place_add_object() and place_remove_object(). I also added a + new place_move_object() which moves an object without removing it and + replacing it in the turn list, so objects which move keep the same turn list + order. + +2003-08-03 Gordon McNutt + + * examples/data/world/astronomy.ghul, examples/data/world/characters/Deric.ghul, examples/data/world/characters/Gen.ghul, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/astar.c, src/cmd.c, src/common.h, src/object.c, src/object.h, src/place.c, src/player.cpp, src/player.h, src/sky.c, src/sky.h: + o Bugfix: in pathfinding, the heuristic was not assigning enough of a handicap + to tiles with hazards on them, and the npc party refused to move on a tile + with hazard. This resulted in npc party's failing to commute. One fix was to + assign enough of a handicap so that the path would prefer to route around the + hazard. Another fix was to only avoid hazards when wandering. When + pathfinding it is sometimes necessary to cross hazardous terrain. + + o Bugfix: furthermore, the pathfinding alg had a bug in it where a shorter but + inferior path could be chosen over a longer but superior path. + + * src/Arms.cpp, src/Field.cpp, src/Field.h, src/Attic/Item.cpp, src/Makefile.am, src/Attic/Makefile.in, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Attic/Spell.cpp, src/astar.c, src/character.cpp, src/character.h, src/cmd.c, src/combat.c, src/common.h, src/conv.c, src/object.c, src/object.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/player.h: + Changed top-level loop. Party-mode keyhandler now runs when it's the player party's turn in the place_exec() loop for the current place. + + * src/Field.cpp: + file Field.cpp was initially added on branch gmcnutt-newcombat-br. + + * src/Attic/NpcParty.cpp, src/astar.c, src/character.cpp, src/common.h, src/map.c, src/object.c, src/object.h, src/place.c, src/place.h, src/player.cpp: + --Fixed a crash that occurred on startup if the --sound 0 option was + specified. + +2003-08-01 Gordon McNutt + + * src/character.cpp, src/map.c: + Bugfix: when zoomed out x)amine was reporting everything out-of-los. + +2003-07-30 Gordon McNutt + + * examples/data/images/mine-32x32.png, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/types/terrains.ghul, examples/data/world/places/GreenTower.ghul: + Added a window terrain + + * examples/data/images/mine-32x32.png, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/types/terrains.ghul, examples/data/world/astronomy.ghul, examples/data/world/places/GreenTower.ghul: + Added arrow slits + + * examples/data/world/astronomy.ghul, examples/data/world/places/P_wilderness.ghul, src/Attic/NpcParty.cpp, src/astar.c, src/combat.c, src/map.c, src/place.c, src/player.cpp, src/terrain_map.c: + o Bugfix: random crash due to overwriting an array during map + blitting. Probably introduced when we reduced the combat map size to 19x19. + + o Bugfix: crash when sinking an npc ship. The tile was being freed twice: once + for the ship and once for the npc party. + + o Bugfix: cannons sometimes not animated. Another map-wrapping problem. + + o Bugfix: cannons sometimes hitting the ship that fired them. Yet another + map-wrapping problem. + +2003-07-29 Gordon McNutt + + * examples/data/def_constants.ghul, examples/data/world/characters/Deric.ghul, examples/data/world/characters/Attic/char_doris.ghul, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/character.cpp, src/character.h, src/cmd.c, src/cmd.h, src/combat.c, src/common.h, src/conv.c, src/conv.h, src/object.c, src/object.h, src/play.c: + Added T)alk command to combat + + * examples/data/types/vehicles.ghul, examples/data/types/weapons.ghul, examples/data/world/places/P_wilderness.ghul, src/Arms.cpp, src/Arms.h, src/Missile.cpp, src/Missile.h, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Attic/Spell.cpp, src/combat.c, src/common.h, src/Attic/game.c, src/map.c, src/map.h, src/object.c, src/object.h, src/player.cpp, src/player.h, src/vehicle.cpp, src/vehicle.h: + Removed the OrdnanceType class, rewriting most of the cannon-firing code in the process + + * examples/data/world/places/all_places.ghul: + Put back some of the old test places + +2003-07-28 Gordon McNutt + + * examples/data/images/mine-32x32.png, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/GoblinCaves.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul: + Upgraded the door sprites. + + * src/Attic/Item.cpp, src/Makefile.am, src/Attic/Makefile.in, src/Attic/Spell.cpp, src/cmd.c, src/cmd.h, src/combat.c, src/console.c, src/conv.c, src/map.c, src/play.c, src/play.h, src/player.cpp: + Moved all the common command-handling code from play.c to the new cmd.c + +2003-07-27 Gordon McNutt + + * examples/data/player/party.ghul, examples/data/types/species.ghul, examples/data/types/weapons.ghul, examples/data/world/places/P_wilderness.ghul: + Rebalanced vision radii a bit + + * examples/data/world/astronomy.ghul, src/map.c, src/place.c: + Changed lighting to use raycasting. + + * src/Arms.cpp, src/character.cpp, src/character.h, src/combat.c, src/common.c, src/common.h: + Extended max vision radius to 19; you need a character in your party who can see that far in order to take advantage of it + + * src/Missile.cpp: + Bugfix: missiles were not doing damage due to recent changes + + * src/combat.c: + Bugfix: if a charmed party members was the only one left in combat then combat would never exit. + + * src/map.c: + Bugfix: --ShowAllTerrain was not painting objects + +2003-07-26 Gordon McNutt + + * src/character.cpp: + Bugfix: resting was resurrecting dead party members + + * src/combat.c, src/play.c: + More console msg cleanup + + * src/combat.c: + Bugfix: combat place needed to inherit 'underground' from town or wilderness place + + * src/player.cpp: + Bugfix: npc parties might visibly 'warp' on entrance to a town because I was painting the scene before synchronizing their schedules + +2003-07-25 Gordon McNutt + + * examples/data/world.ghul, examples/data/world/maps/terrain_combat_maps.ghul: + Added a combat map for hilly terrain + + * examples/data/player/party.ghul, examples/data/world/characters/party_members.ghul, src/Missile.cpp, src/Missile.h, src/map.c, src/map.h, src/screen.c: + Bugfix: missiles were not animated right when zoomed out + + * examples/data/types/terrains.ghul, src/combat.c, src/map.c, src/place.c, src/place.h: + Light sources are now raytraced. Solves the light-shining-through-wall problem. + +2003-07-24 Gordon McNutt + + * src/character.cpp, src/character.h, src/combat.c, src/place.h: + If a place has no parent, characters cannot exit off map edges. Solves the problem where Olin exits in a direction the other characters cannot follow due to passability. + + * src/combat.h, src/map.c: + Fixed map 'peer' mode to recenter correctly in combat/dungeons + + * src/map.c, src/place.c, src/place.h: + Extended line-of-sight to radius 19. + +2003-07-23 Gordon McNutt + + * examples/data/player/party.ghul, examples/data/types/weapons.ghul, src/character.cpp, src/character.h, src/combat.c, src/common.h: + o Bugfix: premature victory in combat in slime cave. Npc's were not being added + properly to the combat npc array when they were introduced after start of + combat. The array elements were getting overwritten and the max used index + was not updated right. Fixed additions and got rid of the max-used index. + + o Bugfix: hitting the '<' key in dungeons caused a crash. Disabled this command + in dungeons. + + * src/combat.c: + Combat re-enters the FIGHTING state if hostile npc's added in a non-FIGHTING state + +2003-07-22 Gordon McNutt + + * examples/data/types/npc_party_defs.ghul, examples/data/types/readable_items.ghul, src/Attic/Spell.cpp, src/combat.c, src/console.c, src/play.c, src/play.h: + Misc small changes; console msg cleanup/polishing + +2003-07-20 Gordon McNutt + + * examples/data/def_macros.ghul, examples/data/types/occupations.ghul, examples/data/world/characters/BlackBart_the_Shipwright.ghul, examples/data/world/characters/Deric.ghul, examples/data/world/characters/Gen.ghul, examples/data/world/characters/Olin_the_Ghast.ghul, examples/data/world/characters/Shroom_the_Hag.ghul, examples/data/world/characters/Attic/char_doris.ghul, examples/data/world/characters/inhabitants_of_britain.ghul, examples/data/world/characters/party_members.ghul, src/Arms.cpp, src/character.cpp, src/character.h, src/combat.c, src/play.c: + Some of the new balancing changes are in place now + +2003-07-19 Gordon McNutt + + * Attic/RELEASE_NOTES, examples/data/types/species.ghul, src/species.c, src/species.h: + Eliminated the unused 'occs' fields from species + + * examples/data/world.ghul, examples/data/types/species.ghul, src/species.c, src/species.h: + Added some (yet unused) fields to species + + * examples/data/types/occupations.ghul, examples/data/types/species.ghul, src/occ.c, src/occ.h: + Added combat modifier fields to occ's + + * examples/data/types/species.ghul: + Adjusted some species attributes + + * src/Arms.cpp, src/Arms.h: + Added methods to access the hit, defend and damage and armor ranges + + * src/status.c: + For arms, print weight on same line as name + +2003-07-18 Gordon McNutt + + * Attic/configure, src/Arms.cpp, src/Arms.h, src/Makefile.am, src/Attic/Makefile.in, src/Missile.cpp, src/Missile.h, src/Attic/Spell.cpp, src/Attic/Spell.h, src/character.cpp, src/player.cpp: + Moved the Missile class out of the Arms files into Missile.h and Missile.cpp + + * examples/data/types.ghul, examples/data/sprite_sets/angband_sprite_set.ghul, examples/data/types/projectiles.ghul, examples/data/types/spells.ghul, examples/data/types/weapons.ghul, examples/data/types/worn_items.ghul, src/Arms.cpp, src/Arms.h, src/combat.c: + o Changed the damage and armor fields of ARMS to be a range of integers. This + simulates a single dice with a modifier. Currently only the max end of the + range is actually used by the engine. + + * examples/data/types.ghul, src/Arms.cpp, src/Arms.h, src/Attic/game.c: + o Changed the way Ghulscript describes and the game parses armament + types. These now have their own keyword: 'ARMS', and are parsed similar to + they way Characters, NpcPartys and other types are parsed. They must no + longer be in the 'object_types' block. + + * examples/data/types.ghul, examples/data/types/projectiles.ghul, examples/data/types/weapons.ghul, src/Arms.cpp, src/Arms.h, src/Attic/game.c: + o For arms, renamed 'attackValue' as 'damage' and 'defendValue' as 'armor'. + + o Cleaned up Arms.h/Arms.cpp a bit. + + * src/Arms.cpp, src/Arms.h, src/character.cpp, src/common.h, src/Attic/game.c, src/player.cpp, src/status.c: + Got rid of the AmmoType class (looks like it isn't used anywher) + +2003-07-17 Sam Glasby + + * examples/data/world.ghul, examples/data/world/maps/terrain_combat_maps.ghul: + Working on 19x19 combat maps. + + * examples/data/world/maps/M_blank_19x19.ghul: + Added a new blank map template, sized for use in combat maps (19x19). + +2003-07-17 Gordon McNutt + + * examples/data/world.ghul, examples/data/types/npc_party_defs.ghul, examples/data/types/occupations.ghul, examples/data/types/readable_items.ghul, examples/data/types/species.ghul, examples/data/world/portals.ghul, examples/data/world/characters/Deric.ghul, examples/data/world/conversations/conversations.ghul, examples/data/world/maps/terrain_combat_maps.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/GoblinCaves.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/GreenTowerLower_Map.ghul, examples/data/world/places/MidWorld.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul, examples/data/world/places/all_places.ghul, src/Attic/Mech.cpp, src/character.cpp, src/combat.c, src/combat.h, src/map.c, src/object.c, src/place.c, src/play.c: + New scripts; removed some engine debug and the aborted no-los-in-combat attempt + + * src/play.c: + Added ability to (x)amine terrain visible via xray + +2003-07-16 Sam Glasby + + * examples/data/images/mine-32x32.png: + Added a water elemental sprite, species, and npc party. + I also added one to Empire City. + + * examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/types/npc_party_defs.ghul, examples/data/types/species.ghul, examples/data/world/places/P_empire_city.ghul: + Added a water elemental sprite, species, and npc party. + Also added one to Empire City. + + * examples/data/world/conversations/C_misc_npcs.ghul: + Added a new file for conversations with misc NPCs. + + * examples/data/world/conversations/conversations.ghul: + Added a new file ./C_misc_npcs.ghul + + * examples/data/world/places/P_empire_city.ghul: + Added a conversation to the water elemental. + +2003-07-15 Sam Glasby + + * examples/data/images/mechanisms.png, examples/data/images/rune_font_32x32.png: + Fixed some errant pixels. + +2003-07-15 Gordon McNutt + + * examples/data/types.ghul, examples/data/types/furniture.ghul, examples/data/world/places/GreenTower.ghul, src/place.c, src/play.c: + Added a dresser container and a chair + + * examples/data/images/lost_dragon.png, examples/data/sprite_sets/lost_dragon.ghul: + Added lost_dragon sprite set and images + +2003-07-14 Gordon McNutt + + * examples/data/images/mine-32x32.png, examples/data/sprite_sets/mechanism_sprites.ghul, examples/data/types/projectiles.ghul, src/Arms.cpp, src/Attic/Spell.cpp: + Prettied-up the portcullis sprite; fixed the assert if missiles have no sprite; fixed the return value for spells that only cast missiles from 'no effect' to 'success' + + * examples/data/images/mine-32x32.png, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/types/projectiles.ghul, examples/data/types/terrains.ghul, examples/data/world/places/Glasdrin.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/GreenTowerLower.ghul, examples/data/world/places/GreenTowerLower_Map.ghul: + Added wall torches, fixed some script bugs + +2003-07-13 Sam Glasby + + * examples/data/player/party.ghul, examples/data/types/projectiles.ghul, examples/data/types/spells.ghul: + Added a new light spell. + + * examples/data/types/magical_fields.ghul: + Added a short-duration "magical illumination" field for a new minor light spell. + + * examples/data/types/projectiles.ghul: + Added a new projectile for a new light spell. + + * examples/data/types/spells.ghul: + Changed BET LOR to use EFFECT_NONE, as it should be. + + * examples/data/types/spells.ghul: + Added comments to the BET LOR (minor light) spell. + +2003-07-13 Gordon McNutt + + * BUGS, examples/data/types.ghul, src/play.c: + o [engine] Fixed TARGET_SPELL_LOCATION for wilderness/town mode. + + * Attic/RELEASE_NOTES, examples/dup_constants.h, examples/data/player/party.ghul, examples/data/types/occupations.ghul, examples/data/types/useable_items.ghul, examples/data/world/characters/Shroom_the_Hag.ghul, examples/data/world/characters/party_members.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_terrain_test.ghul, src/Attic/Item.cpp, src/Attic/Item.h, src/Attic/Spell.cpp, src/character.cpp, src/character.h, src/common.h, src/dup_constants.h, src/Attic/game.c: + o [engine] Added EFFECT_RESTORE to support mana restoration potions. Had to + sacrifice EFFECT_NATURAL because the effects bitmask is out of bits. Turns + out bit 31 does not work right because of an issue with atoi interpreting it + as an overflow. This will be addressed in the 0.3.x line with the new effects + system. + + * examples/data/sprite_sets/angband_sprite_set.ghul, examples/data/types/chest_traps.ghul, examples/data/types/weapons.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_terrain_test.ghul, src/Container.cpp, src/play.c: + Added a way to add traps to chests declared in places + + * examples/data/sprite_sets/angband_sprite_set.ghul, examples/data/types/containers.ghul, examples/data/types/occupations.ghul, examples/data/types/projectiles.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_terrain_test.ghul, examples/data/world/places/P_wilderness.ghul, src/place.c, src/place.h, src/play.c: + Opening chests now described contents again; modified describe to optionally describe the terrain + + * examples/data/types/furniture.ghul: + Added furniture.ghul + +2003-07-12 Sam Glasby + + * examples/data/types/readable_items.ghul: + Minor reformatting of a document. + + * examples/data/types/weapons.ghul: + Minor reformatting. + + * src/Attic/game.c: + Added minor comments. + +2003-07-12 Gordon McNutt + + * Attic/RELEASE_NOTES, examples/data/world/places/P_terrain_test.ghul, src/Container.cpp, src/Container.h: + o [engine] When you declare a container on a map you now must provide a list of + contents. For example: + + t_chest 10 10 { } // an empty chest + t_barrel 5 10 { t_sword 5 t_arrow 50 } // a barrel with a sword and arrows + + * Attic/RELEASE_NOTES, examples/data/world.ghul, examples/data/world/characters/Gen.ghul, examples/data/world/characters/inhabitants_of_britain.ghul, examples/data/world/conversations/conversations.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_wilderness.ghul, src/character.cpp, src/common.h, src/conv.c: + o [daghul] Added an enhanced conversation tree for NPC character Gen and put + him in Green Tower. He can teach the player the rudiments of the goblin + language. + + * examples/data/world.ghul, examples/data/sprite_sets/angband_sprite_set.ghul, examples/data/types/useable_items.ghul, examples/data/world/characters/Shroom_the_Hag.ghul, examples/data/world/maps/M_slime_cave.ghul, examples/data/world/places/P_slime_cave.ghul: + o [daghul] Added the first real mini-quest. + + * examples/data/world/characters/Gen.ghul: + Bugfix to Gen's conversation + + * examples/data/world/characters/Gen.ghul, examples/data/world/places/GreenTower.ghul, src/console.c: + o [daghul] Gave Gen a schedule; modified the Green Tower map a bit. + +2003-07-11 Sam Glasby + + * src/Attic/Item.cpp: + Improved UI prompting for "read a document" mode. + + * src/play.c: + Improved a failure message for teleport spells. + +2003-07-10 Gordon McNutt + + * Attic/RELEASE_NOTES, examples/data/world/conversations/conversations.ghul, src/conv.c, src/conv.h: + o CHECK_ITEM takes a number and an operator. It compares the number of such + items in the player's inventory against the given value. Sliwan's + conversation updated to provide an example. + + * Attic/RELEASE_NOTES, doc/USERS_GUIDE, examples/data/types/readable_items.ghul, src/play.c: + o Added a S)earch command which will reveal things on adjacent tiles that are + normally only visible with a Reveal spell + + o Reformatted the in-game users guide for better readability and use of screen + space + + * Attic/RELEASE_NOTES, examples/data/world/places/P_terrain_test.ghul, src/Attic/game.c, src/object.c, src/object.h: + o Added a quantity field for placed items. The arrows, bolts and rocks in the + terrain test map provide a sample usage. + + * examples/data/world/portals.ghul, examples/data/world/places/ForestCave.ghul, examples/data/world/places/P_slime_cave.ghul, examples/data/world/places/all_places.ghul: + Added a new dungeon map called Forest Cave + + * examples/data/world/places/Glasdrin.ghul, examples/data/world/places/P_wilderness.ghul, examples/data/world/places/all_places.ghul: + Added a new castle-town called Glasdrin + +2003-07-09 Gordon McNutt + + * Attic/RELEASE_NOTES, examples/data/world.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/GreenTowerLower.ghul, src/Attic/Mech.cpp, src/conv.c, src/conv.h, src/Attic/game.c: + o The blit_map api call now works on places besides the one the mech is located + in. Previously it took a place parm but ignored it, defaulting to the current + place. Now it works as originally intended. + + o The CONNECT construct can now be used outside of the object {} block of a + PLACE definition, allowing mechs in different places to be more easily wired + together. + + o Mostly for demonstration purposes I added two levers in the middle of Green + Tower. One lever activates a portcullis in Green Tower Lower (the + underground, a different place) by means of the new global CONNECT + construct. The other lever activates a drawbridge in Green Tower Lower by + means of the newly corrected 'place' parm of blit map. + +2003-07-08 Gordon McNutt + + * Attic/RELEASE_NOTES, examples/dup_constants.h, examples/data/world/astronomy.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/P_wilderness.ghul, src/dup_constants.h, src/Attic/game.c, src/Attic/game.h, src/sky.c: + o Added a mandrake patch to the wilderness. This required a fair amount of new, + special-case engine support, which annoys me: a MECH_FULL_MOON signal is + supported by the engine and delivered to every mech in the game whenever + either moon hits phase 0 (which the engine assumes to be full... see what I + mean? warty). + + * Attic/RELEASE_NOTES, examples/dup_constants.h, examples/data/images/mine-32x32.png, examples/data/player/party.ghul, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/sprite_sets/ultima_IV_sprite_set.ghul, examples/data/types/npc_party_defs.ghul, examples/data/types/species.ghul, examples/data/types/spells.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_slime_cave.ghul, examples/data/world/places/P_wilderness.ghul, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Attic/NpcParty.cpp, src/Attic/Spell.cpp, src/character.cpp, src/combat.c, src/common.h, src/conv.c, src/conv.h, src/dup_constants.h, src/play.c, src/play.h: + o Added the create_object api call for mech and conversations scriptlets. This + creates a simple object like an armament or item. + + o Added the create_npc_party api call for same. This creates npc parties and + adds them to the specified place (haven't tested created them in other + places, but the support is all there). Works in combat (dungeon rooms), too. + + o Added a new engine-supported mech signal: MECH_TURN, which is delivered every + turn to every mechanism within the player's current place. + + o Added some new mechanism macros in the examples to test the new + constructs. See the wilderness, the slime cave and Green Tower for example + usage. + +2003-07-03 Sam Glasby + + * src/play.c: + Increased cursor range for Xamine and Terraform to take advantage + of Zoom mode. + +2003-07-03 Gordon McNutt + + * Attic/RELEASE_NOTES, src/map.c, src/map.h, src/play.c: + --Added a ^z for map editing. This toggles map zooming. + +2003-07-02 Gordon McNutt + + * Attic/RELEASE_NOTES, examples/data/def_constants.ghul, examples/data/images/mine-32x32.png, examples/data/player/party.ghul, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/world/astronomy.ghul, examples/data/world/characters/Shroom_the_Hag.ghul, examples/data/world/characters/Attic/char_doris.ghul, examples/data/world/conversations/C_green_tower.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/GreenTower.ghul, src/conv.c, src/player.cpp: + --Created a simple inn where the player can check out a room to sleep + in. Haven't perfected the logic behind locking the player back out when he's + done, or kicking him out if he sleeps too long, etc. I wanted to this + completely with mechs, and I think it can be done (except for the kicking out + of bed part). Maybe Sam can figure out a nice way to do inns, it seems like + his kind of puzzle. + + * Attic/RELEASE_NOTES, src/Attic/NpcParty.cpp, src/player.cpp, src/player.h: + --Npc parties now wake up the player if he is sleeping in their bed. They don't + throw him out like they do in u5, but they will keep waking the player up + until he moves and let's them get into bed. + + * Attic/RELEASE_NOTES, examples/data/world/characters/Shroom_the_Hag.ghul, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Attic/game.c: + --When npc parties are asleep they show a different sprite (if any species in + the party has a 'sleep_sprite' specified) + +2003-07-01 Gordon McNutt + + * Attic/RELEASE_NOTES, examples/data/def_constants.ghul, examples/data/types.ghul, examples/data/images/mine-32x32.png, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/world/places/GreenTower.ghul, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/map.c, src/map.h, src/object.h, src/place.c, src/play.c, src/player.cpp, src/player.h: + CHECKIN_NOTES + + * examples/data/images/mine-32x32.png, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/sprite_sets/ultima_IV_sprite_set.ghul: + ../CHECKIN_NOTES + +2003-06-30 Sam Glasby + + * examples/data/player/party.ghul, examples/data/types/readable_items.ghul: + Added a Map Editors guide document in-game. + + * examples/data/types/readable_items.ghul: + Added more info to the Map Editors Guide document. + +2003-06-30 Gordon McNutt + + * Attic/RELEASE_NOTES, Attic/configure, doc/GHULSCRIPT, examples/data/types/npc_party_defs.ghul, examples/data/types/species.ghul, examples/data/types/weapons.ghul, examples/data/world/characters/party_members.ghul, examples/data/world/maps/M_slime_cave.ghul, examples/data/world/places/P_slime_cave.ghul, examples/data/world/places/P_wilderness.ghul, examples/data/world/places/all_places.ghul, src/Attic/NpcParty.cpp, src/character.cpp, src/character.h, src/combat.c, src/place.c, src/species.c, src/species.h: + CHECKIN_NOTES + +2003-06-29 Sam Glasby + + * examples/data/types.ghul, examples/data/types/spells.ghul: + Removed the unused REAGENT_TYPE() macro. + + * examples/data/types.ghul, examples/data/types/useable_items.ghul: + Moved the ITEM_TYPE() macro. Reformatting. Added POTION_TYPE() macro. Increased torch duration from 1000 to 5000. + + * examples/data/types.ghul, examples/data/types/projectiles.ghul: + Moved the (unused?) AMMO_TYPE() macro. + + * examples/data/types.ghul, examples/data/types/weapons.ghul: + Moved the ARMS_TYPE() macro and went over weapons macros by type. + + * examples/data/types.ghul, examples/data/types/chest_traps.ghul: + Moved the TRAP_TYPE() macro to where it is used. + + * examples/data/types.ghul, examples/data/types/magical_fields.ghul: + Moved the FIELD_TYPE() macro to where it is used. + + * examples/data/player/party.ghul, examples/data/sprite_sets/angband_sprite_set.ghul, examples/data/types/worn_items.ghul: + Macro-ized worn items. Added some new types of helm, body armor, boots. + + * examples/data/types/projectiles.ghul: + Changed projectiles to use a PROJECTILE_TYPE() macro. + + * examples/data/types/readable_items.ghul: + Added DOCUMENT_TYPE() macro. + + * src/combat.c: + Added display of range/reach for ranged/melee attacks to the + UI prompt when making an attack. + + * src/common.h: + Removed a kludge #ifdef block. + +2003-06-29 Gordon McNutt + + * Attic/RELEASE_NOTES, Attic/RELEASE_NOTES, Attic/RELEASE_NOTES, Attic/RELEASE_NOTES, examples/data/types/vehicles.ghul, examples/data/world/places/P_terrain_test.ghul, src/combat.c, src/common.c, src/common.h, src/cursor.cpp, src/cursor.h, src/Attic/game.c, src/map.c, src/place.c, src/play.c, src/player.cpp, src/player.h: + CHECKIN_NOTES + +2003-06-28 Sam Glasby + + * examples/data/player/party.ghul, examples/data/types/readable_items.ghul, examples/data/types/worn_items.ghul, examples/data/world/places/P_terrain_test.ghul: + Added a couple items. Added placed objects to p_terrain_test. Minor formatting, a couple of spelling fixes. + + * examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/P_terrain_test.ghul: + Added a invisible lever mechanism and an example of its use. + + * examples/data/world/mechanisms/all_mechanisms.ghul: + Minor formatting. + + * examples/data/world/mechanisms/all_mechanisms.ghul: + Converted all door-like mechanisms to use the MAKE_DOORLIKE_MECH() macro. + + * examples/data/world/places/P_rom_camp.ghul: + Corrected a comment. + + * src/play.c: + Added notes to detailed_examine_XY() for future implementation. + +2003-06-27 Sam Glasby + + * Attic/RELEASE_NOTES: + Updated RELEASE_NOTES with info on the palette+map saving command. + + * examples/data/types/npc_party_defs.ghul, examples/data/types/species.ghul, examples/data/types/weapons.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/P_rom_camp.ghul: + Added horses to the gypsy camp, and a new doorlike mechanism for a fence gate. + + * examples/data/types/portal_types.ghul, examples/data/world/portals.ghul, examples/data/world/places/P_cavernous_troll_deeps.ghul, examples/data/world/places/all_places.ghul: + Created a new dungeon. + + * examples/data/types/portal_types.ghul: + Added a new portal type t_standing_portal. + + * examples/data/world/maps/M_blank_16x16.ghul: + Added a new map template of size 16x16. + + * examples/data/world/maps/M_blank_32x32.ghul, examples/data/world/maps/M_blank_64x64.ghul: + Fixed palette name + + * examples/data/world/maps/M_blank_32x32.ghul, examples/data/world/maps/M_blank_64x64.ghul: + Added a couple of blank map templates. + + * examples/data/world/places/P_rom_camp.ghul, examples/data/world/places/all_places.ghul: + Added a gypsy (Rom) camp. + + * src/common.h, src/cursor.cpp, src/play.c: + Some polish on cursor range things. + + * src/play.c: + Polish and messages for Save Map command. + + * src/play.c, src/terrain.c, src/terrain_map.c, src/terrain_map.h: + Added a map- and palette-saving command which saves the current map and palette to files as GhulScript. + +2003-06-26 Sam Glasby + + * src/cursor.cpp, src/cursor.h, src/map.c, src/map.h, src/play.c: + Added mapTileIsWithinViewport() and Cursor::setViewportBounded(). + Changed Cursor::move() and the Xamine and Terraform commands to make + use of these. + + The Xamine and Terraform commands now have a cursor range which allows + for the viewing/alteration of any tile on the viewport. + + * src/play.c, src/play.h, src/terrain.c, src/terrain.h: + Simplified and improved the terrain_palette API. + Improved the UI of Terraform (Home/End, quick terrain get/set) + + * src/terrain.h: + Simplified the internals of quick_terrain in terrain palettes. + +2003-06-25 Sam Glasby + + * Attic/RELEASE_NOTES, examples/data/types/terrains.ghul, src/event.h, src/play.c, src/terrain.c, src/terrain.h: + Implemented actual terrain editing in the (^T)erraform command. + The command is bound to CONTROL-T, and invokes a UI cursoring mode + in which PageUp/PageDown cycle through terrain to draw with (in the + current terrain_palette) and (SPACE | ENTER | RETURN) alters terrain. + + The next step is more UI refinements, and command which saves the + current map and palette. + + * examples/data/player/party.ghul, examples/data/types/terrains.ghul, examples/data/types/vehicles.ghul, examples/data/world/maps/M_dark_passage.ghul, examples/data/world/maps/M_secret_shrine.ghul, examples/data/world/maps/terrain_combat_maps.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/DarkPassage.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/GreenTowerLower_Map.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul, examples/data/world/places/P_terrain_test.ghul, examples/data/world/places/P_wilderness.ghul, src/combat.c, src/common.h, src/Attic/game.c, src/terrain_map.c: + PALETTE is now a top-level keyword, + and the palette {} blocks in MAP {} have been + replaced with a palette field taking a palette tag. + + Also, terrain_map_clone() finally properly fixed, + and all maps and palettes in examples/data/ changed + to match the new GhulScript syntax. + + * src/combat.c, src/conv.c, src/event.c, src/event.h, src/play.c, src/play.h: + Added keymod support to KeyHandler struct and functions. + + Added a skeletal (^T)erraform command, bound to CONTROL-T. + Currently it only prints messages and does not alter terrain. + Checking it in becaues the KeyHandler support touched several files. + The next checkin should add actual editing of terrain. + + * src/combat.c: + Commented out some debugging output. + + * src/combat.c, src/play.c: + Improvements to messages for enter/exit zoom-in maps. Remapped the < and \ keys to > and < for consistency with roguelikes. + + * src/event.c: + Minor change in eventHandler(). + + * src/play.c: + More tweaking of zoom-in messages. + + * src/play.c: + Minor improvements to the Xamine and AT commands: + + Xamine now looks at the party / invoking character tile + before any cursor movement is done. + + AT now prints blank seperator lines above and below + its main output. + + * src/terrain_map.c: + Fixed up terrain_map_print() somewhat. + +2003-06-23 Sam Glasby + + * examples/data/types/terrains.ghul, src/Attic/game.c: + Added a new top-level keyword PALETTE. + This keyword is not used yet (coming next checkin) + but will replace the per-map palettes currently used. + +2003-06-21 Sam Glasby + + * scripts/run_nazghul: + Added information to the comment header. + + * scripts/timesort_data, scripts/timesort_src, scripts/touch_all_src: + Added scripts which use (touch, ls -tr, find) to help know which files you have modified during a hacking session. + + * src/terrain_map.c: + Fixed a picky, anal, pedantic C++ typecast on malloc(). + Curse you C++, curse you... + + * src/terrain_map.c: + Fixed a bug with terrain_map_clone(). + A cloned terrain_map should be given a tag, to facilitate later saving. + Tags should be unique(ish) however. + This change gives a clone of a map with tag "foo" a new tag "foo_c". + + * src/terrain_map.c: + Added some notes about terrains with "facing" + (such as diagonal wall corner pieces) + which we may desire to support in future. + +2003-06-20 Sam Glasby + + * examples/data/world/places/P_wilderness.ghul, src/combat.c, src/common.c, src/common.h, src/Attic/game.c, src/terrain.c, src/terrain.h, src/terrain_map.c: + Added a 'palette' field to terrain_map, for saving same. + + Changes which ensure that every terrain_map has a palette. + Currently this is a best-effort solution; there exists at + least one case (merging two maps such as terrain combat map + + vehicle map, that is done by overlay_map() I believe; + terrain-blitting mechs could do this also, I think.) + where, due to terrain being blitted from a map with another + palette (said terrain not present in the main map palette), + terrain can exist on a map which is not present in the palette. + + In such cases, I soft-fail when writing the MAP {}, + using ? or ?? or the like for any not-in-palette + terrain and adding a comment in the generated GhulScript + which notes that this was done. This will not be sufficient + for the needs of 'save game', but is still very useful for + a map editor, where human hands can fix up the palette afterwards. + + As to how to implement the Right Thing (TM), this brings up + some design questions. Once terrain palettes are globally + scoped entities, rather than being defined for each MAP {}, + there is no truly compelling reason to have more than one + palette; or at least one palette per glyph-width. On the + other hand, there is no truly compelling reason to rip out + multiple palette functionality right now. In the near future + (0.3.x branch), we should decide what is best. Multiple palettes + would require palette-merging of moderate sophistication. + Such code is easy enough to write, but the requirement that it + never fail or generate an invalid palette is rather taxing. + + In any event, here is one more step towards a map editor in-game. + + * scripts/ghul-indent: + Read the manpage, added some whitespace-modifying items, + and the "no tabs, use spaces instead" option. + Changed to using long-form options. + Un-cuddled '} else' + +2003-06-19 Sam Glasby + + * Attic/RELEASE_NOTES, src/Attic/game.c, src/terrain.c, src/terrain.h, src/terrain_map.c, src/terrain_map.h: + Added a map-printing function terrain_map_print() which can output + GhulScript for a MAP. Work remains to be done, including making + sure that every terrain_map has its' palette field properly filled + out, and connecting the palette_print() function. (Or better yet, + making palettes globally-scoped entities rather than per-map.) + + * Attic/RELEASE_NOTES, examples/data/player/party.ghul, examples/data/types/vehicles.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/GreenTowerLower_Map.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_wilderness.ghul, src/Attic/game.c, src/terrain.h: + Finished converting game_load_ascii_terrain_map() to use + string-oriented terrain {} block parsing rather than + Loader::getRaw(). + + Now, both compact one_char_per_tile maps and single/multi-byte + palette non-compact maps work alike. That is, each line is a quoted + string. + + * src/character.cpp: + Added \n to a debug message. + + * src/terrain_map.c: + Un-snarled a diagram in a comment illustrating map rotation. + +2003-06-19 Gordon McNutt + + * BUGS, Attic/configure: + One more update to BUGS + + * BUGS, INSTALL, Attic/RELEASE_NOTES: + Updated INSTALL and BUGS + + * Attic/configure.in, src/nazghul.c: + Updated version number to 0.1.2 + +2003-06-18 Sam Glasby + + * examples/data/player/party.ghul, examples/data/types/terrains.ghul, examples/data/types/vehicles.ghul, examples/data/world/maps/M_dark_passage.ghul, examples/data/world/maps/M_secret_shrine.ghul, examples/data/world/maps/terrain_combat_maps.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/DarkPassage.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul, examples/data/world/places/P_terrain_test.ghul, src/Attic/game.c, src/terrain.c, src/terrain.h: + Changed terrain palettes and terrain blocks in MAP constructs + (when multi-byte map is specified) to use different parsing code. + The new parsing code uses getString() rather than getRaw(). + + This fixes several bugs pertaining to palette and map loading. + + TODO: Fix single-byte (compact) maps to work in the same way, + and the *.ghul that define such maps to match. + + * src/common.h: + This belongs with the previous commit, + with the parsing changes for terrain palette and terarin blocks. + + The only change in this file is a small hack workaround for + a global terrain palette, which I am going to remove in the + very near future. I am only checking this in for completeness, + my tests showed that CVS built and ran OK without this. + +2003-06-18 Gordon McNutt + + * Attic/RELEASE_NOTES, src/map.c: + --Added support for the sleep effect to items (previously only spells). + + --Party leader is now reevaluated every time some part of the code asks about + it (I use to try to cache the leader, but this makes things too + complicated). Also, if the leader falls asleep the next in command takes + over. + + --Fixed sleep fields in combat. Looks they were never processed + correctly. + + --Removed the 'find party' and 'find edge' requirements in combat + placement. Not sure if this will break something or not, but I decided to do + this when I found that nixies could not get distributed on a bridge combat + map. That's just silly, and most of that placement code was written back in + the day when I wanted the engine to do more ass-covering for map hackers. So + I removed it. We'll see what happens. + + --Fixed the "In Lor" spell by making the caster the default spell + target. Apparently I commented that line of code out for some reason but I + don't know why. Should have left a note. This time, I did. + + --Bugfix: the character describe method assumed the character had an + occupation. Some npc characters in the example game don't have an + occupation. For example, insects in a swarm. + + --Bugfix: charmed opponents continued to attack the party. This was a bug + introduced some time ago when I had characters remember their previous + targets so that stepping out of LOS would not make them start to wander + aimlessly. We needed to check if we were still hostile to these remembered + targets. + + --Bugfix: npcs standing on los-blocking terrain in combat no longer blind + + --Bugfix: wave sprites now rendered properly when peering (zoomed out by a + factor of two). There were several bugs contributing to this. + + --Added a level beneath Green Tower (to test some spells, but I think I'll keep + it). + + --Fixed map-wrapping bug in vehicle weapon firing. + + --Removed derived objects examples/mapfile and examples/data/mapfile from CVS. + + --Bugfix: x)amine los-checking did not work across map boundaries. + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/images/mine-32x32.png, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/types/terrains.ghul, examples/data/types/vehicles.ghul, examples/data/world/places/GreenTower.ghul, src/vehicle.cpp, src/vehicle.h: + --Added support for the sleep effect to items (previously only spells). + + --Party leader is now reevaluated every time some part of the code asks about + it (I use to try to cache the leader, but this makes things too + complicated). Also, if the leader falls asleep the next in command takes + over. + + --Fixed sleep fields in combat. Looks they were never processed + correctly. + + --Removed the 'find party' and 'find edge' requirements in combat + placement. Not sure if this will break something or not, but I decided to do + this when I found that nixies could not get distributed on a bridge combat + map. That's just silly, and most of that placement code was written back in + the day when I wanted the engine to do more ass-covering for map hackers. So + I removed it. We'll see what happens. + + --Fixed the "In Lor" spell by making the caster the default spell + target. Apparently I commented that line of code out for some reason but I + don't know why. Should have left a note. This time, I did. + + --Bugfix: the character describe method assumed the character had an + occupation. Some npc characters in the example game don't have an + occupation. For example, insects in a swarm. + + --Bugfix: charmed opponents continued to attack the party. This was a bug + introduced some time ago when I had characters remember their previous + targets so that stepping out of LOS would not make them start to wander + aimlessly. We needed to check if we were still hostile to these remembered + targets. + + --Bugfix: npcs standing on los-blocking terrain in combat no longer blind + + --Bugfix: wave sprites now rendered properly when peering (zoomed out by a + factor of two). There were several bugs contributing to this. + + --Added a level beneath Green Tower (to test some spells, but I think I'll keep + it). + + --Fixed map-wrapping bug in vehicle weapon firing. + + --Removed derived objects examples/mapfile and examples/data/mapfile from CVS. + + * examples/data/world/characters/Shroom_the_Hag.ghul, examples/data/world/places/GreenTowerLower.ghul, examples/data/world/places/GreenTowerLower_Map.ghul: + Forgotten files + + * scripts/run_nazghul: + Adding Sam's run script + +2003-06-17 Gordon McNutt + + * BUGS, Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/types/species.ghul, examples/data/types/spells.ghul, examples/data/types/useable_items.ghul, examples/data/world/astronomy.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/P_wilderness.ghul, examples/data/world/places/all_places.ghul, src/Attic/Item.cpp, src/Attic/NpcParty.cpp, src/character.cpp, src/combat.c, src/map.c, src/play.c, src/player.cpp, src/screen.c, src/sky.c, src/sprite.c, src/sprite.h: + --Added support for the sleep effect to items (previously only spells). + + --Party leader is now reevaluated every time some part of the code asks about + it (I use to try to cache the leader, but this makes things too + complicated). Also, if the leader falls asleep the next in command takes + over. + + --Fixed sleep fields in combat. Looks they were never processed + correctly. + + --Removed the 'find party' and 'find edge' requirements in combat + placement. Not sure if this will break something or not, but I decided to do + this when I found that nixies could not get distributed on a bridge combat + map. That's just silly, and most of that placement code was written back in + the day when I wanted the engine to do more ass-covering for map hackers. So + I removed it. We'll see what happens. + + --Fixed the "In Lor" spell by making the caster the default spell + target. Apparently I commented that line of code out for some reason but I + don't know why. Should have left a note. This time, I did. + + --Bugfix: the character describe method assumed the character had an + occupation. Some npc characters in the example game don't have an + occupation. For example, insects in a swarm. + + --Bugfix: charmed opponents continued to attack the party. This was a bug + introduced some time ago when I had characters remember their previous + targets so that stepping out of LOS would not make them start to wander + aimlessly. We needed to check if we were still hostile to these remembered + targets. + + --Bugfix: npcs standing on los-blocking terrain in combat no longer blind + + --Bugfix: wave sprites now rendered properly when peering (zoomed out by a + factor of two). There were several bugs contributing to this. + + --Added a level beneath Green Tower (to test some spells, but I think I'll keep + it). + +2003-06-15 Gordon McNutt + + * BUGS, Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul, src/Attic/Mech.cpp, src/Attic/Mech.h: + --Bugfix: circular mech activation now has some crude + (over)protection. Connecting two lights spaceship-style in no longer causes + the engine to crash on stack overflow. + + * Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, src/play.c: + --Bugfix: combat resulting from a conversation was not placing the opponent on + the combat map. This broke when I made towns function in party mode like the + wildernesses. Before that change combat just occurred in town so I didn't + need to setup the npc party in the combat map. + + * Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/types/occupations.ghul, src/Attic/NpcParty.cpp, src/place.c, src/place.h: + --Added a druid class. + + --Npc parties in wander mode no longer walk over hazardous terrain. I was + getting concerned about Shroom walking around in the firepit at the White + Stag Lodge. :-) + + * Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/world/places/GreenTower.ghul, src/Attic/NpcParty.cpp, src/conv.c: + --Added a new character to Green Tower. Shroom the Hag owns the reagent shop. + + * Attic/RELEASE_NOTES, src/cmdwin.c, src/console.c, src/play.c, src/player.cpp: + --New feature in the console. If a message is a repeat of the last one then + instead of printing it again the console will print a notice of how many time + the message has repeated so far. Also changed the way "slow progress" and + friends are reported so that it takes advantage of this feature. + + * Attic/RELEASE_NOTES, src/cmdwin.c, src/cmdwin.h, src/combat.c, src/play.c: + --The final contents of the cmdwin are now shown on the main console. + +2003-06-14 Sam Glasby + + * examples/data/player/party.ghul, examples/data/types/terrains.ghul, examples/data/types/vehicles.ghul, examples/data/world/maps/M_secret_shrine.ghul, examples/data/world/places/P_empire_city.ghul, src/Attic/game.c, src/terrain.c, src/terrain.h: + Changed the implementation of terrain palettes. + Added print functionality for terrain palettes and + for terrain palette entries. + Got rid of the glyph field of terrains + Palettes now have a palette tag + Changed world data to match + (all map palettes are now named, no glyph field in TERRAIN() macro.) + +2003-06-14 Gordon McNutt + + * BUGS, Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/sprite_sets/moons_sprite_set.ghul, examples/data/sprite_sets/ultima_IV_font_sprite_set.ghul, examples/data/world/astronomy.ghul, src/Attic/Mech.cpp, src/common.h, src/Attic/game.c, src/play.c, src/player.cpp, src/sky.c, src/sky.h, src/terrain.c, src/terrain.h: + --Fixed some issues with sunrise/sunset. The sun now begins to appear in the + sky window at sunrise, and is completely gone by sunset. The light fades in + and out over the space of the first hour after sunrise and before sunset, + respectively. The code to calculate sunlight now uses a single consistent + forumula, and does so for the moons as well as the sun (more on that below). + + --The moons now provide light depending on their arc and phase. They can + provide at most 128 light units, whereas the sun can provide 255 (max is 255 + due to the way the lightmap gets built in map.c). So even with a full moon + things are a bit dim. + + --Replaced the u4 moon sprites with my own, since mine are 16x16 and u4 is + only 8x16. Makes the full moons look full. + + * BUGS, Attic/RELEASE_NOTES, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/play.c: + --If the player attacks a non-hostile npc party then the target's alignment + bits are cleared from the player's alignment bits. In other words, the npc + party and all of its allies are now the player's enemies. If you attack a + townsperson all the other townspeople and the guards will attack you if they + can. Note that they still aren't smart enough to pathfind through impassable + mechanisms, so a door is enough to hold them off. + + * BUGS, Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, src/play.c: + --Added the (a)ttack command for towns and wilderness. If the target is + non-hostile it prompts the player for confirmation. + +2003-06-13 Sam Glasby + + * examples/data/types/terrains.ghul, src/Attic/game.c, src/terrain.c, src/terrain.h: + Obsoleted the 'glyph' field in 'struct terrain' + Moved 'struct terrain_palette' to terrain.h + Some notes and such. + + * examples/data/world/astronomy.ghul: + Added some notes on the value of arc for the sun. + + * src/Attic/game.c: + Added some notes prior to implementing NULL terrain support + for (terrain, terrain_palette, terrain_map). + + * src/play.c: + Polished the use of mapTileIsVisible() in cmdXamine(). + + * src/terrain.c: + Added some notes where the 'struct terrain' API seemed inconsistent. + + * src/terrain.h: + Notes and formatting + + * src/Attic/util.h: + The removal of #include "common.h" from this file + prevented compilation. Perhaps it is better for the other + files which want common.h to #include it themselves + (hash.c, others) but for now I desire that CVS compile. + +2003-06-13 Gordon McNutt + + * BUGS, Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/world/astronomy.ghul, examples/data/world/places/GreenTower.ghul, examples/data/world/places/all_places.ghul, src/Attic/util.h: + --Added start of a new town: Green Tower + + * examples/data/world/places/GreenTower.ghul: + Map upgrade. + +2003-06-12 Sam Glasby + + * examples/data/def_constants.ghul, examples/data/types/terrains.ghul: + Moved all the Terrain stuff into terrains.ghul except pmask macros, which are used elsewhere + + * examples/data/def_constants.ghul, examples/data/types.ghul, examples/data/sprite_sets/rune_font_sprite_set_32x32.ghul, examples/data/sprite_sets/ultima_IV_sprite_set.ghul, examples/data/types/terrains.ghul, examples/data/types/vehicles.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_terrain_test.ghul, examples/data/world/places/all_places.ghul: + Much work on terrain types. Macro-ization, rearrangement, + improved ship combat map, made a new STD_EXPANDED_PALETTE, + and added a new place P_terrain_test + + * examples/data/def_macros.ghul, examples/data/types.ghul: + Moved macros to where they were used. + + * examples/data/types.ghul: + Formatting improvements for internal documentation. + + * examples/data/sprite_sets/rune_font_sprite_set_8x16.ghul: + Fixed the path to the image file from "images/" to "data/images/" + + * src/Attic/Mech.cpp: + Turned off some verbose debug output. + +2003-06-12 Gordon McNutt + + * BUGS, Attic/RELEASE_NOTES, doc/GHULSCRIPT, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/types/terrains.ghul, examples/data/world/astronomy.ghul, examples/data/world/places/P_wilderness.ghul, src/angband.c, src/map.c, src/map.h, src/play.c, src/sky.c: + --Added a campsite map, campsite formation and party formation to the examples + file. Increased the light from a fireplace, too. + + --Added a new function in map: mapTileIsVisible checks if a tile is visible + under the LOS rules. + +2003-06-11 Sam Glasby + + * examples/data/types/readable_items.ghul: + Added Xamine and AT commands to the "Users Guide to Nazghul" + + * src/character.cpp, src/character.h, src/combat.c, src/play.c, src/status.c: + // Added pmask to Ztats display + // Added ammo display to Attack prompt + // Require confirmation for attack self + // (and attack ally, in near future) + // Changed the key to exit combat from ESCAPE to '\' + // Improved a few prompts + + * src/combat.c, src/common.h, src/map.c, src/map.h, src/play.c, src/play.h, src/sky.c, src/sky.h: + New command AT which displays party-centric information. Lots of astronomy functions stuff related to this as well. + + * src/combat.c, src/event.h, src/play.c: + Refactored the Xamine command to un-munge struct KeyHandler for future expansions + + * src/play.c: + Look, Xamine, Ztats, AT take zero turns, improved some prompts + +2003-06-11 Gordon McNutt + + * BUGS, Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world/places/P_wilderness.ghul, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Attic/Spell.cpp, src/combat.c, src/Attic/game.c, src/map.c, src/object.c, src/play.c: + --Fixed a memory leak. NpcParty objects were not being deleted after combat + except in the case where the NpcParty initiated combat. Added a new flag to + the NpcParty class: 'destroy_on_combat_exit'. By default it is true. In the + case where the NpcParty initiates combat it sets it to false before entering + combat. After combat the NpcParty will be deleted once it returns to the code + in place.c which updates objects every turn. + + * Attic/RELEASE_NOTES, doc/GHULSCRIPT, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world/astronomy.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_wilderness.ghul, src/play.c, src/sound.c: + --Fixed a crash that occurred on startup if the --sound 0 option was + specified. + +2003-06-08 Gordon McNutt + + * Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world.ghul, src/Attic/NpcParty.cpp, src/combat.c, src/combat.h, src/common.h, src/Attic/game.c, src/vehicle.cpp: + --Added a COMBAT section to the script. Currently this is only used to declare + the sound files used in combat for events like entry, defeat and victory. + + --Fixed a bug introduced when I fixed cannons firing in town. The npc code was + not properly incrementing turns when it fired cannons. + + --When npc vehicle weapons hit an npc party it was printing "You hit ", as if + the player was doing the firing. Changed the message from "you" to whatever + the name of the weapon being fired. + + * Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/types/species.ghul, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/character.cpp, src/character.h, src/combat.c, src/map.c, src/map.h, src/object.c, src/object.h, src/place.h, src/play.c, src/player.cpp, src/sound.c, src/sound.h, src/species.c, src/species.h, src/vehicle.cpp: + --Added sound attenuation with distance (hearing the nixies splash around gets + really annoying when you can't get away from it - need to find some better + sounds). I only made it apply in party mode because in combat mode it's a bit + trickier for the code that's playing the sound to figure out which party + member it needs to calculate the distance from. Since dungeons are not party + mode I'll probably want to reconsider how to do that. + + * Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/types/species.ghul, examples/data/world/characters/Olin_the_Ghast.ghul, examples/data/world/characters/inhabitants_of_britain.ghul, src/Attic/Loader.cpp, src/Attic/Loader.h, src/character.cpp, src/character.h, src/sound.c, src/species.c, src/species.h: + --Fixed bugs related to playing a sound when damage is inflicted. Previously it + was a hardcoded hack that broke a while back when we split the data files + into their own directory. The fix was to add an optional 'damage_sound' field + to both the SPECIES and CHAR declarations. When a character receives damage + it will first check if it has its own special damage sound to play, otherwise + it will check if its species has a damage sound to play, otherwise it doesn't + play anything. This works in the case of damaging npc parties, too (for + example with ship cannons) because npc party damage calls the character + damage routines. In the examples I modified all species to play the old + traditional damage sound. + +2003-06-07 Gordon McNutt + + * BUGS: + Added a BUGS file for per-release bug info + + * INSTALL, Attic/configure, Attic/configure.in, src/nazghul.c: + Updated INSTALL and configure.in in preparation for release 0.1.1 + + * Attic/RELEASE_NOTES, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/types.ghul, examples/data/types/projectiles.ghul, examples/data/types/vehicles.ghul, src/common.h, src/place.c, src/place.h, src/play.c, src/player.cpp, src/player.h, src/vehicle.cpp: + --Fixed the bug Sam reported about firing cannons in town. Whenever the cannon + was fired the turns were updates as if the party was in the wilderness, not + town. So about 64 turns passed, and if any hostiles happened to be nearby you + would immediately enter combat. Also spruced up the messages shown when + firing and fixed the cannonball sprite (finally :-)) in the examples. + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/types/readable_items.ghul: + Removed the old notes which referred to LB and SH + +2003-06-06 Gordon McNutt + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul, src/Attic/Mech.cpp, src/Attic/Mech.h, src/object.h, src/place.c: + --Changed the way mechs are described. From now on, the mech state name is an + adjective. This adjective is applied to the mech name when the mech is + described. For example, if a "door" mech is in a "closed" state then the + l)ook or x)amine commands will describe it as "a locked door" (the articles + 'a' and 'an' are automatically derived by the engine's code for describing + objects). If the mech has no state, or if the state has no name, then simply + the mechanism name is used. E.g., "a door". I updated all the mechs in the + example game so that they are described nicely now. + + --I also added a new optional field to mechanism states: 'invisible'. By + default it is false. When true the mechanism is not shown on the map and it + is not described by l)ook or x)amine. However, if Reveal is in effect (Wis + Quas in the current magic system), then the mechanism is described and - if a + sprite is available - rendered. + + --Closed moongates are not described by l)ook or x)amine unless Reveal is in + effect. + +2003-06-05 Gordon McNutt + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world.ghul, examples/data/world/maps/terrain_combat_maps.ghul, examples/data/world/places/P_wilderness.ghul: + --Created a combat map for east-west bridges (combat looks kind of funny when + half the map has been terrain-filled with bridge icons ;)). + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/cursor.cpp, src/place.c: + --Sam found some bugs in cursor movement related to map-wrapping. Fixed those + and added a regression test for this case. + + --If an npc party is in a vehicle, the l)ook and x)amine commands will now say + so. + + * examples/Attic/mapfile, examples/data/def_constants.ghul, examples/data/Attic/mapfile, examples/data/types/portal_types.ghul, examples/data/world/portals.ghul, examples/data/world/places/DarkPassage.ghul, src/character.cpp, src/combat.c: + --Previously party members could switch places if one bumped another one on the + map. But if passability constraints didn't permit the switch then the move + simply failed. In order to get us out of some corner cases I modified this so + that if passability checks fail then the move succeeds and the mover is + simply stacked on the same tile as the other member. We already stack to + solve passability problems on dungeon entrance, so this just extends the + scope of that compromise. + + --Implemented the new dungeon exit rules regarding portal entry: the party must + be in party mode, all members must be able to rendezvous at the portal, and + the exit takes effect atomically (i.e., everybody exits at once via the + portal or nobody at all gets to go through the portal). This concludes the + new player movement algorithm. And that calls for a beer. + + * src/character.cpp, src/character.h, src/object.c, src/object.h, src/place.c, src/play.c, src/player.cpp, src/player.h, src/vehicle.cpp: + --Fixed the L)ook and X)amine output to be for the most part correct. We still + need to make up our minds on what to print for mechanisms, but other than + that the output should be correct. + + --Also resynched the layer enumeration in object.h and the LAYER_* #defines in + examples/data/def_constants.ghul (we really need to fix this dependency). I + did this so that the cursor would not be described by the l)ook or x)amine + commands. Note that if they get out of synch again we might see the cursor + being described and things kept at a nother layer NOT described, so watch for + this. + +2003-06-04 Sam Glasby + + * examples/data/sprite_sets/misc_added_sprite_set.ghul: + Minor formatting fix (removed duplicate ;;) + + * examples/data/world/maps/terrain_combat_maps.ghul: + Changed the m_water_combat map to 32x32 to match the rest. + + * examples/data/world/places/P_empire_city.ghul: + Changed the castle_bay_portcullis lever's initial state + to match the terrain initial state. (Minor tweak) + + * src/combat.c, src/cursor.cpp, src/event.h, src/play.c, src/play.h: + Added an (X)amine command, which is an extended (L)ook. And some notes ton the Cursor API. + +2003-06-04 Gordon McNutt + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world/places/P_empire_city.ghul, src/play.c, src/player.cpp, src/player.h: + --Added a minor hack to force the game into dungeon mode if it loads up with + the player party starting out in a dungeon. Previously the party would be in + the dungeon, but it would be in party mode. The new game rules forbid party + mode in a dungeon. + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/world/portals.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul, src/combat.c, src/place.c: + --Discovered that "follow mode" did not work correctly when the party leader + moved north or east. Not sure how long that's been like that, but I fixed it + in place.c. + + --Fixed a crash when entering a dungeon from another dungeon. The combat code + was tring to derefence the party's current place to check for an unboarded + vehicle (this is necessary for town/wilderness combat), but the last dungeon + entry erased the current place. This seems to be the only place combat code + tries to find the party's current place without first checking that it is + town or wilderness combat. Fixed it by simply skipping the vehicle test if + the party's current place is null. + + --Added another dungeon, "Dark Passage", with links both to the Prison Chamber + and to the surface of Empire City. Tested moving between them all and + everything seems ok for the simple cases. + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world/characters/BlackBart_the_Shipwright.ghul, src/Attic/NpcParty.cpp, src/place.c, src/place.h: + This checkin fixes all known problems with creating temporary combat maps. + + --The combat algorith now always combines the map derived from the player + party's tile with the map derived from the npc party's tile. Before it only + did this when it was creating filled maps from the terrain, not it will use + the combat map specified for the terrain, too. + + --Terrain combat maps are now required to be at least COMBAT_MAP_W x + COMBAT_MAP_H in size (currently set to 32 x 32 in combat.h). The combat code + will assert if a map is too small, but before that happens the parser code + will catch it at load time. + + --Fixed the old combat maps for forest and grass to be 32 x 32 (didn't touch + Sam's new water map - he may want to make his own changes at this point). + + * examples/data/world/places/DarkPassage.ghul: + Forgot to check this in + + * src/character.cpp, src/character.h, src/combat.c: + --Changed combat party positioning code. When entering combat, if a party + member cannot find a safe position then it will default to the party's + "start" location. This means that party members can get stacked, and that + they can get stranded on combat maps. But it also means that entry to combat + or dungeons is guaranteed to work, and this simplifies the movement algorithm + tremendously. + +2003-06-03 Gordon McNutt + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world.ghul, examples/data/player/party.ghul, examples/data/world/maps/terrain_combat_maps.ghul, src/combat.c, src/combat.h, src/Attic/game.c: + This checkin fixes all known problems with creating temporary combat maps. + + --The combat algorith now always combines the map derived from the player + party's tile with the map derived from the npc party's tile. Before it only + did this when it was creating filled maps from the terrain, not it will use + the combat map specified for the terrain, too. + + --Terrain combat maps are now required to be at least COMBAT_MAP_W x + COMBAT_MAP_H in size (currently set to 32 x 32 in combat.h). The combat code + will assert if a map is too small, but before that happens the parser code + will catch it at load time. + + --Fixed the old combat maps for forest and grass to be 32 x 32 (didn't touch + Sam's new water map - he may want to make his own changes at this point). + +2003-06-02 Sam Glasby + + * examples/data/def_constants.ghul, examples/data/world.ghul, examples/data/sprite_sets/mechanism_sprites.ghul, examples/data/types/npc_party_defs.ghul, examples/data/types/occupations.ghul, examples/data/types/species.ghul, examples/data/world/maps/terrain_combat_maps.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_wilderness.ghul: + 2003/06/01 -- map changes, nixies, mechanism macros and sprites + +2003-06-02 Gordon McNutt + + * doc/USERS_GUIDE: + Updated the section on magic in the USERS_GUIDE to match the current example game + + * examples/Attic/mapfile, examples/data/def_constants.ghul, examples/data/Attic/mapfile, examples/data/player/party.ghul, src/Attic/Mech.cpp, src/place.c: + Fixed passability problems with mechs. + + * src/combat.c, src/place.h, src/player.cpp, src/player.h: + --First pass at new dungeon support. Party correctly enters and exits an empty + dungeon with only one entrance. Haven't tested other cases yet. + +2003-06-01 Gordon McNutt + + * doc/Attic/GAME_DEVELOPERS_GUIDE, doc/MAP_HACKERS_GUIDE: + Moved a doc + + * doc/USERS_GUIDE: + Updated for 0.2.0 release + + * examples/Attic/mapfile, examples/data/def_constants.ghul, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/types/species.ghul, examples/data/types/terrains.ghul, examples/data/types/vehicles.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/P_empire_city.ghul: + --Added SOLID as a passability bit to the examples and modified most currently + impassable terrain and impassable mech states to use it. Also uodated all + literal constant passability masks to use macros. + + --Added pretty much all bits to the ghast passability mask. This allows them to + walk through walls, over water, etc. + + --Added Olin to Empire City and gave him a schedule and a conversation tree, + including an option to join the party. + + --Removed WATER from the gazer pmask (still has SHOALS, though) + + --Added a mortuary and crypt to Empire City. + + --Removed the pmask field in the player party definition. This field is now + obsolete - the engine will use the intersection of the party member's pmasks + to compute party passability. + + * examples/data/def_constants.ghul, examples/data/def_macros.ghul, examples/data/main.ghul, examples/data/types.ghul, examples/data/world.ghul, examples/data/player/party.ghul, examples/data/sprite_sets/angband_sprite_set.ghul, examples/data/sprite_sets/frame_sprite_set.ghul, examples/data/sprite_sets/mechanism_sprites.ghul, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/sprite_sets/moons_sprite_set.ghul, examples/data/sprite_sets/rune_font_sprite_set.ghul, examples/data/sprite_sets/rune_font_sprite_set_32x32.ghul, examples/data/sprite_sets/rune_font_sprite_set_8x16.ghul, examples/data/sprite_sets/sam_new_tiles_32x32.ghul, examples/data/sprite_sets/ultima_IV_font_sprite_set.ghul, examples/data/sprite_sets/ultima_IV_sprite_set.ghul, examples/data/types/chest_traps.ghul, examples/data/types/containers.ghul, examples/data/types/magical_fields.ghul, examples/data/types/npc_party_defs.ghul, examples/data/types/occupations.ghul, examples/data/types/portal_types.ghul, examples/data/types/projectiles.ghul, examples/data/types/readable_items.ghul, examples/data/types/species.ghul, examples/data/types/spells.ghul, examples/data/types/terrains.ghul, examples/data/types/useable_items.ghul, examples/data/types/vehicles.ghul, examples/data/types/weapons.ghul, examples/data/types/worn_items.ghul, examples/data/world/astronomy.ghul, examples/data/world/portals.ghul, examples/data/world/characters/BlackBart_the_Shipwright.ghul, examples/data/world/characters/inhabitants_of_britain.ghul, examples/data/world/characters/party_members.ghul, examples/data/world/conversations/conversations.ghul, examples/data/world/maps/M_dark_passage.ghul, examples/data/world/maps/M_secret_shrine.ghul, examples/data/world/maps/terrain_combat_maps.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul, examples/data/world/places/P_wilderness.ghul, examples/data/world/places/all_places.ghul, scripts/apply-license-header, scripts/ghul-indent, scripts/gpl.h, scripts/public-domain.h, scripts/remove-old-copyright-header, src/Arms.cpp, src/Arms.h, src/Container.cpp, src/Container.h, src/Field.h, src/Attic/Item.cpp, src/Attic/Item.h, src/Attic/Loader.cpp, src/Attic/Loader.h, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Reagent.cpp, src/Reagent.h, src/Attic/Spell.cpp, src/Attic/Spell.h, src/Attic/Trap.cpp, src/Attic/Trap.h, src/angband.c, src/ascii.c, src/ascii.h, src/astar.c, src/astar.h, src/character.cpp, src/character.h, src/cmdwin.c, src/cmdwin.h, src/combat.c, src/combat.h, src/common.c, src/common.h, src/console.c, src/console.h, src/constants.h, src/conv.c, src/conv.h, src/cursor.cpp, src/cursor.h, src/debug.h, src/dup_constants.h, src/event.c, src/event.h, src/floodfill.c, src/foogod.c, src/foogod.h, src/formation.h, src/Attic/game.c, src/Attic/game.h, src/hash.c, src/hash.h, src/heap.c, src/heap.h, src/images.c, src/images.h, src/knapsack.c, src/knapsack.h, src/Attic/lexer.c, src/Attic/lexer.h, src/list.h, src/los.c, src/los.h, src/map.c, src/map.h, src/Attic/moongate.c, src/Attic/moongate.h, src/nazghul.c, src/object.c, src/object.h, src/occ.c, src/occ.h, src/olist.c, src/olist.h, src/pinfo.h, src/place.c, src/place.h, src/play.c, src/play.h, src/player.cpp, src/player.h, src/Attic/portal.h, src/sched.c, src/sched.h, src/screen.c, src/screen.h, src/sky.c, src/sky.h, src/sound.c, src/sound.h, src/species.c, src/species.h, src/sprite.c, src/sprite.h, src/status.c, src/status.h, src/terrain.c, src/terrain.h, src/terrain_map.c, src/terrain_map.h, src/tree.c, src/tree.h, src/Attic/util.c, src/Attic/util.h, src/vehicle.cpp, src/vehicle.h, src/wind.c, src/wind.h, src/wq.c, src/wq.h: + Added license headers to all source and example files + + * examples/data/main.ghul, examples/data/types.ghul, examples/data/types/spells.ghul: + Cleaned up some obsolete references to u4/u5/u6 + + * examples/data/world/characters/Olin_the_Ghast.ghul: + Missed this file on an earlier commit + + * src/Attic/NpcParty.cpp, src/Attic/game.c, src/player.cpp, src/player.h: + --Fixed a bug in NpcParty related to npc schedules. The engine was only + properly advancing turns for the known nps schedule activities. Activities + extended by the script were not updating the npc turn counter, resulting in + an infinite loop when the engine tried to update npc turns. + + --Removed the pmask field from the player party, both in the parsing code and + in the class definition. Player party pmask is now calculated on the fly from + the intersection of party member pmasks. + + --Modified the add_member routine in the player party to reject proposed + members which do not have a passability bit in common with the party + pmask. In the case of the first member added to the party this rule is + skipped. + +2003-05-31 Gordon McNutt + + * Makefile.am, Attic/Makefile.in, Attic/configure, Attic/configure.in: + --Minor cleanup in configure.in (comments only) + + --Version number now 0.2.0 (configure.in) + + --If you build the distro tarball from the cvs tree the cvs directories are now + removed. + + * autogen.sh, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/player/party.ghul, examples/data/world/characters/BlackBart_the_Shipwright.ghul, src/conv.c, src/place.c: + -- Fixed a bug in conversation parsing which did not properly chain + "send_signal" and "set_alarm", so if these were not last in the list of + responses they would not be executed. + + -- Fixed a crash when "blinking" across a wilderness map boundary. Some of the + public entry functions to place.c were not wrapping coordinates, resulting + in some bad tile lookups. Fixed all public functions to wrap when the map + supports it. + + -- Updated Black Bart's conversation to inherit from the generic orc + conversation, and edited it for consistency. + + * Attic/configure.in: + Re-enabled the -O2 option + + * examples/Makefile.am, examples/Makefile.in, examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world.ghul: + -- Fixed Makefile.am to generate a Makefile which always forces a rebuild of + the example mapfile. + -- Fixed a build error introduced when I removed a map in my previous checkin. + + * examples/data/world/maps/Attic/M_prison_and_torture_chamber.ghul, examples/data/world/places/P_empire_city.ghul, examples/data/world/places/P_prison_and_torture_chamber.ghul: + -- Removed obsolete map files. + -- Added place file for empire city. + + * src/Attic/Mech.cpp, src/Attic/Spell.cpp, src/Attic/game.c, src/play.c: + Fixed all the uninitialized variables that -Wall was warning about when + the -O2 option was enabled. That also seems to fix the runtime crashes that + occurred when -O2 was enabled. + + * src/Attic/game.c: + Found another uninitialized variable that caused a crash during game load + +2003-05-30 Gordon McNutt + + * doc/GAME_RULES: + Modified some rules pertaining to party movement from town to world maps and through portals. + + * doc/GAME_RULES: + Added GAME_RULES to capture the explanation and reasoning behind engine behaviour where it differs from u5 + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world/characters/BlackBart_the_Shipwright.ghul, examples/data/world/mechanisms/all_mechanisms.ghul: + -- Added a shipwright to Empire City where the player can purchase a ship. + + * examples/Attic/mapfile, examples/data/Attic/mapfile, examples/data/world/astronomy.ghul, examples/data/world/places/P_wilderness.ghul: + -- Improved terrain variety on the wilderness map. + + * src/Attic/Makefile.in, src/Attic/NpcParty.cpp, src/player.cpp: + -- Portals and moongates now trump terrain passability in party movement. If a + tile has a portal, terrain passability is ignored. + + -- The engine no longer checks portals for destination passability. If the + party enters a portal, it's going to move through it regardless of what's on + the other side. This does not affect entering towns from a map edge, + however. In that case passability is still determined by the terrain at the + edge of the town map. + + -- When stepping through a portal the player now gets a quick look at what's + there before the party appears. This is to hopefully make things less + confusing when the party portals on top of a hostile npc party and combat + starts up. + +2003-05-29 Gordon McNutt + + * doc/Attic/GAME_DEVELOPERS_GUIDE, src/Attic/game.c, src/play.c, src/player.cpp, src/player.h: + t + + * examples/Makefile.am, examples/Makefile.in, examples/Attic/mapfile, examples/data/def_constants.ghul, examples/data/Attic/mapfile, examples/data/types.ghul, examples/data/world.ghul, examples/data/player/party.ghul, examples/data/sprite_sets/mechanism_sprites.ghul, examples/data/world/astronomy.ghul, examples/data/world/portals.ghul, examples/data/world/characters/inhabitants_of_britain.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/all_places.ghul: + Tried to fix Makefile.am (didn't quite); imported empire city map; some new mech macros + + * examples/data/world/places/P_wilderness.ghul, examples/data/world/places/all_places.ghul: + Added new simple wilderness + +2003-05-28 Gordon McNutt + + * COPYING, INSTALL, Makefile.am, Attic/Makefile.in, README, Attic/aclocal.m4, Attic/config.guess, Attic/config.sub, Attic/configure, Attic/configure.in, Attic/install-sh, Attic/missing, Attic/mkinstalldirs, examples/Attic/.console, examples/Makefile.am, examples/Makefile.in, examples/dup_constants.h, examples/Attic/mapfile, examples/data/ALL_GHULFILES, examples/data/Makefile, examples/data/def_constants.ghul, examples/data/def_macros.ghul, examples/data/main.ghul, examples/data/Attic/mapfile, examples/data/types.ghul, examples/data/world.ghul, examples/data/images/angband-16x16.png, examples/data/images/angband-32x32.png, examples/data/images/charset-16x16.png, examples/data/images/charset-8x16.png, examples/data/images/charset-8x16_intra1.png, examples/data/images/charset-8x8.png, examples/data/images/frame.png, examples/data/images/frame_pieces.png, examples/data/images/frame_pieces_2-16x16.png, examples/data/images/images_35x24_intra1.png, examples/data/images/mechanisms.png, examples/data/images/mine-32x32.png, examples/data/images/moons-16x16.png, examples/data/images/rune_font_32x32.png, examples/data/images/rune_font_8x16.png, examples/data/images/sam_32x32_font_template.png, examples/data/images/sam_mechanisms_template.png, examples/data/images/sam_new_tiles_32x32_intra1.png, examples/data/images/shapes-16x16.png, examples/data/images/shapes-32x32.png, examples/data/images/shrine-32x32.png, examples/data/images/splash.png, examples/data/images/u4_enhanced_tiles_32x32.png, examples/data/images/u4_enhanced_tiles_32x32_intra_1.png, examples/data/player/party.ghul, examples/data/sounds/cannon.wav, examples/data/sounds/damage.wav, examples/data/sounds/drum_02.wav, examples/data/sounds/enter_moongate.wav, examples/data/sounds/fanfare5.wav, examples/data/sounds/fanfare7.wav, examples/data/sounds/footsteps_1.wav, examples/data/sounds/horse.wav, examples/data/sounds/rowing-old1.wav, examples/data/sounds/rowing.wav, examples/data/sounds/walk.wav, examples/data/sprite_sets/angband_sprite_set.ghul, examples/data/sprite_sets/frame_sprite_set.ghul, examples/data/sprite_sets/mechanism_sprites.ghul, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/sprite_sets/moons_sprite_set.ghul, examples/data/sprite_sets/rune_font_sprite_set.ghul, examples/data/sprite_sets/rune_font_sprite_set_32x32.ghul, examples/data/sprite_sets/rune_font_sprite_set_8x16.ghul, examples/data/sprite_sets/sam_new_tiles_32x32.ghul, examples/data/sprite_sets/ultima_IV_font_sprite_set.ghul, examples/data/sprite_sets/ultima_IV_sprite_set.ghul, examples/data/tile_sheet_utils/TileSheet.pm, examples/data/tile_sheet_utils/reformat_tile_sheet.perl, examples/data/types/chest_traps.ghul, examples/data/types/containers.ghul, examples/data/types/magical_fields.ghul, examples/data/types/npc_party_defs.ghul, examples/data/types/occupations.ghul, examples/data/types/portal_types.ghul, examples/data/types/projectiles.ghul, examples/data/types/readable_items.ghul, examples/data/types/species.ghul, examples/data/types/spells.ghul, examples/data/types/terrains.ghul, examples/data/types/useable_items.ghul, examples/data/types/vehicles.ghul, examples/data/types/weapons.ghul, examples/data/types/worn_items.ghul, examples/data/world/astronomy.ghul, examples/data/world/portals.ghul, examples/data/world/characters/inhabitants_of_britain.ghul, examples/data/world/characters/party_members.ghul, examples/data/world/conversations/conversations.ghul, examples/data/world/maps/M_dark_passage.ghul, examples/data/world/maps/Attic/M_prison_and_torture_chamber.ghul, examples/data/world/maps/M_secret_shrine.ghul, examples/data/world/maps/terrain_combat_maps.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/all_places.ghul, examples/data/world/sounds/cannon.wav, examples/data/world/sounds/damage.wav, examples/data/world/sounds/drum_02.wav, examples/data/world/sounds/enter_moongate.wav, examples/data/world/sounds/fanfare5.wav, examples/data/world/sounds/fanfare7.wav, examples/data/world/sounds/footsteps_1.wav, examples/data/world/sounds/horse.wav, examples/data/world/sounds/rowing-old1.wav, examples/data/world/sounds/rowing.wav, examples/data/world/sounds/walk.wav, src/Arms.cpp, src/Arms.h, src/Container.cpp, src/Container.h, src/Field.h, src/Attic/Item.cpp, src/Attic/Item.h, src/Attic/Loader.cpp, src/Attic/Loader.h, src/Makefile.am, src/Attic/Makefile.in, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Reagent.cpp, src/Reagent.h, src/Attic/Spell.cpp, src/Attic/Spell.h, src/Attic/Trap.cpp, src/Attic/Trap.h, src/angband.c, src/ascii.c, src/ascii.h, src/astar.c, src/astar.h, src/character.cpp, src/character.h, src/cmdwin.c, src/cmdwin.h, src/combat.c, src/combat.h, src/common.c, src/common.h, src/console.c, src/console.h, src/constants.h, src/conv.c, src/conv.h, src/cursor.cpp, src/cursor.h, src/debug.h, src/dup_constants.h, src/event.c, src/event.h, src/floodfill.c, src/foogod.c, src/foogod.h, src/formation.h, src/Attic/game.c, src/Attic/game.h, src/hash.c, src/hash.h, src/heap.c, src/heap.h, src/images.c, src/images.h, src/knapsack.c, src/knapsack.h, src/Attic/lexer.c, src/Attic/lexer.h, src/list.h, src/los.c, src/los.h, src/map.c, src/map.h, src/Attic/moongate.c, src/Attic/moongate.h, src/nazghul.c, src/object.c, src/object.h, src/occ.c, src/occ.h, src/olist.c, src/olist.h, src/pinfo.h, src/place.c, src/place.h, src/play.c, src/play.h, src/player.cpp, src/player.h, src/Attic/portal.h, src/sched.c, src/sched.h, src/screen.c, src/screen.h, src/sky.c, src/sky.h, src/sound.c, src/sound.h, src/species.c, src/species.h, src/sprite.c, src/sprite.h, src/status.c, src/status.h, src/terrain.c, src/terrain.h, src/terrain_map.c, src/terrain_map.h, src/tree.c, src/tree.h, src/Attic/util.c, src/Attic/util.h, src/vehicle.cpp, src/vehicle.h, src/wind.c, src/wind.h, src/wq.c, src/wq.h: + Initial revision + + * COPYING, INSTALL, Makefile.am, Attic/Makefile.in, README, Attic/aclocal.m4, Attic/config.guess, Attic/config.sub, Attic/configure, Attic/configure.in, Attic/install-sh, Attic/missing, Attic/mkinstalldirs, examples/Attic/.console, examples/Makefile.am, examples/Makefile.in, examples/dup_constants.h, examples/Attic/mapfile, examples/data/ALL_GHULFILES, examples/data/Makefile, examples/data/def_constants.ghul, examples/data/def_macros.ghul, examples/data/main.ghul, examples/data/Attic/mapfile, examples/data/types.ghul, examples/data/world.ghul, examples/data/images/angband-16x16.png, examples/data/images/angband-32x32.png, examples/data/images/charset-16x16.png, examples/data/images/charset-8x16.png, examples/data/images/charset-8x16_intra1.png, examples/data/images/charset-8x8.png, examples/data/images/frame.png, examples/data/images/frame_pieces.png, examples/data/images/frame_pieces_2-16x16.png, examples/data/images/images_35x24_intra1.png, examples/data/images/mechanisms.png, examples/data/images/mine-32x32.png, examples/data/images/moons-16x16.png, examples/data/images/rune_font_32x32.png, examples/data/images/rune_font_8x16.png, examples/data/images/sam_32x32_font_template.png, examples/data/images/sam_mechanisms_template.png, examples/data/images/sam_new_tiles_32x32_intra1.png, examples/data/images/shapes-16x16.png, examples/data/images/shapes-32x32.png, examples/data/images/shrine-32x32.png, examples/data/images/splash.png, examples/data/images/u4_enhanced_tiles_32x32.png, examples/data/images/u4_enhanced_tiles_32x32_intra_1.png, examples/data/player/party.ghul, examples/data/sounds/cannon.wav, examples/data/sounds/damage.wav, examples/data/sounds/drum_02.wav, examples/data/sounds/enter_moongate.wav, examples/data/sounds/fanfare5.wav, examples/data/sounds/fanfare7.wav, examples/data/sounds/footsteps_1.wav, examples/data/sounds/horse.wav, examples/data/sounds/rowing-old1.wav, examples/data/sounds/rowing.wav, examples/data/sounds/walk.wav, examples/data/sprite_sets/angband_sprite_set.ghul, examples/data/sprite_sets/frame_sprite_set.ghul, examples/data/sprite_sets/mechanism_sprites.ghul, examples/data/sprite_sets/misc_added_sprite_set.ghul, examples/data/sprite_sets/moons_sprite_set.ghul, examples/data/sprite_sets/rune_font_sprite_set.ghul, examples/data/sprite_sets/rune_font_sprite_set_32x32.ghul, examples/data/sprite_sets/rune_font_sprite_set_8x16.ghul, examples/data/sprite_sets/sam_new_tiles_32x32.ghul, examples/data/sprite_sets/ultima_IV_font_sprite_set.ghul, examples/data/sprite_sets/ultima_IV_sprite_set.ghul, examples/data/tile_sheet_utils/TileSheet.pm, examples/data/tile_sheet_utils/reformat_tile_sheet.perl, examples/data/types/chest_traps.ghul, examples/data/types/containers.ghul, examples/data/types/magical_fields.ghul, examples/data/types/npc_party_defs.ghul, examples/data/types/occupations.ghul, examples/data/types/portal_types.ghul, examples/data/types/projectiles.ghul, examples/data/types/readable_items.ghul, examples/data/types/species.ghul, examples/data/types/spells.ghul, examples/data/types/terrains.ghul, examples/data/types/useable_items.ghul, examples/data/types/vehicles.ghul, examples/data/types/weapons.ghul, examples/data/types/worn_items.ghul, examples/data/world/astronomy.ghul, examples/data/world/portals.ghul, examples/data/world/characters/inhabitants_of_britain.ghul, examples/data/world/characters/party_members.ghul, examples/data/world/conversations/conversations.ghul, examples/data/world/maps/M_dark_passage.ghul, examples/data/world/maps/Attic/M_prison_and_torture_chamber.ghul, examples/data/world/maps/M_secret_shrine.ghul, examples/data/world/maps/terrain_combat_maps.ghul, examples/data/world/mechanisms/all_mechanisms.ghul, examples/data/world/places/all_places.ghul, examples/data/world/sounds/cannon.wav, examples/data/world/sounds/damage.wav, examples/data/world/sounds/drum_02.wav, examples/data/world/sounds/enter_moongate.wav, examples/data/world/sounds/fanfare5.wav, examples/data/world/sounds/fanfare7.wav, examples/data/world/sounds/footsteps_1.wav, examples/data/world/sounds/horse.wav, examples/data/world/sounds/rowing-old1.wav, examples/data/world/sounds/rowing.wav, examples/data/world/sounds/walk.wav, src/Arms.cpp, src/Arms.h, src/Container.cpp, src/Container.h, src/Field.h, src/Attic/Item.cpp, src/Attic/Item.h, src/Attic/Loader.cpp, src/Attic/Loader.h, src/Makefile.am, src/Attic/Makefile.in, src/Attic/Mech.cpp, src/Attic/Mech.h, src/Attic/NpcParty.cpp, src/Attic/NpcParty.h, src/Reagent.cpp, src/Reagent.h, src/Attic/Spell.cpp, src/Attic/Spell.h, src/Attic/Trap.cpp, src/Attic/Trap.h, src/angband.c, src/ascii.c, src/ascii.h, src/astar.c, src/astar.h, src/character.cpp, src/character.h, src/cmdwin.c, src/cmdwin.h, src/combat.c, src/combat.h, src/common.c, src/common.h, src/console.c, src/console.h, src/constants.h, src/conv.c, src/conv.h, src/cursor.cpp, src/cursor.h, src/debug.h, src/dup_constants.h, src/event.c, src/event.h, src/floodfill.c, src/foogod.c, src/foogod.h, src/formation.h, src/Attic/game.c, src/Attic/game.h, src/hash.c, src/hash.h, src/heap.c, src/heap.h, src/images.c, src/images.h, src/knapsack.c, src/knapsack.h, src/Attic/lexer.c, src/Attic/lexer.h, src/list.h, src/los.c, src/los.h, src/map.c, src/map.h, src/Attic/moongate.c, src/Attic/moongate.h, src/nazghul.c, src/object.c, src/object.h, src/occ.c, src/occ.h, src/olist.c, src/olist.h, src/pinfo.h, src/place.c, src/place.h, src/play.c, src/play.h, src/player.cpp, src/player.h, src/Attic/portal.h, src/sched.c, src/sched.h, src/screen.c, src/screen.h, src/sky.c, src/sky.h, src/sound.c, src/sound.h, src/species.c, src/species.h, src/sprite.c, src/sprite.h, src/status.c, src/status.h, src/terrain.c, src/terrain.h, src/terrain_map.c, src/terrain_map.h, src/tree.c, src/tree.h, src/Attic/util.c, src/Attic/util.h, src/vehicle.cpp, src/vehicle.h, src/wind.c, src/wind.h, src/wq.c, src/wq.h: + Initial import + + * Makefile.am, Attic/Makefile.in: + Fixed top-level Makefile.am to include the doc directory when building the distro tarball. + + * doc/Attic/GAME_DEVELOPERS_GUIDE, doc/GHULSCRIPT, doc/USERS_GUIDE, examples/Attic/.console: + Added documentation. + + * examples/Attic/.console: + Removed .console. + + * src/play.c: + bugfix: mapInit() must go before placeEnter() diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..f6ba1f3 --- /dev/null +++ b/INSTALL @@ -0,0 +1,54 @@ +BUILDING AND INSTALLING + +Nazghul requires the following libraries: + + SDL-1.2............http://www.libsdl.org + libSDL_image-1.2...http://www.libsdl.org/projects/SDL_image/ + libSDL_image-1.2...http://www.libsdl.org/projects/SDL_mixer/ + libpng.............http://www.libpng.org/pub/png/libpng.html + zlib + +UNIXy systems + +The libraries should be available as packages for most systems- you will +need dev versions of the packages, eg SDL_dev-1.2.deb + +To compile and install nazghul from a tarball: + + $ ./configure + $ make + $ make install + +(If you don't want to install as root then use the --prefix option with +configure. E.g., ./configure --prefix=$HOME) + +To compile and install from a CVS checkout rather than a milestone +tarball: + + $ ./autogen.sh + $ make + $ make install + +The --prefix option may be applied to autogen in the same manner as +configure. + +STARTING THE GAME + +To run haxima, the game that comes packaged with the engine: + + $ haxima.sh + +WIN32 + +The prebuilt installers should simply be a case of download and click. + +Setting up a compilation environment and libraries for a cvs build can +be more tricky: Detailed instuctions are available in win32/readme.txt + + +TROUBLESHOOTING + +Try one of the following resources: + + http://myweb.cableone.net/gmcnutt/faq.html + nazghul-users@lists.sourceforge.net \ No newline at end of file diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..d7dfa01 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,30 @@ +AUTOMAKE_OPTIONS = dist-shar dist-zip dist-tarZ + +SUBDIRS = src worlds m4 + +DIST_SUBDIRS = $(SUBDIRS) + +EXTRA_DIST = doc icons haxima.desktop + +ACLOCAL_AMFLAGS = -I m4 + +@MAINT@alldist: +@MAINT@ ${MAKE} distcheck +@MAINT@ ${MAKE} dist-shar +@MAINT@ ${MAKE} dist-zip +@MAINT@ ${MAKE} dist-tarZ + +MAINTAINERCLEANFILES = configure Makefile.in aclocal.m4 config.h.in \ + config.guess config.sub depcomp install-sh \ + missing mkinstalldirs + +@MAINT@cvsclean: maintainer-clean +@MAINT@ @-rm -f `find . -name Makefile.in` +@MAINT@ @-rm -f libtool ltmain.sh acinclude.m4 */Makefile.in +@MAINT@ @-rm -f configure aclocal.m4 config.h.in stamp-h.in depcomp ylwrap +@MAINT@ @-rm -f config.guess config.sub config.cache config.log config.status +@MAINT@ @-rm -f mkinstalldirs missing install-sh COPYING ABOUT-NLS config.rpath +@MAINT@ @-rm -fr @PACKAGE@-@VERSION@* *~ */*~ +@MAINT@ @echo "=================================================" +@MAINT@ @echo "Don't forget your ChangeLog and NEWS entries ...." +@MAINT@ @echo "=================================================" diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..48de57d --- /dev/null +++ b/Makefile.in @@ -0,0 +1,726 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ + config.guess config.sub depcomp install-sh missing +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/sdl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno config.status.lineno +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ + html-recursive info-recursive install-data-recursive \ + install-dvi-recursive install-exec-recursive \ + install-html-recursive install-info-recursive \ + install-pdf-recursive install-ps-recursive install-recursive \ + installcheck-recursive installdirs-recursive pdf-recursive \ + ps-recursive uninstall-recursive +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ + $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ + distdir dist dist-all distcheck +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d "$(distdir)" \ + || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr "$(distdir)"; }; } +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.Z $(distdir).shar.gz \ + $(distdir).zip +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = dist-shar dist-zip dist-tarZ +SUBDIRS = src worlds m4 +DIST_SUBDIRS = $(SUBDIRS) +EXTRA_DIST = doc icons haxima.desktop +ACLOCAL_AMFLAGS = -I m4 +MAINTAINERCLEANFILES = configure Makefile.in aclocal.m4 config.h.in \ + config.guess config.sub depcomp install-sh \ + missing mkinstalldirs + +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +am--refresh: + @: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ + $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + $(am__cd) $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) +$(am__aclocal_m4_deps): + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. +$(RECURSIVE_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +$(RECURSIVE_CLEAN_TARGETS): + @fail= failcom='exit 1'; \ + for f in x $$MAKEFLAGS; do \ + case $$f in \ + *=* | --[!k]*);; \ + *k*) failcom='fail=yes';; \ + esac; \ + done; \ + dot_seen=no; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + rev=''; for subdir in $$list; do \ + if test "$$subdir" = "."; then :; else \ + rev="$$subdir $$rev"; \ + fi; \ + done; \ + rev="$$rev ."; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done +ctags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + test -d "$(distdir)" || mkdir "$(distdir)" + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done + -test -n "$(am__skip_mode_fix)" \ + || find "$(distdir)" -type d ! -perm -755 \ + -exec chmod u+rwx,go+rx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r "$(distdir)" +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-lzma: distdir + tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma + $(am__remove_distdir) + +dist-xz: distdir + tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz + $(am__remove_distdir) +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.lzma*) \ + lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ + *.tar.xz*) \ + xz -dc $(distdir).tar.xz | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + test -d $(distdir)/_build || exit 0; \ + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && am__cwd=`pwd` \ + && $(am__cd) $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ + && cd "$$am__cwd" \ + || exit 1 + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' +distuninstallcheck: + @$(am__cd) '$(distuninstallcheck_dir)' \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-recursive +all-am: Makefile config.h +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-recursive + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all \ + ctags-recursive install-am install-strip tags-recursive + +.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ + all all-am am--refresh check check-am clean clean-generic \ + ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \ + dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \ + distclean distclean-generic distclean-hdr distclean-tags \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic pdf \ + pdf-am ps ps-am tags tags-recursive uninstall uninstall-am + + +@MAINT@alldist: +@MAINT@ ${MAKE} distcheck +@MAINT@ ${MAKE} dist-shar +@MAINT@ ${MAKE} dist-zip +@MAINT@ ${MAKE} dist-tarZ + +@MAINT@cvsclean: maintainer-clean +@MAINT@ @-rm -f `find . -name Makefile.in` +@MAINT@ @-rm -f libtool ltmain.sh acinclude.m4 */Makefile.in +@MAINT@ @-rm -f configure aclocal.m4 config.h.in stamp-h.in depcomp ylwrap +@MAINT@ @-rm -f config.guess config.sub config.cache config.log config.status +@MAINT@ @-rm -f mkinstalldirs missing install-sh COPYING ABOUT-NLS config.rpath +@MAINT@ @-rm -fr @PACKAGE@-@VERSION@* *~ */*~ +@MAINT@ @echo "=================================================" +@MAINT@ @echo "Don't forget your ChangeLog and NEWS entries ...." +@MAINT@ @echo "=================================================" + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..a86a5b4 --- /dev/null +++ b/NEWS @@ -0,0 +1,257 @@ +Changes between 0.7.0 and 0.7.1 +o Fixed c++ compile warnings (g++ (GCC) 4.4.4 20100630 (Red Hat 4.4.4-10)) +o Fixed missing libpng DLL in win32 release +Changes between 0.6.0 and 0.7.0 +Engine +o Y)use command for skills +o Quest log in the Z)stats pane +o Intro scene +o Misc bugfixes +Haxima +o Music +o Warritrix quest resolved +o Wilderness spawns slightly more challenging +o Smoke bombs +o Misc bugfixes +Changes between 0.5.6 and 0.6.0 +Engine +o Detailed speed handling added +o Backend support for multiple actions per turn +o Better support for diagonal movement +o Terrains can now have partial opacity +o Backend support for skills- wrogue skills added, but not enabled yet +o Enhanced weapon callbacks and behaviour +o Enhancements to the built in map editor +o Better support for script/engine integration via script defined engine variables +o Revisions to Zstats screens +o Improved npc party behaviour when player is camping +o Fixed: Memory leaks are hopefully all cleaned up now +o New effects: smoke, beam attacks +o Fixed: several crashes +o Objects are not dropped on water or air +Module +o New spells +o Random dungeon code generalized, new random dungeons added +o More movement types added, to distinguish fast creatures from merely fast-moving ones +o New items, weapons and shopping options +o Equipment now affects character speed +o Fixes and additions to conversations +o Fixed: problems with porcullises not working +o Visibly distinguishable moons +o Burning glass maze fairer +o Characters will no longer voluntarily walk off cliffs (chasm terrain now only selectively lethal)) +o Improved hidden map behaviour +o Many spellbooks added and distributed +o Several tweaks to combat balance +o Fixed: problems entering places diagonally +o More sprites +o More hires terrains, directional 'natural rock' walls +o First pass at a template for new games (now out of date already, sigh) +o Vehicle combat maps upgraded +o Various minor bugfixes + +Changes between nazghul 0.5.6 and 0.5.5: +o Fixed: crash when dying upon exit from tutorial cave +o Fixed: various minor bug-fixes + +Changes between nazghul 0.5.5 and 0.5.4: +Kernel changes: +o SAVED GAMES FROM PREVIOUS VERSIONS BROKEN! (sorry) +o Support for smaller displays +o Multiple saved games supported (with screenshots) +o Colorized text +o Character stats affect spell outcomes +o Character stats have more effect on combat +o Character and global effects now shown as icons instead of letter codes +o U)sed and R)eadied items moved to top of list for quicker access next time +o Mouse targeting +o New settings menu to turn sound off and change the screen size +o Better error handling if init script cannot be found +o Missiles handle line-of-fire better when standing next to corners +o Support for large icons on big critter (sorry, not multi-tile yet) +o Disable '>' when standing over a town to prevent abuse +o M)ix command now shows how many of that spell are already mixed +o Spell inventory shows icons and stats about spell +o Bugfixes +Haxima changesL +o Reduced most reagent and consumable prices +o Undead immune to sleep and kill spells +o Boss dude at end of game immune to charm +o Some new spells +o Some new quests and dungeons +o Lots of new sprites +o Simple character creation at start of game +o New in-game objects: clocks, mirrors, watches, bookshelf, caltrops, viles of + slime (fun!) and a spell book +o New NPCs: ratlings, sludge kraken, griffins and carybids +o Better flee algorithm for NPCs who have had enough +o Doors may be trapped like chests; multiple traps may be applied +o S)earching chests or doors might detect a trap, or might set one off +o Sextant and In Wis both report location as [x= y=] +o When party members leave they U)nready their equipment and give it back +o Mesmeme now has prismatic gaze, making him somewhat useful in combat +o You can name your ships +o Some new characters +o Bugfixes + +Changes between nazghul 0.5.3 and nazghul 0.5.4: +o Blended terrain [1] +o Misc. improved sprites +o Fixes for: spinning arrows on ground, S rune visibility, "dropped" key + presses, solo mode/rendezvous abuse, fire slimes dividing into green slimes, + immobile critters, misc. spelling/grammar, party mode + save game abuse, solo + moded + posession lockup, Alchemist's lich quest, invisibility scrolls not + getting consumed when used, extra ship on town entry bug, wind not updated on + load bug, t)alk targeting invisible people abuse, missing Abigail character + [1], misc. haxima plot fixes, misc. other +o Minor limited tweaks to some weapon stats +o Reagents a lot cheaper now +o New bottom level of Kurpolis (warning: evil) [1] +o Demons immune to kill spell +o Improved pathfinding performance +o Fixes for 64bit compilation +o Added sextants +[1] Changes not applicable with previous saved games + + +Changes between nazghul 0.5.2 and nazghul 0.5.3: +o Bugfix: assert in status.c after disarmed or acid dissolves readied +o New sprites: gint mage, tower, activated altar, PC's, goblins, transparent + moon sprites +o Balance: fireballs no longer drop fire fields where they +o Bugfix: hydra's weren't appearing on wilderness combat maps +o Bugfix: pirate ships spawning in Fens +o Bugfix: dragons, hydras, lichs and spiders dropped some loot in wilderness +o Accursed loot +o Accursed Templar and Roland use human knight sprite +o Fire slimes drop flaming oils +o "Normal" UNIX-style installation for source distros +o New commandline -I (game data dir) and -G (save game dir) options +o Fixed Gregor and Tooth's sleeping locations +o Disarm now drops the target's weapon on the ground at his feet +o Bugfix: nazghul junk (where junk was not a valid load file) caused a segfault +o G)et now always scoops up everything +o Bugfix: after leaving, Roland and Kama couldn't rejoin +o Tweaked armour defense, prices +o Bugfix: troll loot not using +o Added eclipse and improved moon phases +o Fixed many plural names +o Drunken staggering doesn't swap +o Opening sequence tweaks + +Changes between nazghul 0.5.1 and nazghul 0.5.2: +o Bugfix: purchasing a cure service from a healer didn't work +o Bugfix: when zoomed out, transparency shows up as magenta +o Bugfix: spawn points in Fun with Levers weren't getting triggered +o Bugfix: canceling u)se scroll was using up scroll +o Bugfix NPC parties getting into towns and dungeons +o Bugfix: Kathryn not giving player her Wis Quas scroll upon join +o Bugfix: ladder up from Dank Cave led to wrong location +o Bugfix: Bole's inn-room door was not being locked on town re-entry +o Bugfix: dryads in combat/town maps would walk +o Bugfix: when t)alking and a person was nearby, target origin started on + person instead of player +o Bugfix: g)et didn't work with Runes on the ground +o Bugfix: selling itesm - list updated improperly. Actually, list was just + getting built improperly from the get-go. +o Bugfix: kathryn's letter was defined in kathryn.scm, which might not be + loaded before the letter is referenced in the script. +o Bugfix: found a part of the wilderness map that was incorrectly impassable +o Bugfix: old entrance to slimy cavern still in moongate clearing +o Bugfix: +4 iron helm stats were wrong +o Ctrl-Q now means "quit without saving" +o Ctrl-S now means "save without quitting" +o Command-line options changed +o Increased dragon HP +o Changed quit-without-saving keybinding from ctrl-Q to ctrl-S +o Casting spells now gives XP +o Doubled XP required for level advancement +o Removed unthiefly treasure from Thief's Den +o New sprites: rune stones, human knight, shop signs +o Added transparency to all sprites +o New NPC type: fire slimes +o NPC's no longer drop loot on the wilderness map +o Gen buffed up + +Changes between nazghul 0.5.0 and 0.5.1: +o Bugfix: some spells like In Ex Por would be + consumed even if the player aborted without + selecting a target (In Sanct, Sanct and An Ex + Por were also affected) +o Bugfix: searching corpses from saved games + sometimes caused script errors +o Bugfix: if Kathrn in party but Thud alive and + not in party, crash when player encounters the + Mouse +o Bugfix: error in the script when the Necromancer + summoned Luximene. +o Bugfix: if a party member died it's readied + items were lost. +o Bugfix: moongate near Glasdrin was positioned + over an impassable mountain +o Bugfix: spider's sometimes dropped piles of + spider silk with zero (0) objects in them +o Bugfix: cannon-killing a large gint party cuased + a crash +o Bugfix: shroom's trade conv broken +o Bugfix: NPC pirates caused bad save file + +Major changes between nazghul 0.5.0 and 0.4.0: + +Haxima changes: +o Haxima is now a complete game. +o Wilderness map +o Several towns +o Several dungeons +o A main quest which can be completed +o Several side quests + +Kernel changes: +o NPC target highlighting shows friends and foes +o Attack command autotargets nearest foe +o Talk command autotargets nearest object with a conversation +o Main menu added + +Changes between nazghul 0.3.3 and 0.4.0: + +Haxima changes: +o Fixed the sprite for the eldritch blade +o Trolls can pick up boulders +o Improved NPC taunts +o Improved various NPC conversations +o Rebalanced some weapons and armor +o Improved performance in crowded places +o Added monster generators in Lost Halls +o Characters can climb over boulders at some + risk of falling off +o Bugfix: inn prices lower than advertised +o Bugfix: occupied doors should stay open +o Bugfix: opening troll corpse in Abandoned Cellar +o Started a new town: the Enchanter's Tower +o Added a few new spells (undocumented - talk to + NPC's to discover them) +o Feat request: Shopkeepers tell you what time + they open +o Feat request: ESC exits combat when done (note: + '<' already did) +o Feat request: resurrected characters should be + asleep +o Feat request: automatically open doors when + walking into them +o Misc new objects, terrains and the odd NPC + character + +Kernel changes: +o Fixed several crashes that occurred on reload +o Andreas Bauer improved the configure and build + system(now GNU-compliant) +o Bugfix: crash when using picklocks on objects +o Bugfix: setting a watch in camp means certain + death +o Added "fill" command (f key) to terrain editor +o Added "copy' command (c key) to terrain editor +o Bugfix: camping procedure corrupted (crash) +o Bugfix: crash when a Character's target is + killed by someone else +o Bugfix: NPC bow "vanishes" when they run out of + arrows diff --git a/README b/README new file mode 100644 index 0000000..dfd826e --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +See INSTALL for instructions on building, installing and starting the game. See +doc/USERS_GUIDE for detailed instructions on playing the game. diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..7c09da1 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1005 @@ +# generated automatically by aclocal 1.11.1 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.63],, +[m4_warning([this file was generated for autoconf 2.63. +You have another version of autoconf. It may work, but is not guaranteed to. +If you have problems, you may need to regenerate the build system entirely. +To do so, use the procedure documented by the package, typically `autoreconf'.])]) + +# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +# (This private macro should not be called outside this file.) +AC_DEFUN([AM_AUTOMAKE_VERSION], +[am__api_version='1.11' +dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to +dnl require some minimum version. Point them to the right macro. +m4_if([$1], [1.11.1], [], + [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl +]) + +# _AM_AUTOCONF_VERSION(VERSION) +# ----------------------------- +# aclocal traces this macro to find the Autoconf version. +# This is a private macro too. Using m4_define simplifies +# the logic in aclocal, which can simply ignore this definition. +m4_define([_AM_AUTOCONF_VERSION], []) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. +# This function is AC_REQUIREd by AM_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], +[AM_AUTOMAKE_VERSION([1.11.1])dnl +m4_ifndef([AC_AUTOCONF_VERSION], + [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl +_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 9 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE])dnl +AC_SUBST([$1_FALSE])dnl +_AM_SUBST_NOTMAKE([$1_TRUE])dnl +_AM_SUBST_NOTMAKE([$1_FALSE])dnl +m4_define([_AM_COND_VALUE_$1], [$2])dnl +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 10 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], UPC, [depcc="$UPC" am_compiler_list=], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + am__universal=false + m4_case([$1], [CC], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac], + [CXX], + [case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac]) + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH])dnl +_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 5 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[{ + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005, 2006, 2008, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 16 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.62])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl +dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. +m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, + [m4_fatal([AC_INIT should be called with package and version arguments])])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_OBJC], + [_AM_DEPENDENCIES(OBJC)], + [define([AC_PROG_OBJC], + defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl +]) +_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl +dnl The `parallel-tests' driver may need to know about EXEEXT, so add the +dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro +dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. +AC_CONFIG_COMMANDS_PRE(dnl +[m4_provide_if([_AM_COMPILER_EXEEXT], + [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl +]) + +dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not +dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further +dnl mangled by Autoconf and run in a shell conditional statement. +m4_define([_AC_COMPILER_EXEEXT], +m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_arg=$1 +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_MAINTAINER_MODE([DEFAULT-MODE]) +# ---------------------------------- +# Control maintainer-specific portions of Makefiles. +# Default is to disable them, unless `enable' is passed literally. +# For symmetry, `disable' may be passed as well. Anyway, the user +# can override the default with the --enable/--disable switch. +AC_DEFUN([AM_MAINTAINER_MODE], +[m4_case(m4_default([$1], [disable]), + [enable], [m4_define([am_maintainer_other], [disable])], + [disable], [m4_define([am_maintainer_other], [enable])], + [m4_define([am_maintainer_other], [enable]) + m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])]) +AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles]) + dnl maintainer-mode's default is 'disable' unless 'enable' is passed + AC_ARG_ENABLE([maintainer-mode], +[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + [USE_MAINTAINER_MODE=$enableval], + [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes])) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST([MAINT])dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 6 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +AC_REQUIRE_AUX_FILE([missing])dnl +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check for `mkdir -p'. +AC_DEFUN([AM_PROG_MKDIR_P], +[AC_PREREQ([2.60])dnl +AC_REQUIRE([AC_PROG_MKDIR_P])dnl +dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, +dnl while keeping a definition of mkdir_p for backward compatibility. +dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. +dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of +dnl Makefile.ins that do not define MKDIR_P, so we do our own +dnl adjustment using top_builddir (which is defined more often than +dnl MKDIR_P). +AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl +case $mkdir_p in + [[\\/$]]* | ?:[[\\/]]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac +]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 5 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[[\\\"\#\$\&\'\`$am_lf]]*) + AC_MSG_ERROR([unsafe absolute working directory name]);; +esac +case $srcdir in + *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) + AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Copyright (C) 2006, 2008 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. +# This macro is traced by Automake. +AC_DEFUN([_AM_SUBST_NOTMAKE]) + +# AM_SUBST_NOTMAKE(VARIABLE) +# --------------------------- +# Public sister of _AM_SUBST_NOTMAKE. +AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([m4/acinclude.m4]) +m4_include([m4/sdl.m4]) diff --git a/config.guess b/config.guess new file mode 100644 index 0000000..dc84c68 --- /dev/null +++ b/config.guess @@ -0,0 +1,1501 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-11-20' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > $dummy.c ; + for c in cc gcc c89 c99 ; do + if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ + /usr/sbin/$sysctl 2>/dev/null || echo unknown)` + case "${UNAME_MACHINE_ARCH}" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE_ARCH}" in + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval $set_cc_for_build + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "${UNAME_VERSION}" in + Debian*) + release='-gnu' + ;; + *) + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + exit ;; + *:ekkoBSD:*:*) + echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd${UNAME_RELEASE} + exit ;; + *:MirBSD:*:*) + echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE="alpha" ;; + "EV4.5 (21064)") + UNAME_MACHINE="alpha" ;; + "LCA4 (21066/21068)") + UNAME_MACHINE="alpha" ;; + "EV5 (21164)") + UNAME_MACHINE="alphaev5" ;; + "EV5.6 (21164A)") + UNAME_MACHINE="alphaev56" ;; + "EV5.6 (21164PC)") + UNAME_MACHINE="alphapca56" ;; + "EV5.7 (21164PC)") + UNAME_MACHINE="alphapca57" ;; + "EV6 (21264)") + UNAME_MACHINE="alphaev6" ;; + "EV6.7 (21264A)") + UNAME_MACHINE="alphaev67" ;; + "EV6.8CB (21264C)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8AL (21264B)") + UNAME_MACHINE="alphaev68" ;; + "EV6.8CX (21264D)") + UNAME_MACHINE="alphaev68" ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE="alphaev69" ;; + "EV7 (21364)") + UNAME_MACHINE="alphaev7" ;; + "EV7.9 (21364A)") + UNAME_MACHINE="alphaev79" ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit ;; + arm:riscos:*:*|arm:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten${UNAME_RELEASE} + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && + dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`$dummy $dummyarg` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos${UNAME_RELEASE} + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[456]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "${HP_ARCH}" = "" ]; then + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ ${HP_ARCH} = "hppa2.0w" ] + then + eval $set_cc_for_build + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH="hppa2.0w" + else + HP_ARCH="hppa64" + fi + fi + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit ;; + 3050*:HI-UX:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit ;; + *:FreeBSD:*:*) + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac + exit ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit ;; + *:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit ;; + i*:windows32*:*) + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 + exit ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit ;; + *:Interix*:*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; + [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) + echo i${UNAME_MACHINE}-pc-mks + exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i586-pc-interix + exit ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; + *:GNU:*:*) + # the GNU system + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu + exit ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit ;; + arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo cris-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo crisv32-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo frv-unknown-linux-gnu + exit ;; + i*86:Linux:*:*) + LIBC=gnu + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #ifdef __dietlibc__ + LIBC=dietlibc + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` + echo "${UNAME_MACHINE}-pc-linux-${LIBC}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit ;; + sh64*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo ${UNAME_MACHINE}-unknown-stop + exit ;; + i*86:atheos:*:*) + echo ${UNAME_MACHINE}-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo ${UNAME_MACHINE}-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit ;; + i*86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit ;; + i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo ${UNAME_MACHINE}-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux${UNAME_RELEASE} + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + case $UNAME_PROCESSOR in + i386) + eval $set_cc_for_build + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + UNAME_PROCESSOR="x86_64" + fi + fi ;; + unknown) UNAME_PROCESSOR=powerpc ;; + esac + echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = "x86"; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NSE-?:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk${UNAME_RELEASE} + exit ;; + NSR-?:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux${UNAME_RELEASE} + exit ;; + *:DragonFly:*:*) + echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "${UNAME_MACHINE}" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +eval $set_cc_for_build +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix\n"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && + { echo "$SYSTEM_NAME"; exit; } + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + c34*) + echo c34-convex-bsd + exit ;; + c38*) + echo c38-convex-bsd + exit ;; + c4*) + echo c4-convex-bsd + exit ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..11fd56e --- /dev/null +++ b/config.h.in @@ -0,0 +1,149 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the `atexit' function. */ +#undef HAVE_ATEXIT + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_FLOAT_H + +/* Define to 1 if you have the `floor' function. */ +#undef HAVE_FLOOR + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `png' library (-lpng). */ +#undef HAVE_LIBPNG + +/* Define to 1 if you have the `SDL_image' library (-lSDL_image). */ +#undef HAVE_LIBSDL_IMAGE + +/* Define to 1 if you have the `SDL_mixer' library (-lSDL_mixer). */ +#undef HAVE_LIBSDL_MIXER + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIMITS_H + +/* Define to 1 if you have the `malloc' function. */ +#undef HAVE_MALLOC + +/* Define to 1 if you have the header file. */ +#undef HAVE_MALLOC_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `realloc' function. */ +#undef HAVE_REALLOC + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `select_argtypes' function. */ +#undef HAVE_SELECT_ARGTYPES + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + +/* Define to 1 if you have the `strchr' function. */ +#undef HAVE_STRCHR + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the `strpbrk' function. */ +#undef HAVE_STRPBRK + +/* Define to 1 if you have the `strstr' function. */ +#undef HAVE_STRSTR + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Most likely your home directory is stored in $HOME. */ +#undef HOME_ENV + +/* Minimum supported script version */ +#undef MIN_SCRIPT_MAJOR + +/* Minimum supported script version */ +#undef MIN_SCRIPT_MINOR + +/* Minimum supported script version */ +#undef MIN_SCRIPT_RELEASE + +/* .nazghul is for Unix users. */ +#undef NAZGHUL_USER_DIR + +/* _nazghul is for Windows users. */ +#undef NAZGHUL_USER_DIR_WIN + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Enable quest log */ +#undef USE_QUESTS + +/* Enable Yuse command and skills */ +#undef USE_SKILLS + +/* Version number of package */ +#undef VERSION + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +#undef inline +#endif + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +#undef volatile diff --git a/config.sub b/config.sub new file mode 100644 index 0000000..2a55a50 --- /dev/null +++ b/config.sub @@ -0,0 +1,1705 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 +# Free Software Foundation, Inc. + +timestamp='2009-11-20' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA +# 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + + +# Please send patches to . Submit a context +# diff and a properly formatted GNU ChangeLog entry. +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + kopensolaris*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ + | bfin \ + | c4x | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | fido | fr30 | frv \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | i370 | i860 | i960 | ia64 \ + | ip2k | iq2000 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nios | nios2 \ + | ns16k | ns32k \ + | or32 \ + | pdp10 | pdp11 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ + | pyramid \ + | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ + | tahoe | thumb | tic4x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e \ + | we32k \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12 | picochip) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + ;; + ms1) + basic_machine=mt-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ + | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | i*86-* | i860-* | i960-* | ia64-* \ + | ip2k-* | iq2000-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nios-* | nios2-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ + | pyramid-* \ + | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ + | tahoe-* | thumb-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | vax-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i*86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze) + basic_machine=microblaze-xilinx + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little | ppc64-le | powerpc64-little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + sh64) + basic_machine=sh64-unknown + ;; + sparclite-wrs | simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tic55x | c55x*) + basic_machine=tic55x-unknown + os=-coff + ;; + tic6x | c6x*) + basic_machine=tic6x-unknown + os=-coff + ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + z80-*-coff) + basic_machine=z80-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -aros*) + os=-aros + ;; + -kaos*) + os=-kaos + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-haiku) + os=-haiku + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/configure b/configure new file mode 100644 index 0000000..30931b4 --- /dev/null +++ b/configure @@ -0,0 +1,8148 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.63 for nazghul 0.7.1. +# +# Report bugs to . +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell bug-autoconf@gnu.org about your system, + echo including any error possibly output before this message. + echo This can help us improve future autoconf versions. + echo Configuration will now proceed without shell functions. +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 &1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME='nazghul' +PACKAGE_TARNAME='nazghul' +PACKAGE_VERSION='0.7.1' +PACKAGE_STRING='nazghul 0.7.1' +PACKAGE_BUGREPORT='nazghul-devel@lists.sourceforge.net' + +ac_unique_file="src/nazghul.c" +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#ifdef STDC_HEADERS +# include +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +#ifdef HAVE_STRING_H +# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +# include +# endif +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif +#ifdef HAVE_INTTYPES_H +# include +#endif +#ifdef HAVE_STDINT_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='am__EXEEXT_FALSE +am__EXEEXT_TRUE +LTLIBOBJS +LIBOBJS +CXXCPP +EGREP +GREP +CPP +SDL_LIBS +SDL_CFLAGS +SDL_CONFIG +am__fastdepCXX_FALSE +am__fastdepCXX_TRUE +CXXDEPMODE +ac_ct_CXX +CXXFLAGS +CXX +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +MAINT +MAINTAINER_MODE_FALSE +MAINTAINER_MODE_TRUE +am__untar +am__tar +AMTAR +am__leading_dot +SET_MAKE +AWK +mkdir_p +MKDIR_P +INSTALL_STRIP_PROGRAM +STRIP +install_sh +MAKEINFO +AUTOHEADER +AUTOMAKE +AUTOCONF +ACLOCAL +VERSION +PACKAGE +CYGPATH_W +am__isrc +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +target_os +target_vendor +target_cpu +target +host_os +host_vendor +host_cpu +host +build_os +build_vendor +build_cpu +build +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' +ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_maintainer_mode +enable_dependency_tracking +with_sdl_prefix +with_sdl_exec_prefix +enable_sdltest +enable_dynamic_link +' + ac_precious_vars='build_alias +host_alias +target_alias +CC +CFLAGS +LDFLAGS +LIBS +CPPFLAGS +CXX +CXXFLAGS +CCC +CPP +CXXCPP' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; + + -without-* | --without-*) + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 + { (exit 1); exit 1; }; } + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { $as_echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { $as_echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 + { (exit 1); exit 1; }; } ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { $as_echo "$as_me: error: working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures nazghul 0.7.1 to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/nazghul] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names + +System types: + --build=BUILD configure for building on BUILD [guessed] + --host=HOST cross-compile to build programs to run on HOST [BUILD] + --target=TARGET configure for building compilers for TARGET [HOST] +_ACEOF +fi + +if test -n "$ac_init_help"; then + case $ac_init_help in + short | recursive ) echo "Configuration of nazghul 0.7.1:";; + esac + cat <<\_ACEOF + +Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + --disable-sdltest Do not try to compile and run a test SDL program + --enable-dynamic-link Create dynamically linked binaries (default) + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-sdl-prefix=PFX Prefix where SDL is installed (optional) + --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional) + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + LIBS libraries to pass to the linker, e.g. -l + CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if + you have headers in a nonstandard directory + CXX C++ compiler command + CXXFLAGS C++ compiler flags + CPP C preprocessor + CXXCPP C++ preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +Report bugs to . +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +nazghul configure 0.7.1 +generated by GNU Autoconf 2.63 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by nazghul $as_me 0.7.1, which was +generated by GNU Autoconf 2.63. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + $as_echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + $as_echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE +if test -n "$CONFIG_SITE"; then + ac_site_file1=$CONFIG_SITE +elif test "x$prefix" != xNONE; then + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site +else + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site +fi +for ac_site_file in "$ac_site_file1" "$ac_site_file2" +do + test "x$ac_site_file" = xNONE && continue + if test -r "$ac_site_file"; then + { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + +ac_config_headers="$ac_config_headers config.h" + + +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + { { $as_echo "$as_me:$LINENO: error: cannot run $SHELL $ac_aux_dir/config.sub" >&5 +$as_echo "$as_me: error: cannot run $SHELL $ac_aux_dir/config.sub" >&2;} + { (exit 1); exit 1; }; } + +{ $as_echo "$as_me:$LINENO: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if test "${ac_cv_build+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + { { $as_echo "$as_me:$LINENO: error: cannot guess build type; you must specify one" >&5 +$as_echo "$as_me: error: cannot guess build type; you must specify one" >&2;} + { (exit 1); exit 1; }; } +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $ac_build_alias failed" >&2;} + { (exit 1); exit 1; }; } + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical build" >&5 +$as_echo "$as_me: error: invalid value of canonical build" >&2;} + { (exit 1); exit 1; }; };; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:$LINENO: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if test "${ac_cv_host+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $host_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical host" >&5 +$as_echo "$as_me: error: invalid value of canonical host" >&2;} + { (exit 1); exit 1; }; };; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + + +{ $as_echo "$as_me:$LINENO: checking target system type" >&5 +$as_echo_n "checking target system type... " >&6; } +if test "${ac_cv_target+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test "x$target_alias" = x; then + ac_cv_target=$ac_cv_host +else + ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || + { { $as_echo "$as_me:$LINENO: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&5 +$as_echo "$as_me: error: $SHELL $ac_aux_dir/config.sub $target_alias failed" >&2;} + { (exit 1); exit 1; }; } +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_target" >&5 +$as_echo "$ac_cv_target" >&6; } +case $ac_cv_target in +*-*-*) ;; +*) { { $as_echo "$as_me:$LINENO: error: invalid value of canonical target" >&5 +$as_echo "$as_me: error: invalid value of canonical target" >&2;} + { (exit 1); exit 1; }; };; +esac +target=$ac_cv_target +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_target +shift +target_cpu=$1 +target_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +target_os=$* +IFS=$ac_save_IFS +case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac + + +# The aliases save the names the user supplied, while $host etc. +# will get canonicalized. +test -n "$target_alias" && + test "$program_prefix$program_suffix$program_transform_name" = \ + NONENONEs,x,x, && + program_prefix=${target_alias}- + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + +done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + { { $as_echo "$as_me:$LINENO: error: unsafe absolute working directory name" >&5 +$as_echo "$as_me: error: unsafe absolute working directory name" >&2;} + { (exit 1); exit 1; }; };; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + { { $as_echo "$as_me:$LINENO: error: unsafe srcdir value: \`$srcdir'" >&5 +$as_echo "$as_me: error: unsafe srcdir value: \`$srcdir'" >&2;} + { (exit 1); exit 1; }; };; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { $as_echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +$as_echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { $as_echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +$as_echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +{ $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_STRIP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:$LINENO: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:$LINENO: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if test "${ac_cv_path_mkdir+set}" = set; then + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done +done +IFS=$as_save_IFS + +fi + + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + test -d ./--version && rmdir ./--version + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:$LINENO: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_AWK+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:$LINENO: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + { { $as_echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +$as_echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='nazghul' + VERSION='0.7.1' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + + + +{ $as_echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5 +$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; } + # Check whether --enable-maintainer-mode was given. +if test "${enable_maintainer_mode+set}" = set; then + enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval +else + USE_MAINTAINER_MODE=no +fi + + { $as_echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5 +$as_echo "$USE_MAINTAINER_MODE" >&6; } + if test $USE_MAINTAINER_MODE = yes; then + MAINTAINER_MODE_TRUE= + MAINTAINER_MODE_FALSE='#' +else + MAINTAINER_MODE_TRUE='#' + MAINTAINER_MODE_FALSE= +fi + + MAINT=$MAINTAINER_MODE_TRUE + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl.exe +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CC" && break +done + + if test "x$ac_ct_CC" = x; then + CC="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CC=$ac_ct_CC + fi +fi + +fi + + +test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + +# Provide some information about the compiler. +$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + +ac_rmfiles= +for ac_file in $ac_files +do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + * ) ac_rmfiles="$ac_rmfiles $ac_file";; + esac +done +rm -f $ac_rmfiles + +if { (ac_try="$ac_link_default" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link_default") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. +# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' +# in a Makefile. We should not override ac_cv_exeext if it was cached, +# so that the user can short-circuit this test for compilers unknown to +# Autoconf. +for ac_file in $ac_files '' +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; + then :; else + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + fi + # We set ac_cv_exeext here because the later test for it is not + # safe: cross compilers may not add the suffix if given an `-o' + # argument, so we may need to know it at that point already. + # Even if this section looks crufty: it has the advantage of + # actually working. + break;; + * ) + break;; + esac +done +test "$ac_cv_exeext" = no && ac_cv_exeext= + +else + ac_file='' +fi + +{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } +if test -z "$ac_file"; then + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; }; } +fi + +ac_exeext=$ac_cv_exeext + +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } + fi + fi +fi +{ $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check that the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } + +{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + break;; + * ) break;; + esac +done +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +rm -f conftest$ac_cv_exeext +{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } +if test "${ac_cv_objext+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in conftest.o conftest.obj conftest.*; do + test -f "$ac_file" || continue; + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } +if test "${ac_cv_c_compiler_gnu+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } +if test "${ac_cv_prog_cc_g+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_save_c_werror_flag=$ac_c_werror_flag + ac_c_werror_flag=yes + ac_cv_prog_cc_g=no + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_c_werror_flag=$ac_save_c_werror_flag + CFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_c_werror_flag=$ac_save_c_werror_flag +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } +if test "${ac_cv_prog_cc_c89+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_prog_cc_c89=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cc_c89=$ac_arg +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC + +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:$LINENO: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:$LINENO: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:$LINENO: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +if test -z "$CXX"; then + if test -n "$CCC"; then + CXX=$CCC + else + if test -n "$ac_tool_prefix"; then + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$CXX"; then + ac_cv_prog_CXX="$CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +CXX=$ac_cv_prog_CXX +if test -n "$CXX"; then + { $as_echo "$as_me:$LINENO: result: $CXX" >&5 +$as_echo "$CXX" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$CXX" && break + done +fi +if test -z "$CXX"; then + ac_ct_CXX=$CXX + for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_CXX"; then + ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CXX="$ac_prog" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_CXX=$ac_cv_prog_ac_ct_CXX +if test -n "$ac_ct_CXX"; then + { $as_echo "$as_me:$LINENO: result: $ac_ct_CXX" >&5 +$as_echo "$ac_ct_CXX" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$ac_ct_CXX" && break +done + + if test "x$ac_ct_CXX" = x; then + CXX="g++" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + CXX=$ac_ct_CXX + fi +fi + + fi +fi +# Provide some information about the compiler. +$as_echo "$as_me:$LINENO: checking for C++ compiler version" >&5 +set X $ac_compile +ac_compiler=$2 +{ (ac_try="$ac_compiler --version >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler --version >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -v >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -v >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (ac_try="$ac_compiler -V >&5" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compiler -V >&5") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C++ compiler" >&5 +$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } +if test "${ac_cv_cxx_compiler_gnu+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_compiler_gnu=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_compiler_gnu=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_cxx_compiler_gnu=$ac_compiler_gnu + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_cxx_compiler_gnu" >&5 +$as_echo "$ac_cv_cxx_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GXX=yes +else + GXX= +fi +ac_test_CXXFLAGS=${CXXFLAGS+set} +ac_save_CXXFLAGS=$CXXFLAGS +{ $as_echo "$as_me:$LINENO: checking whether $CXX accepts -g" >&5 +$as_echo_n "checking whether $CXX accepts -g... " >&6; } +if test "${ac_cv_prog_cxx_g+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_save_cxx_werror_flag=$ac_cxx_werror_flag + ac_cxx_werror_flag=yes + ac_cv_prog_cxx_g=no + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + CXXFLAGS="" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cxx_werror_flag=$ac_save_cxx_werror_flag + CXXFLAGS="-g" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_prog_cxx_g=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + ac_cxx_werror_flag=$ac_save_cxx_werror_flag +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cxx_g" >&5 +$as_echo "$ac_cv_prog_cxx_g" >&6; } +if test "$ac_test_CXXFLAGS" = set; then + CXXFLAGS=$ac_save_CXXFLAGS +elif test $ac_cv_prog_cxx_g = yes; then + if test "$GXX" = yes; then + CXXFLAGS="-g -O2" + else + CXXFLAGS="-g" + fi +else + if test "$GXX" = yes; then + CXXFLAGS="-O2" + else + CXXFLAGS= + fi +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +depcc="$CXX" am_compiler_list= + +{ $as_echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CXX_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CXX_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CXX_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $am_cv_CXX_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } +CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then + am__fastdepCXX_TRUE= + am__fastdepCXX_FALSE='#' +else + am__fastdepCXX_TRUE='#' + am__fastdepCXX_FALSE= +fi + + + + + +{ $as_echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + + + +SDL_VERSION=1.2.3 + + +# Check whether --with-sdl-prefix was given. +if test "${with_sdl_prefix+set}" = set; then + withval=$with_sdl_prefix; sdl_prefix="$withval" +else + sdl_prefix="" +fi + + +# Check whether --with-sdl-exec-prefix was given. +if test "${with_sdl_exec_prefix+set}" = set; then + withval=$with_sdl_exec_prefix; sdl_exec_prefix="$withval" +else + sdl_exec_prefix="" +fi + +# Check whether --enable-sdltest was given. +if test "${enable_sdltest+set}" = set; then + enableval=$enable_sdltest; +else + enable_sdltest=yes +fi + + + if test x$sdl_exec_prefix != x ; then + sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_args="$sdl_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + + + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + # Extract the first word of "sdl-config", so it can be a program name with args. +set dummy sdl-config; ac_word=$2 +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if test "${ac_cv_path_SDL_CONFIG+set}" = set; then + $as_echo_n "(cached) " >&6 +else + case $SDL_CONFIG in + [\\/]* | ?:[\\/]*) + ac_cv_path_SDL_CONFIG="$SDL_CONFIG" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_SDL_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + test -z "$ac_cv_path_SDL_CONFIG" && ac_cv_path_SDL_CONFIG="no" + ;; +esac +fi +SDL_CONFIG=$ac_cv_path_SDL_CONFIG +if test -n "$SDL_CONFIG"; then + { $as_echo "$as_me:$LINENO: result: $SDL_CONFIG" >&5 +$as_echo "$SDL_CONFIG" >&6; } +else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } +fi + + + min_sdl_version=$SDL_VERSION + { $as_echo "$as_me:$LINENO: checking for SDL - version >= $min_sdl_version" >&5 +$as_echo_n "checking for SDL - version >= $min_sdl_version... " >&6; } + no_sdl="" + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + rm -f conf.sdltest + if test "$cross_compiling" = yes; then + echo $ac_n "cross compiling; assumed OK... $ac_c" +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + char *tmp_version; + + /* This hangs on some systems (?) + system ("touch conf.sdltest"); + */ + { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + + +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +no_sdl=yes +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } + : + else + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main + +int +main () +{ + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + { { $as_echo "$as_me:$LINENO: error: *** SDL version $SDL_VERSION not found!" >&5 +$as_echo "$as_me: error: *** SDL version $SDL_VERSION not found!" >&2;} + { (exit 1); exit 1; }; } + + fi + + + rm -f conf.sdltest + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } +if test "${ac_cv_path_GREP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if test -z "$GREP"; then + ac_path_GREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP +case `"$ac_path_GREP" --version 2>&1` in +*GNU*) + ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" + "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_GREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_GREP="$ac_path_GREP" + ac_path_GREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_GREP_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_GREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_GREP=$GREP +fi + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } + GREP="$ac_cv_path_GREP" + + +{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } +if test "${ac_cv_path_EGREP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 + then ac_cv_path_EGREP="$GREP -E" + else + if test -z "$EGREP"; then + ac_path_EGREP_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP +case `"$ac_path_EGREP" --version 2>&1` in +*GNU*) + ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" + "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + ac_count=`expr $ac_count + 1` + if test $ac_count -gt ${ac_path_EGREP_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_EGREP="$ac_path_EGREP" + ac_path_EGREP_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_EGREP_found && break 3 + done + done +done +IFS=$as_save_IFS + if test -z "$ac_cv_path_EGREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + { (exit 1); exit 1; }; } + fi +else + ac_cv_path_EGREP=$EGREP +fi + + fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } + EGREP="$ac_cv_path_EGREP" + + +{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if test "${ac_cv_header_stdc+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_header_stdc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_header_stdc=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +rm -f conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -rf conftest.dSYM +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi + + +fi +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + eval "$as_ac_Header=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_Header=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu +{ $as_echo "$as_me:$LINENO: checking how to run the C++ preprocessor" >&5 +$as_echo_n "checking how to run the C++ preprocessor... " >&6; } +if test -z "$CXXCPP"; then + if test "${ac_cv_prog_CXXCPP+set}" = set; then + $as_echo_n "(cached) " >&6 +else + # Double quotes because CXXCPP needs to be expanded + for CXXCPP in "$CXX -E" "/lib/cpp" + do + ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CXXCPP=$CXXCPP + +fi + CXXCPP=$ac_cv_prog_CXXCPP +else + ac_cv_prog_CXXCPP=$CXXCPP +fi +{ $as_echo "$as_me:$LINENO: result: $CXXCPP" >&5 +$as_echo "$CXXCPP" >&6; } +ac_preproc_ok=false +for ac_cxx_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + : +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi + +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + # Broken: success on invalid input. +continue +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi + +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&5 +$as_echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; }; } +fi + +ac_ext=cpp +ac_cpp='$CXXCPP $CPPFLAGS' +ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_cxx_compiler_gnu + + + + + + +for ac_header in fcntl.h \ + malloc.h \ + float.h \ + limits.h +do +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 +$as_echo_n "checking $ac_header usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 +$as_echo_n "checking $ac_header presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## -------------------------------------------------- ## +## Report this to nazghul-devel@lists.sourceforge.net ## +## -------------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + +fi +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + +{ $as_echo "$as_me:$LINENO: checking whether what binaries we shall create" >&5 +$as_echo_n "checking whether what binaries we shall create... " >&6; } +# Check whether --enable-dynamic-link was given. +if test "${enable_dynamic_link+set}" = set; then + enableval=$enable_dynamic_link; if test "$enableval" = "yes"; then + { $as_echo "$as_me:$LINENO: result: dynamically linked" >&5 +$as_echo "dynamically linked" >&6; } +else + LDFLAGS="$LDFLAGS -static" + { $as_echo "$as_me:$LINENO: result: statically linked" >&5 +$as_echo "statically linked" >&6; } +fi +else + { $as_echo "$as_me:$LINENO: result: dynamically linked" >&5 +$as_echo "dynamically linked" >&6; } +fi + + +{ $as_echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } +if test "${ac_cv_c_const+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset cs; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *pcpcc; + char **ppc; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + pcpcc = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++pcpcc; + ppc = (char**) pcpcc; + pcpcc = (char const *const *) ppc; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + if (s) return 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + if (!foo) return 0; + } + return !cs[0] && !zero.x; +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_const=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_const=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const /**/ +_ACEOF + +fi + +{ $as_echo "$as_me:$LINENO: checking for inline" >&5 +$as_echo_n "checking for inline... " >&6; } +if test "${ac_cv_c_inline+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_c_inline=no +for ac_kw in inline __inline__ __inline; do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifndef __cplusplus +typedef int foo_t; +static $ac_kw foo_t static_foo () {return 0; } +$ac_kw foo_t foo () {return 0; } +#endif + +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_inline=$ac_kw +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + test "$ac_cv_c_inline" != no && break +done + +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5 +$as_echo "$ac_cv_c_inline" >&6; } + + +case $ac_cv_c_inline in + inline | yes) ;; + *) + case $ac_cv_c_inline in + no) ac_val=;; + *) ac_val=$ac_cv_c_inline;; + esac + cat >>confdefs.h <<_ACEOF +#ifndef __cplusplus +#define inline $ac_val +#endif +_ACEOF + ;; +esac + +{ $as_echo "$as_me:$LINENO: checking for working volatile" >&5 +$as_echo_n "checking for working volatile... " >&6; } +if test "${ac_cv_c_volatile+set}" = set; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + +volatile int x; +int * volatile y = (int *) 0; +return !x && !y; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_c_volatile=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_c_volatile=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_volatile" >&5 +$as_echo "$ac_cv_c_volatile" >&6; } +if test $ac_cv_c_volatile = no; then + +cat >>confdefs.h <<\_ACEOF +#define volatile /**/ +_ACEOF + +fi + + + + + + + + + + + + + + + + +for ac_func in malloc \ + realloc \ + select_argtypes \ + vprintf \ + strerror \ + strpbrk \ + strstr \ + atexit \ + floor \ + strcasecmp \ + strdup \ + realloc \ + select \ + strchr +do +as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 +$as_echo_n "checking for $ac_func... " >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + $as_echo_n "(cached) " >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + eval "$as_ac_var=yes" +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +CFLAGS="$CFLAGS $SDL_CFLAGS" + +CXXFLAGS="$CFLAGS" + +CXXCPP="$CXXCPP $CXXFLAGS" + +CC="$CXX" + +LIBS="$LIBS $SDL_LIBS" + + +{ $as_echo "$as_me:$LINENO: checking for png_create_write_struct in -lpng" >&5 +$as_echo_n "checking for png_create_write_struct in -lpng... " >&6; } +if test "${ac_cv_lib_png_png_create_write_struct+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lpng $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char png_create_write_struct (); +int +main () +{ +return png_create_write_struct (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_png_png_create_write_struct=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_png_png_create_write_struct=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_create_write_struct" >&5 +$as_echo "$ac_cv_lib_png_png_create_write_struct" >&6; } +if test "x$ac_cv_lib_png_png_create_write_struct" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPNG 1 +_ACEOF + + LIBS="-lpng $LIBS" + +fi + + +if test "${ac_cv_header_png_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for png.h" >&5 +$as_echo_n "checking for png.h... " >&6; } +if test "${ac_cv_header_png_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5 +$as_echo "$ac_cv_header_png_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking png.h usability" >&5 +$as_echo_n "checking png.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking png.h presence" >&5 +$as_echo_n "checking png.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: png.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: png.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: png.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: png.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: png.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: png.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: png.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: png.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: png.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: png.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: png.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: png.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: png.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: png.h: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## -------------------------------------------------- ## +## Report this to nazghul-devel@lists.sourceforge.net ## +## -------------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for png.h" >&5 +$as_echo_n "checking for png.h... " >&6; } +if test "${ac_cv_header_png_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_png_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5 +$as_echo "$ac_cv_header_png_h" >&6; } + +fi +if test "x$ac_cv_header_png_h" = x""yes; then + : +else + { { $as_echo "$as_me:$LINENO: error: *** png include file not found! +You should install development package." >&5 +$as_echo "$as_me: error: *** png include file not found! +You should install development package." >&2;} + { (exit 1); exit 1; }; } +fi + + + + +{ $as_echo "$as_me:$LINENO: checking for IMG_ReadXPMFromArray in -lSDL_image" >&5 +$as_echo_n "checking for IMG_ReadXPMFromArray in -lSDL_image... " >&6; } +if test "${ac_cv_lib_SDL_image_IMG_ReadXPMFromArray+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lSDL_image $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char IMG_ReadXPMFromArray (); +int +main () +{ +return IMG_ReadXPMFromArray (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_SDL_image_IMG_ReadXPMFromArray=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_SDL_image_IMG_ReadXPMFromArray=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_SDL_image_IMG_ReadXPMFromArray" >&5 +$as_echo "$ac_cv_lib_SDL_image_IMG_ReadXPMFromArray" >&6; } +if test "x$ac_cv_lib_SDL_image_IMG_ReadXPMFromArray" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSDL_IMAGE 1 +_ACEOF + + LIBS="-lSDL_image $LIBS" + +fi + + +if test "${ac_cv_header_SDL_image_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for SDL_image.h" >&5 +$as_echo_n "checking for SDL_image.h... " >&6; } +if test "${ac_cv_header_SDL_image_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_SDL_image_h" >&5 +$as_echo "$ac_cv_header_SDL_image_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking SDL_image.h usability" >&5 +$as_echo_n "checking SDL_image.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking SDL_image.h presence" >&5 +$as_echo_n "checking SDL_image.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: SDL_image.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: SDL_image.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_image.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: SDL_image.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: SDL_image.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: SDL_image.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_image.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: SDL_image.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_image.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: SDL_image.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_image.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: SDL_image.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_image.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: SDL_image.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_image.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: SDL_image.h: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## -------------------------------------------------- ## +## Report this to nazghul-devel@lists.sourceforge.net ## +## -------------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for SDL_image.h" >&5 +$as_echo_n "checking for SDL_image.h... " >&6; } +if test "${ac_cv_header_SDL_image_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_SDL_image_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_SDL_image_h" >&5 +$as_echo "$ac_cv_header_SDL_image_h" >&6; } + +fi +if test "x$ac_cv_header_SDL_image_h" = x""yes; then + : +else + { { $as_echo "$as_me:$LINENO: error: *** SDL_image include files not found! +You should install development package." >&5 +$as_echo "$as_me: error: *** SDL_image include files not found! +You should install development package." >&2;} + { (exit 1); exit 1; }; } +fi + + + + +{ $as_echo "$as_me:$LINENO: checking for Mix_OpenAudio in -lSDL_mixer" >&5 +$as_echo_n "checking for Mix_OpenAudio in -lSDL_mixer... " >&6; } +if test "${ac_cv_lib_SDL_mixer_Mix_OpenAudio+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lSDL_mixer $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char Mix_OpenAudio (); +int +main () +{ +return Mix_OpenAudio (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_lib_SDL_mixer_Mix_OpenAudio=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_SDL_mixer_Mix_OpenAudio=no +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_SDL_mixer_Mix_OpenAudio" >&5 +$as_echo "$ac_cv_lib_SDL_mixer_Mix_OpenAudio" >&6; } +if test "x$ac_cv_lib_SDL_mixer_Mix_OpenAudio" = x""yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSDL_MIXER 1 +_ACEOF + + LIBS="-lSDL_mixer $LIBS" + +fi + + +if test "${ac_cv_header_SDL_mixer_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for SDL_mixer.h" >&5 +$as_echo_n "checking for SDL_mixer.h... " >&6; } +if test "${ac_cv_header_SDL_mixer_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_SDL_mixer_h" >&5 +$as_echo "$ac_cv_header_SDL_mixer_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking SDL_mixer.h usability" >&5 +$as_echo_n "checking SDL_mixer.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_cxx_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking SDL_mixer.h presence" >&5 +$as_echo_n "checking SDL_mixer.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: SDL_mixer.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: SDL_mixer.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_mixer.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: SDL_mixer.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: SDL_mixer.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: SDL_mixer.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_mixer.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: SDL_mixer.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_mixer.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: SDL_mixer.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_mixer.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: SDL_mixer.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_mixer.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: SDL_mixer.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: SDL_mixer.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: SDL_mixer.h: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## -------------------------------------------------- ## +## Report this to nazghul-devel@lists.sourceforge.net ## +## -------------------------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for SDL_mixer.h" >&5 +$as_echo_n "checking for SDL_mixer.h... " >&6; } +if test "${ac_cv_header_SDL_mixer_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_SDL_mixer_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_SDL_mixer_h" >&5 +$as_echo "$ac_cv_header_SDL_mixer_h" >&6; } + +fi +if test "x$ac_cv_header_SDL_mixer_h" = x""yes; then + : +else + { { $as_echo "$as_me:$LINENO: error: *** SDL_mixer include files not found! +You should install development package." >&5 +$as_echo "$as_me: error: *** SDL_mixer include files not found! +You should install development package." >&2;} + { (exit 1); exit 1; }; } +fi + + + + +# User directories for saving game data + + +cat >>confdefs.h <<\_ACEOF +#define NAZGHUL_USER_DIR "/.nazghul" +_ACEOF + + + +cat >>confdefs.h <<\_ACEOF +#define NAZGHUL_USER_DIR_WIN "/_nazghul" +_ACEOF + + + +cat >>confdefs.h <<\_ACEOF +#define HOME_ENV "HOME" +_ACEOF + + + +cat >>confdefs.h <<\_ACEOF +#define MIN_SCRIPT_MAJOR 0 +_ACEOF + + + +cat >>confdefs.h <<\_ACEOF +#define MIN_SCRIPT_MINOR 6 +_ACEOF + + + +cat >>confdefs.h <<\_ACEOF +#define MIN_SCRIPT_RELEASE 0 +_ACEOF + + + +cat >>confdefs.h <<\_ACEOF +#define USE_SKILLS 1 +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define USE_QUESTS 1 +_ACEOF + + +# Finally create all the generated files +ac_config_files="$ac_config_files Makefile m4/Makefile src/Makefile worlds/Makefile worlds/haxima-1.002/Makefile worlds/haxima-1.002/music/Makefile" + + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + +if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then + { { $as_echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +$as_echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_write_fail=0 +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir 2>/dev/null +fi +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else + as_ln_s='cp -p' + fi +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by nazghul $as_me 0.7.1, which was +generated by GNU Autoconf 2.63. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# Files that config.status was made for. +config_files="$ac_config_files" +config_headers="$ac_config_headers" +config_commands="$ac_config_commands" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTION]... [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet, --silent + do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_cs_version="\\ +nazghul config.status 0.7.1 +configured by $0, generated by GNU Autoconf 2.63, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2008 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +MKDIR_P='$MKDIR_P' +AWK='$AWK' +test -n "\$AWK" || AWK=awk +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + $as_echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" + ac_need_defaults=false;; + --he | --h) + # Conflict between --help and --header + { $as_echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + $as_echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { $as_echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +if \$ac_cs_recheck; then + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' + export CONFIG_SHELL + exec "\$@" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + $as_echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +# +# INIT-COMMANDS +# +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "m4/Makefile") CONFIG_FILES="$CONFIG_FILES m4/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "worlds/Makefile") CONFIG_FILES="$CONFIG_FILES worlds/Makefile" ;; + "worlds/haxima-1.002/Makefile") CONFIG_FILES="$CONFIG_FILES worlds/haxima-1.002/Makefile" ;; + "worlds/haxima-1.002/music/Makefile") CONFIG_FILES="$CONFIG_FILES worlds/haxima-1.002/music/Makefile" ;; + + *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + $as_echo "$as_me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. +if test -n "$CONFIG_FILES"; then + + +ac_cr=' ' +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && +_ACEOF + + +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + . ./conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then + break + elif $ac_last_try; then + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done +rm -f conf$$subs.sh + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && +_ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\).*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\).*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" + +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 +$as_echo "$as_me: error: could not setup config files machinery" >&2;} + { (exit 1); exit 1; }; } +_ACEOF + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +fi # test -n "$CONFIG_FILES" + +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF + +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 +$as_echo "$as_me: error: could not setup config headers machinery" >&2;} + { (exit 1); exit 1; }; } +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +shift +for ac_tag +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 +$as_echo "$as_me: error: invalid tag $ac_tag" >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + ac_file_inputs="$ac_file_inputs '$ac_f'" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} + fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } ;; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac + ac_MKDIR_P=$MKDIR_P + case $MKDIR_P in + [\\/$]* | ?:[\\/]* ) ;; + */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +ac_sed_dataroot=' +/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s|@configure_input@|$ac_sed_conf_input|;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +s&@MKDIR_P@&$ac_MKDIR_P&;t t +$ac_datarootdir_hack +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + ;; + :H) + # + # CONFIG_HEADER + # + if test x"$ac_file" != x-; then + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} + else + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + fi + else + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 +$as_echo "$as_me: error: could not create -" >&2;} + { (exit 1); exit 1; }; } + fi +# Compute "$ac_file"'s index in $config_headers. +_am_arg="$ac_file" +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $_am_arg | $_am_arg:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || +$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$_am_arg" : 'X\(//\)[^/]' \| \ + X"$_am_arg" : 'X\(//\)$' \| \ + X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$_am_arg" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'`/stamp-h$_am_stamp_count + ;; + + :C) { $as_echo "$as_me:$LINENO: executing $ac_file commands" >&5 +$as_echo "$as_me: executing $ac_file commands" >&6;} + ;; + esac + + + case $ac_file$ac_mode in + "depfiles":C) test x"$AMDEP_TRUE" != x"" || { + # Autoconf 2.62 quotes --file arguments for eval, but not when files + # are listed without --file. Let's play safe and only enable the eval + # if we detect the quoting. + case $CONFIG_FILES in + *\'*) eval set x "$CONFIG_FILES" ;; + *) set x $CONFIG_FILES ;; + esac + shift + for mf + do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # Grep'ing the whole file is not good either: AIX grep has a line + # limit of 2048, but all sed's we know have understand at least 4000. + if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then + dirpart=`$as_dirname -- "$mf" || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`$as_dirname -- "$file" || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir=$dirpart/$fdir + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done + done +} + ;; + + esac +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + +test $ac_write_fail = 0 || + { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi + + +cat <. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u="sed s,\\\\\\\\,/,g" + depmode=msvisualcpp +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> "$depfile" + echo >> "$depfile" + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" + # Add `dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # With Tru64 cc, shared objects can also be used to make a + # static library. This mechanism is used in libtool 1.4 series to + # handle both shared and static libraries in a single compilation. + # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. + # + # With libtool 1.5 this exception was removed, and libtool now + # generates 2 separate objects for the 2 libraries. These two + # compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 + tmpdepfile2=$dir$base.o.d # libtool 1.5 + tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 + tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.o.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + tmpdepfile4=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/doc/CVS/Entries b/doc/CVS/Entries new file mode 100644 index 0000000..41cfae4 --- /dev/null +++ b/doc/CVS/Entries @@ -0,0 +1,7 @@ +/GAME_RULES/1.3/Tue Jan 23 08:32:13 2007// +/GHULSCRIPT/1.4/Mon Jun 30 09:42:47 2003// +/MAP_HACKERS_GUIDE/1.7/Tue Jan 23 08:32:13 2007// +/USERS_GUIDE/1.31/Sat Oct 10 23:31:19 2009// +/null.gif/1.1/Mon Aug 28 12:39:23 2006/-kb/ +/users_guide.html/1.8/Sat Oct 27 05:46:49 2007// +D diff --git a/doc/CVS/Entries.Log b/doc/CVS/Entries.Log new file mode 100644 index 0000000..3fe78de --- /dev/null +++ b/doc/CVS/Entries.Log @@ -0,0 +1,2 @@ +A D/engine_extension_and_design//// +A D/world_building//// diff --git a/doc/CVS/Repository b/doc/CVS/Repository new file mode 100644 index 0000000..fe6e416 --- /dev/null +++ b/doc/CVS/Repository @@ -0,0 +1 @@ +nazghul/doc diff --git a/doc/CVS/Root b/doc/CVS/Root new file mode 100644 index 0000000..4d8737a --- /dev/null +++ b/doc/CVS/Root @@ -0,0 +1 @@ +:ext:gmcnutt@nazghul.cvs.sourceforge.net:/cvsroot/nazghul diff --git a/doc/GAME_RULES b/doc/GAME_RULES new file mode 100644 index 0000000..893b236 --- /dev/null +++ b/doc/GAME_RULES @@ -0,0 +1,491 @@ +Contexts & Control Modes +------------------------ + +There are 2 contexts: +* Party +* Combat + +In party context: +* A single icon in the center of the screen represents the entire player party +* A single icon represents npc parties (which consist of one or more + characters) + +In combat context there are three different modes of control: +* Solo mode, where a single party member moves while the others do nothing +* Follow mode, where the player controls the party leader and the other member + follow him/her/it +* Round-robin mode, where the player moves each party member in turn + +Place Types +----------- + +And there are 4 types of places: +* Wilderness (party mode) +* Town (party mode) +* Dungeon room (combat mode) +* Temporary combat map (combat mode) + +Place To Place Movement +----------------------- + +U5 is the basic model. Linux cloned unix, nazghul is trying to clone u5. But +there is at least one feature of u5 I cannot stand: first person dungeons. So +those have to go. + +In u5, the player walks around the FP dungeon and when he enters a room the +view switches back to a sane top-down combat map. Things get interesting when +the player leaves the dungeon. + +But first, note that all party member must exit the same way. This simple rule +presents a problem for nazghul: not all party members necessarily share the +same passability rules. So, for example, if a floater crosses a body of water +and exits off the map, what happens if the other party members can't get across +the water? So this problem needs to be solved. And I think the way to solve it +is to do a check before allowing the first party member to exit. The check +consists of running a pathfinding alg from each other party member to the exit +point. If a party member can't find a path the player gets a message and the +exit is denied. This is a simple, rather stupid way to do it (it ignores the +possibility of mechanisms or spells being able to create passages, for example, +which could lead to pathological cases). And things get even hairier when we +consider that a passability check to the destination is also necessary, which +I'll cover below. Now u5 did not have any of these issues because everyone in +the party had the same exact passability. If I can't figure out any other way +to do it, that will be my solution as well. + +Now, let's consider what happens when the player party exits a dungeon combat +room. There are 3 possibilities. + +First, the party may exit to a dungeon corridor tile. If the tile was occupied +by an npc party then combat on a temporay map immediately ensued. Upon exit +from combat the party was on the same exact tile (exiting temporary combat maps +in a certain direction does not move the party to the tile in that direction - +a sensible strategy which I will emulate). + +Next, the party may exit to a dungeon corridor tile with a pit or a field. I've +never seen a case with an impassable energy field, so probably u5 maps were +designed to avoid that tricky case. In general, corridors outside dungeon rooms +were gauranteed to be passable. Unfortunately I don't have that luxury, due to +the principle of freedom of expression. (The Principle of Freedom of Expression +states that I don't have any control over the scripts fed to the engine.) + +Finally, the party may exit to another dungeon room. Note that in u5 entrance +was gauranteed in all dungeon rooms. Again, u5 controlled the script, the +party's passability was hardcoded, and everyone in the party had the same +passablity (and the number of party members had an upper limit). + +Now, I want to get this damned thing finished. And I'm willing to sacrifice +some dearly held feature ideas to make that happen. Here are the features which +are causing problems: + +* The party will have a fixed passability mask specified at load time. This + mask is a property of the party. It is not derived from the party members' + masks. It is fixed. The purpose of this is to allow the engine to + sanity-check combat map and dungeon room entrances at load time. If a map + fails the check the engine refuses to load the game. + +* The party will have a fixed upper limit on the number of party members + specified at load time. Again, this is to allow sanity-checking of entry + zones in combat and dungeon room maps. + +* Combat maps and dungeon room maps must have an "entry zone" on all four + sides. Even if the map is never placed such that the player party could + possibly enter there, it doesn't matter. All four sides will have an entry + zone. The zone must be able to fit the maximum number of party members with + the party passability mask. + + The engine will be pretty flexible with zones. The algorithm will first + search, starting at the midpoint of the map edge, for a passable tile. Once + it finds one it will then attempt to pathfind from there to n other passable + tiles, where n is the maximum number of party members. So the zones need not + be square regions centered on the map edge or anything like that. + + Furthermore, combat maps will not be persistent, even in dungeons. They will + be loaded afresh each time they are entered. + +* I'll disallow placing autoportals in the entry zones. This will be checked at + load time when the portal is declared. + +* Everyone in the party will have a superset of the party passability mask. + It's ok if they have extra passability (permanent or temporary). + +* Party members cannot teleport out of dungeon rooms. They can teleport within + dungeon rooms, and I'll allow teleport spells which move the whole party at + once. + +* Portals which lead into dungeon rooms must have an entry zone around their + destinations. This will be checked at load time when the portal is defined. + +Now given these limitations we can solve all of our problems. + +The Exit Problem +---------------- + +All party members must exit a dungeon room the same way. (I'm going to lift +this restriction on temporary combat maps because the party will not change +location upon exit). If a party member attempts to exit via an edge or a portal +the engine will check the destination place and location. If that place and +location is not passable to the *party* then I will reject the move (note that +if the tile is occupied by a non-hostile npc party it is not passable). If I +cannot pathfind from any other party member to the exit point then I will +reject the move. + +Exit From Dungeon Room To Wilderness or Town +-------------------------------------------- + +There are several possibilities here. But impassability is not one of them - +that's tested in the Exit Problem. + +First, the destination tile might be occupied by a hostile npc party. In this +case combat begins immediately on a temporary combat map. Upon exit from that +combat the party will occupy the destination tile. + +Next, the destination tile might contain an automatic portal. The standard +rules for autoportals apply in this case. + +Finally, the destination tile might be empty in which case the party simply +lands there. + +Exit From Dungeon Room To Dungeon Room +-------------------------------------- + +Since entrance to the next room is guaranteed, there should be no issues +here. Note that upon entrance to a dungeon room (or regular combat) the player +party is positioned first and then the npc party. + +That should handle dungeon rooms. Towns are very similar to dungeons, except +that the engine is always in party context in towns and combat context in +dungeons. But in towns the party can still exit via a portal or by walking off +the edge of the map. The exit rules from town are the same (except of course +the pathfinding rule for party members because we're in party mode). + +Entering Wilderness +------------------- + +* If the destination tile's terrain is impassable and there is no unoccupied + vehicle there then entry fails +* Else if a non-hostile npc party is there then entry fails (revisit: add a + push mechanism?) +* Else if a hostile npc party is there then the player immediately enters a + temporary combat map. If combat succeeds then when it is over the party is on + that tile. If an autoportal was there then it is ignored. +* Else if an autoportal is there then it's ignored (revisit - necessary?) + +Entering Temporary Combat Maps +------------------------------ + +* If not all player party members can be placed then combat is denied. The npc + party will not be removed from the map in this case. + +---------------------------------- + +Moving In Party Mode +-------------------- + +Possible outcomes: +* blocked by non-hostile +* fought combat +* game over +* couldn't enter combat +* success +* impassable +* couldn't enter dungeon +* noplace to go +* blocked by vehicle +* entered dungeon + +if the destination tile is occupied { + + /************************************************************************** + * In older versions moving toward a hostile npc party was implicitly + * interpreted as an attack. This may cause some user confusion when + * moving from one place to another, depending on how other features are + * implemented. Examples to consider are exiting town off a map edge, + * entering town via a map edge and passing through a portal or other means + * of teleporting. In all of these cases the user cannot see the + * destination when deciding to move, but he expects the move to take him + * to a new place. + * + * One way to deal with this is what I have here: block the move (and let + * the caller print a user message explaining what happened). I can think + * two other ways to deal with this. One, let the attack happen. Two, try + * to "bump" the npc out of the way to allow passage. + * + * Letting the attack happen opens up other problems we must solve: + * What happens when combat is over - do we then run through this algorithm + * again to see if the move now succeeds? What if the destination is an + * autoportal entrance? + * + * Trying to bump also opens up more issues. What if the bump fails? Should + * we allow any npc to be bumpbed? What about npcs in vehicles? What if we + * bump them onto an autportal (or should that be disallowed)? + * + * Since these solutions require yet other solutions to support them, I + * tend to disfavor them. + *************************************************************************/ + + return blocked by npc + +} else if the destination tile contains an autoportal and autoportals are not + ignored { + + /************************************************************************* + * I give automatic portals higher priority than passability. This is + * mainly to allow ships to have access to towns which are placed on land + * but which may have a port. Passability should be determined by checking + * the town map to see if it allows entrance, not checking the terrain the + * tile is on. + *************************************************************************/ + + if portal destination is a dungeon { + if dungeon can be entered { + return entered dungeon + } else { + return couldn't enter dungeon + } + } else { + recur on portal destination with autoportals disabled + if recursion resulted in combat { + retry recursion and return results + } else { + return recursion results + } + } +} else if the destination tile is impassable { + + if the tile has a vehicle (empty) and the player is not in a vehicle { + + move party to destination + + return success + + } else { + + return impassable + + } +} else if the destination tile is off-map { + if this place has no parent map { + return noplace to go + } else { + + /********************************************************************* + * Yes, I'm making the following unconditional with no further checks. + * The parent tile is _always_ and _unconditionally_ passable. + * Consider everything that could make that tile impassable: + * --Terrain on parent map... don't care + * --Autoportals leading elsewhere... ignore them + * --Npc's... they aren't allowed on town tiles in the wilderness, + * and if one sneaks through ignore it + * --Fields... unlikely, and don't care + * --Vehicles (when player is already in one)... ignore them (and + * don't allow player to abandon a vehicle over a town, otherwise + * we can leak vehicles since consecutive abandonments will + * clobber previous ones) + * See notes on the ship problem in discussion #1 below. + *********************************************************************/ + move party to tile on parent map + return success + } +} else if the party is in a vehicle and the destination tile also contains a + vehicle { + return blocked by vehicle +} else { + move party to destination + return success +} + +Exiting Dungeon Rooms +--------------------- + +* You cannot exit dungeon rooms via edges. I know this differs from u5, but + dungeons are just different from u5. Unlike u5, a nazgul dungeon room can be + arbitrarily large. In effect a dungeon room is more like a dungeon level. +* The only way in or out of dungeon rooms are portals or party teleport + effects. +* To avoid the stranded party member effect, dungeon exits will work like + u6. First, the party must be in follow mode. When the party leader attempts + to enter a portal all party members must be able to pathfind to the portal + within N steps. If any cannot then entrance is denied. + +if party is not in follow mode or +if any party members cannot pathfind to the portal within N steps { + failed +} else { + call party move routine on portal destination (autoportals enabled?) + case blocked by non-hostile { + failed + } + case fought combat { + retry + } + case game over { + game over + } + case couldn't enter combat { + failed + } + case success { + success + } + case impassable { + failed + } + case couldn't enter dungeon { + failed + } + case noplace to go { + portal connection error + } + case blocked by vehicle { + failed + } + case entered dungeon { + restart dungeon loop + } +} + + +---------------------------------------------------------------------------- +Design Discussion #1: Stepping off a map edge +---------------------------------------------------------------------------- + +There are two ways to implement this. One way is to emulate u5, where stepping +off a town map took the party to the wilderness map and the party was located +directly over the town. Recall that in u5 when entering a town the party always +appeared in town at the same entrance, so this was fine. + +Another way to implement this was suggested by Sam: stepping off the edge of +town takes you to the wilderness and moves the party one tile in the direction +of travel. Stepping onto a town makes the party appear on the map edge +corresponding to the side of town entered from. It's a nice touch, but it is a +bit of an iceberg. The advantages of this approach are: + +* It's more intuitive to the player +* It allows games where a town blocks passages in the wilderness (for example a + fortress town guarding a passage through the mountains) +* Player's can save some time by entering a specific side to reach a specific + part of town more quickly +* Player's can avoid parts of town they don't like +* It allows towns with ports and docks for ships to enter and exit from the + wilderness, as well as foot traffic through a gate on another side of town + +The disadvantages are: + +* If the player does end up directly over the town in the wilderness, how does + he enter and from which direction? This can be solved with a player prompt. +* If the player tries to walk off a map edge but the move fails, what should + the player see? One possibility is to move the player over the town in this + special case, provided we can solve the reentry problem above. +* If the player teleports onto a town, what should happen? One possibility is + he does not enter the town, but may enter as noted above. Another is that he + enters from the direction of travel, another is that he lands in the center + (or the teleport fails). I like the first solution best because it's + simplest. + +Example: the player tries to step off a map edge, but the tile in the direction +of travel is occupied by a hostile npc party in a ship. +1. First the party is moved to the wilderness directly over the town +2. Next the party engages the hostiles in combat, using a combat map comprised + partially of the terrain beneath the town and partially of the terrain + beneath the hostile. Entrance to combat is not gauranteed, since the terrain + beneath the town may be impassable to the party (the party may have entered + the town through a portal). +3. If combat entry fails then the move is done. The hostile npc remains next to + the town. +4. If combat entry succeeds then the party will still be on the town and the + empty npc ship will be visible next to town. + +In general, I want to completely separate combat from movement - at least for +version 1.0. In fact, I'm probably going to disable the implicit attack that +occurs when you try to step on a tile with a hostile npc. Attacks will be +explicit with the (A)ttack- command like u4/u5. + + +[the ship problem] + +Another issue Sam and I discovered the other night is with passability on the +parent map. We were in a ship on the wilderness and entered town while still on +the ship. This worked because the edge of town we entered on had a tile +passable to the ship. But exiting didn't work... the tile the town occupied on +the parent map had land passability. Here's a disadvantage to the rule! But +this needs to work. This is the reason I added the clause that moving off the +edge of a town map _always_ works as long as it has a parent map. Ah... much +simpler. + + +---------------------------------------------------------------------------- +Design Discussion #2: Should the party move to the destination tile after +succeeding in combat? +---------------------------------------------------------------------------- +I'm thinking "no". U5 did not. And taking the opposite apporach might result in +some surprises for the player. For example, if the hostile npc party was +standing on an autoportal, after combat when the player party moves to occupy +that tile should the autoportal be invoked? Consider what the player would see: +first, he sees the npc party on the wilderness. Next, he attacks and sees +combat. When he exits combat he expects to go back to the wilderness, but +instead he is autoportalled somewhere. Confusing. + +Also, if the npc party left behind a vehicle then it would be most apparent to +the player that they've just captured a vehicle if it's sitting next to them +upon exit from combat. + +Furthermore, I can't think of a good reason to say "yes". My original reason +involved exiting from towns, but with the outcomes of Design Discussion #1 I no +longer think this is an issue. When the party exits town and encounters a +hostile npc party then after combat they will be over the town, and are free to +continue moving or to reenter. + +However, what if the party enters a portal but the destination tile contains a +hostile npc party? If combat is entered, then after combat should the player +still be standing at the portal entrance? Or at the portal destination? + +One way to work around that problem is to treat autportaling specially. Having +the move routine return a result code is one way. When the party steps on an +autportal the move routine calls itself recursively on the portal +destination. If combat occurs the recursive call can return a code to that +effect, and the calling layer can then do the recursive call again in the case +of combat. Since the hostile npc party should be gone at that point the +recursive call will "succeed". + +---------------------------------------------------------------------------- +Design Discussion #3: Complications when entering portals +---------------------------------------------------------------------------- + +What should happen when a portal destination is on impassable terrain? What if +a portal itself is on impassable terrain? + +In the case where a portal entrance is really a town entrance, the passability +of the terrain the portal is on should not be a consideration. Instead, the +engine should check and see if the town edge in question has some passable +terrain the party can be moved to. + +But what about other cases? It looks rather strange when the player can step +from the shore onto a whirlpool - especially when the whirlpool is linked to +another whirlpool in the middle of some ocean. Entering whirlpools on a ship +makes perfect sense. But if the ocean is usually impassable to the party, what +then? + +I think that except for the special case of town entrances the passability of +the tile a portal is on should be a consideration. If the party can't leap into +the ocean, they shouldn't be able to leap into a whirlpool. + +Likewise the destination passability should also be a consideration. On the one +hand, it might be kind of fun to let the player drive a ship through a moongate +and get marooned on dry land - because the player can always walk away. But +letting the player get marooned someplace they can't get out of seems +unfriendly. On the other hand, maybe I shouldn't be trying to make that +decision for game designers. After all, it won't crash the engine. + +Ok, yes, that's a good principle to follow. Portal links are completely under +the game developers control, so I'll leave it to them. Terrain passability will +not be a consideration for portals, either on the source or on the destination. + +Well, I tried it and discovered that ships can turn when stranded. This is sort +of disconcerting, so I tried to disable that by having the turning code check +for impassable terrain. And then that broke the ship-exit-town problem! I still +think that this is a good principle, though, so I'll simply permit turning +while stranded. This will also permit the case where a ship portals to a +stranded destination, but right next to it is another auto-portal, so the ship +can still enter that autoportal and escape. Weird, but I'm not going to lose +sleep over it. + diff --git a/doc/GHULSCRIPT b/doc/GHULSCRIPT new file mode 100644 index 0000000..180d015 --- /dev/null +++ b/doc/GHULSCRIPT @@ -0,0 +1,794 @@ +The GhulScript Specification + + +-Conversation + +A conversation is a set of other conversations and a set of keyword-response +pairs. + + := CONV tag { IMPORT { } + NATIVE { }} + := tag | + := | + := tag + +The lookup rules determine how to match a keyword to a response. The order of +searching qr_pairs for a keyword match is as follows: + + 1. The NATIVE section of a conversation, in the order specified + 2. Each conversation in the IMPORT section, in the order specified + 3. The DEFAULT keyword + +Note that rule 2 is recursive (and if I haven't said it yet circular inclusion +of conversations is disallowed). The DEFAULT keyword is a special keyword used +when a search fails. Other special keywords include HAIL, used when starting a +conversation, and BYE, used when ending a conversation. + + +--Special Keywords + + Normally a keyword is something the player types during a conversation, but + the following keywords are special in that the engine generates them + automatically in certain situations. + + DEFAULT If the player keyword does not match anything in the + conversation, then the engine looks up the response for the + DEFAULT keyword instead. This gives NPC characters the chance + to customize their "I don't know" response. + + HAIL When the conversation first starts up, before the player has a + chance to give a query, the engine will check if the + conversation has a response for the HAIL keyword and will + invoke it if so. This gives NPC characters a chance to have the + first word. + + BYE When the conversation terminates, after the player has issued + his last query and received a response, the engine will check + if the conversation has a response to the BYE keyword and will + invoke it if so. This gives NPC characters a chance to say + "Farewell" or have the last word. + +The player may type these keywords and they will be looked up in the usual way. + + +--Responses + +In the grammar above a qr_pair is a (which is a simple string) and a +tag. The tag refers to a response. Each response is defined separately in its +own construct. Because responses are independent you may mix them with +different keywords in different conversations as you like. The syntax for a +response declaration is like this: + + := RESP tag + + := { } + + := SAY string | + TRADE | + TURN_AWAY | + SET_FLAG flag | + CLEAR_FLAG flag | + TAKE GOLD | + CHANGE_PARM | + TAKE_ITEM tag | + GIVE_ITEM tag | + JOIN | + ATTACK | + GET_AMOUNT | + + + /* Proposed constructs: */ + MENU | + BREAK + + := +int | -int + := { } + := tag + := int + + := GET_YES_NO | + CHECK_PARM operator int | + CHECK_FLAG flag int bool | + CHECK_ITEM tag | + CHECK_MEMBER tag + + := int + + := { } + := + := string + := int + + := | + + := | + + + SAY The SAY command prints a line on the console. It prints the + literal string that follows it with no formatting. + + TRADE The TRADE command invokes the trading subroutine of the game + engine, providing it a list of items and prices to trade. The + engine automatically adds buy/sell and quantity prompts and + handles the exchange of money and goods. + + When the player opts to Buy he sees the list of goods and + prices. He can buy as many as he cares to and can afford (in + other words the merchant has an endless supply of the goods + listed). + + When the player opts to Sell then the engine scans player + inventory and lists any of the items from inventory which + appear on the trade list. The sell price is fixed at 1/4 of the + buying price. This constant is currently hard-coded in the + engine and applies to all trade situations. + + TURN_AWAY + The TURN_AWAY command causes the NPC to terminate the + conversation without player consent. The player will see a + console message like "Hawknoz turns away." and then + conversation mode will be over. + + SET_FLAG + The SET_FLAG command sets the value of the specified flag, + causing a subsequent CHECK_FLAG to evaluate to true. The + opposite of SET_FLAG is CLEAR_FLAG. + + CLEAR_FLAG + The opposite of SET_FLAG. + + TAKE_GOLD + Decrement the player's gold counter by the indicated + amount. The engine will not decrement beyond zero. (Note that + there is no corresponding GIVE_GOLD simply because I haven't + needed it). + + CHANGE_PARM + Change the indicated parameter by the indicated amount. If the + amount is negative the engine will not decrement beyond + zero. (Note the absence of a SET_PARM - again because I haven't + needed it yet). + + TAKE_ITEM + Decrement one count of the indicated item type from player + inventory. If the player has none in inventory then this has no + effect. If the tag does not resolve to an item type then this + has no effect. + + Note: currently this does not add the item to the NPC's + inventory, as one might expect. + + GIVE_ITEM + The opposite of TAKE_ITEM. This does not actually remove + anything from the NPC's inventory. + + GET_YES_NO + Prompt the player to answer yes or no. The player must respond + with one or the other (ie he cannot escape from the + prompt). "Yes" means true and "no" means false. + + CHECK_PARM + Check if the given expression is true for the indicated + parameter. + + CHECK_FLAG + Test if a flag is set. + + CHECK_ITEM + Check if the player has at least one count of the indicated + item in inventory. + + CHECK_MEMBER + Check if the indicated character has joined the player party. + + + /* Proposed constructs */ + + MENU Use the status window to display a list of choices to the + player. When the player selects an entry from the list the + corresponding set of responses is executed. Upon completion - + unless one of the responses was a BREAK or EXIT - the menu will + "loop", displaying the list of choices again. MENUs may be + nested. + + BREAK Break out of a MENU loop. Execution resumes after the MENU + block. If the MENUs are nested, only the lowest level MENU is + aborted. + +---Flags + +The SET_FLAG, CLEAR_FLAG and CHECK_FLAG responses all operate on flags. A flag +is an unsigned 8-bit integer id for a boolean value. + +Flags may be global or per-conversation. Global flags may be accessed from any +conversation in the game. Per-conversation flags apply only to the conversation +in which they appear. Different conversations may use the same per-conversation +flag id but each will have its own value for the flag. Per-conversation flag +ids have the high bit clear (giving them the range 0 to 127) and global flag +ids have the high bit set (giving them the range 128 to 255). + +Note: Initially all flags are clear. When savegames are implemented flag values +will need to be saved/restored, so in the future there will need to be syntax +for specifying initial flag values. + + +---Parameters + +The CHANGE_PARM and CHECK_PARM responses operate on parameters. A parameter is +a signed 32-bit id for an integer value. + +The engine reserves all negative parameter ids. The following parameter ids are +currently supported by the engine: + + -1 AMOUNT + The AMOUNT parameter refers to the value obtained by the last + GET_AMOUNT response. A value of -1 means the player did not + enter an amount at the last prompt (i.e. escaped out of the + prompt). + + -2 GOLD + This refers to the player's gold counter. + + -3 FOOD + This refers to the player's food counter. + + -4 ACTIVITY + This refers to the speaking NPC party's current activity + code. Activity codes are used by schedules. This parameter + allows conversation scripts to change their response based on + what the npc party is currently doing. For example, in u5 the + NPC merchants would not trade with the player when they were + not in their shop. + +All parameter id's of 0 or greater are available for use by the game script. + +All parameters are global in scope. + +Note: Initially all non-reserved parameters are zero. When savegames are +implemented parameter values will need to be saved/restored, so in the future +there will need to be syntax for specifying initial parameter values. + + +---Branching + +The GET_YES_NO, CHECK_PARM, CHECK_FLAG, CHECK_ITEM and CHECK_MEMBER responses +are all branching responses. They each specify a test and two sets of +responses. If the test evaluates to true then the first set executes, otherwise +the second set executes. + + +---Examples + +These are not final, but are experimental examples for my own benefit while +designing changes to the language. + +Example: a healer. This example illustrates how one might use some as-yet +unimplemented constructs like MENU, GET_PARTY_MEMBER, CHANGE_HP and an +unsupported PARTY_MEMBER parameter to script a healer. Note the heavy +duplication of code for each menu response, and also the dubious syntax for +checking if the player escaped out of the GET_PARTY_MEMBER prompt. + +RESP r_healer { + SAY "Hail, traveler! Do you require my healing services?" + GET_YES_NO { + MENU { + "Heal 30g" { + CHECK_PARM GOLD >= 30 { + SAY "Who requires healing?" + GET_PARTY_MEMBER + CHECK_PARM PARTY_MEMBER = 0 { + SAY "Never mind then." + }{ + CHANGE_HP PARTY_MEMBER +10 + } + }{ + SAY "You lack the gold, my friend." + } + } + "Cure 50g" { + SAY "Whom shall I cure?" + GET_PARTY_MEMBER + CHECK_PARM PARTY_MEMBER = 0 { + SAY "Never mind then." + }{ + SET_POISONED PARTY_MEMBER false + } + } + "Resurrect 500g" { + SAY "Whom shall I call back from the dead?" + GET_PARTY_MEMBER + CHECK_PARM PARTY_MEMBER = 0 { + SAY "Never mind then." + }{ + SET_DEAD PARTY_MEMBER false + CHANGE_HP PARTY_MEMBER +10 + } + } + "Done" { + SAY "Very well." + BREAK /* exit the MENU loop */ + } + } + }{ + SAY "Very well." + } +} + + +Example: A weapon merchant. The example illustrates the use of a +yet-unimplemented technique whereby one response "calls" another by referring +to its tag. The r_weaponsmith_hail response invokes the r_sell_to_player +response in order to avoid some of the duplication seen above in the healer +example. "Arguments" to the "called" response take the form of parameters set +by the caller before invoking it. + +Note that I left the SELL clause blank because I was at a loss on how to +proceed. There is no proposed syntax for building a MENU list on the fly at +runtime, and that is essentially what is required for the SELL clause as +written. An alternative is not to use a MENU for sell, but to use hand-crafted +checks for items in player inventory followed by offers to buy them one type at +a time off the player. + +Also note the use of multiplication in the r_sell_to_player response. This is +currently not implemented. + + +RESP r_sell_to_player { + SAY "How many would you like?" + GET_AMOUNT + CHECK_PARM AMOUNT > 0 { + SET_PARM COST (AMOUNT * COST) + CHECK_PARM GOLD >= COST) { + SAY "Here you go."; + TAKE GOLD COST; + GIVE t_sword AMOUNT; + }{ + SAY "You don't have enough gold!"; + } + }{ + SAY "Changed your mind, eh?"; + } +} + +RESP r_weaponsmith_hail { + SAY "Hail, traveler! Do you require my healing services?" + GET_YES_NO { + MENU { + "Buy" { + MENU { + "Swords 100g" { + + + /* + * "Call" the other response after setting up the + * "arguments" to it. + */ + SET_PARM ITEM $t_sword; + SET_PARM COST 100; + $r_sell_to_player; + + } + /*** add other items here ***/ + "Done" { + BREAK; + } + } + } + "Sell" { + + } + "Done" { + SAY "Very well."; + BREAK; /* exit the MENU loop */ + } + } + }{ + SAY "Hrumph."; + EXIT; + } +} + +---------------------------------------------------------------------------- +Spell Effects + +An effect is a change to an object, map or place. + +A recurring effect is attached to a target and takes effect every turn. Wether +or not an effect is recurring is determined by its duration. A duration of < 0 +means it recurs indefinitely (until some other effect removes it). A duration +of > 0 indicates the number of turns for which the effect will recur before +expiring. A duration of 0 means the effect is not recurring. Henceforth, I +DON'T DISTINGUISH BETWEEN RECURRING EFFECTS AND EFFECTS IN THIS DISCUSSION. + +A spell attaches a set of effects to a set of targets. A conversation response +may do the same. So may using an item, stepping on a terrain, or engaging a +mech. When it comes to effects, the difference between all these things lies in +how the set of targets is specified. Specifying the set of effects probably +won't change much between them. But this discussion is about spells. I only +mention those other things as a reminder. + +An effect is a change, so what can be changed? It depends on the target. I've +listed below some of the most reasonable things I can think of. + + Character Hit Points + Character Mana Points + Character Strength + Character Dexterity + Character Intelligence + Character Experience + Character Level + Object Glow + Character or Party Turns + Object Location + Character or Party Alignment + Character, Vehicle, Terrain or Mech Passability + Character or Party Can Take a Turn + Character is Dead + Hidden Objects are Revealed + Time is Stopped + Magic is Negated + Wind Direction + Object's Existence + Terrain Type + Object's Edibility + Ambient Glow + Mechanism Jam + Mechanism Signals + Existing Effects (an effect that affects another effect) + Object User Bits* + Object User Fields* + +Those last two (marked with asterisks) probably don't make a lot of sense to +you now. Why are they there? Well, I can't think of everything a map hacker is +going to want to design into a game. And some things I don't think require +engine support. For example, u4/u5 had a virtue system. Currently nazghul does +not. But by taking advantage of the user bits or user fields a map hacker can +add one. These bits and fields have no semantic value to the engine, but they +can be interpreted by the ghulscript. They can be modified by effects, and they +can be checked by conversation scripts (and perhaps eventually mech +scripts). Remind me to provide an example somewhere if you're interested in, +that's all I'm going to say for now. + +An effect specification is a piece of ghulscript which declares an effect. Once +declared, an effect can be referred to elsewhere in the script (such as terrain +or spell type declarations). I'll show the syntax further down (after I figure +out what it is ;-)). + +Anyway, the first part of an effect specification is WHAT it affects. I refer +to this as the SUBJECT OF THE EFFECT. + +The next part specifies IN WHAT WAY it effects it. This part of the spec +depends upon what type of attribute is affected. Here's a table: + +============================================================================ +Target Type | Subject | Subject Type | Notes +============================================================================ +Character | Alignment | SET | +Character | Dead | BOOL | Necessary? Or HP==0 enough? +Character | Dexterity | INT | +Character | Experience | INT | +Character | Field[0-9] | INT | Generic attributes +Character | Flags | SET | Generic flags +Character | Hit Points | INT | +Character | Immunity | SET | Effect immunities +Character | Intelligence | INT | +Character | Level | INT | +Character | Lose Turn | BOOL | +Character | Mana Points | INT | +Character | Occupation | TAG | Change jobs +Character | Passability | SET | +Character | Protections | SET (?) | +Character | Species | TAG | Were-shift somebody +Character | Speed | INT | +Character | Strength | INT | +Effect | Existence | BOOL | Remove another effect +Mech | Passability | SET | Applies to current state +Mech | Jam | BOOL | +Mech | Signal | INT | +Object | Glow | INT | +Object | Location | (TAG, INT, INT) | Meaning (place, x, y) +Object | LocationDelt | (TAG, INT, INT) | +Object | Visible | BOOL | Applies to particular object +Object | Existence | BOOL | Used to destroy an object +Object | Type | TAG | Morph an object +Object | Edibility | BOOL | Turn something into food +Party | Lose Turn | BOOL | +Party | Speed | INT | +Party | Alignment | SET | +Party | Reveal | BOOL | Can see invisible objects +Party | TimeStop | BOOL | Only this party can take turns +Party | MagicNegated | BOOL | Spellcasting disabled +Place | Wind Directi | DIR | Wind direction +Place | Ambient Glow | INT | +Terrain | Passability | SET | +Tile | Terrain Type | TAG | +Vehicle | Passability | SET | + +The engine can infer the subject type from the target type and subject, so +there's no need to specify it in the script. But map hackers will need this +info as they design effects. If a spec gives a value which is the wrong type +then the engine needs to complain about it at load time. + +The value of an effect is the amount or direction by which the subject changes, +or the value to which the subject is set. For scaler and vector subject types +the value of the effect might be a signed offset. This would be added to the +existing value. The possible operations for each subject meta-type are listed +below: + +============================================================================ +Subject Metatype | Operations +============================================================================ +scaler | assign, add, subtract, multiply +vector | assign, add, subtract, multiply +tag | assign, instantiate, destroy(?) +bool | assign, invert +set | assign, intersect, union, invert +============================================================================ + +Multiple operations can be combined. + +An effect is a change which is achieved by some means, and the means indicates +wether or not the effect will apply to a particular target. Some targets may be +immune to a particular means so that the effect will not apply. Or some targets +may have modifiers which apply to a particular means which reduce the value of +the effect. + +At this point I can speculate about what an effect specification is going to +look like: + +EFFECT MagicFireball { + target_type Character; + subject HitPoints; + value -10 + method (MAGIC|BURN) +} + +// Reduce the value of burn effects by 10 +EFFECT Protection { + target_type Character; + subject Protections; + value +10 + method (BURN) +} + +// Make a character immune to burning effects +EFFECT BurnImmunity { + target_type Character; + subject Immunity; + value +BURN + method (MAGIC) +} + +// Here's an effect which might be produced by a sword: +EFFECT EdgedWeaponDamage { + target_type Character; + subject HitPoints; + value -5 + method (EDGED_WEAPON) +} + +// And here's one which might be produced by a shield: +EFFECT EdgedWeaponDamageProtection { + target_type Character; + subject Protections; + value +5 + method (EDGED_WEAPON) +} + +But what if the character is immune to heat damage? To accomodate immunities in +the game the effect must specify HOW the effect is achieved. Now the engine has +no interest in the semantics here, so we can use an open set and let map +hackers decide what they want the elements of a set to "mean". + +Not to get too far off track, but you can see that I'm thinking about the way +sets should be represented in ghulscript. Currently we use a bitmask. This may +be a bit too esoteric for normal people. So instead I'm considering a new +ghulscript construct to pre-declare set elements similar to an +enumeration. I see no reason to discard the C bitwise operators as a means of +constructing sets. + +EFFECT Burn { + // same as before + method (BURN) // where BURN is a script-defined set element +} + +So how does the engine know not to burn a character if that character is immune +to burn effects? It does this by checking the character's immunity set. If any +element in the effect method set is not in the character immunity set, then the +effect is applied. For those who like to think about such things, consider an +effect which confers immunity to effects which confer immunity... :-) + +How is the effect achieved? + + Poison + Fire + Acid + Sleep + Paralysis + Petrify + Frighten + Encourage + Extensible Bits + +How is the effect quantified? + + Integer + Integer Offset + Boolean + Direction + Location + Location Offset + Object Type + Terrain Type + Terrain Map + +How is the target specified? + + Object + Object Type + Tile + Tile Rectangle + Tile Circle + Alignment + Species + Occupation + Circle Arc + Passability + +What special effects apply? + + Change the character's sprite to prone (sleeping, unconscious or dead) + Shake the screen + Animated missile + Animated shockwave (arc-specified) + Chain lightning + Meteor strike + Sounds + Screen flash + Alpha transparency + +Examples: + + An Nox (Cure Poison) + What: Existing Character Effect + How: Poison + Value: False + Target Method: Select Party Member + + In Nox Por (Poison) + What: Character Hit Points + How: Poison + Value: -10 + Dur: Indefinite + Target: Tile + Cumul: No + Multi: No + + Because it affects specifically Character hit points, the engine knows + to search the targeted tile for a Character object. Because it does not + support multiple targets only the first Character found will be + affected. Because the effect is not cumulative the engine will search + the list of existing effects for the Character to make sure a Poison + effect is not already at work. If not then it checks the Character's + immunity mask and if the Poison bit is set then the effect is + ignored. Otherwise it inserts the new effect in the list of effects for + the character and applies -10 to the Character hit points. Since the + duration is indefinite the engine does not decrement the duration + counter. + +Effects which create objects are a bit different then what is discussed +above. Such an effect has no subject, as it is not changing an existing +object's attributes. Instead it is creating a new subject. + +There are several ways to carry out object creation. First of all, we must +unfortunately distinguish between characters and other object types. The reason +is that most objects have a type, and this type specifies the default values +for an object. But characters do not have a single type. Instead they have a +species, an occupation, a schedule and a conversation. Perhaps they should have +a type which combines all these elements. The downside is you end up with a lot +of character types which will only have a single instance because the type info +is so specific to a single character, which is why I deviated from the rule a +bit. Anyway, besides that distinction we must also recognize that sometimes we +want to create a new object from scratch and sometimes we want to clone an +existing object. + +EFFECT SlimeCloneWhenDamaged { + target_type Character; + target_method Effected; + subject Existence; + hook HpReduced; + source (); + value new; + probability 0.25; +} + + + +Prototype header file: + + // What the effect applies to. + enum effect_target_type { + effect_target_type_none = 0, + }; + + // How to pick what the effect applies to. + enum effect_target_method { + effect_target_method_none = 0, + effect_target_method_affected, + }; + + // What is being changed about the thing the effect applies to? + enum effect_subject { + effect_subject_none = 0, + effect_subject_affected, + }; + + // List of subject value types. + enum effect_value_type { + effect_value_none = 0, + effect_value_tag, + effect_value_bool, + effect_value_int, + effect_value_float, + }; + + // How is the value of the subject going to be changed? + struct effect_value { + enum effect_value_type type; + union value { + char *tag; + int _bool:1; + int _int; + float _float; + }; + }; + + // List of events which invoke an effect ("hooks" an effect is attached + // to) + enum effect_hook { + effect_hook_none = 0, + effect_hook_hp_reduced, + }; + + // List of ways to specify a target for an effect. + enum effect_target_method { + effect_target_none = 0, + effect_target_effected, // whatever the effect is attached to + }; + + // List of operators applied to the subject + enum effect_operator { + effect_operator_none = 0, + effect_operator_assign = '=', + effect_operator_new = 'n', + effect_operator_delete = 'd', + effect_operator_clone = 'c', // the subject + effect_operator_add = '+', // w/ assignment to subject + effect_operator_subtract = '-', // w/ assignment to subject + effect_operator_multiply = '*', // w/ assignment to subject + effect_operator_divide = '/', // w/ assignment to subject + }; + + // The effect data structure. + struct effect { + char *tag; + struct list list; + enum effect_target_type type; + enum effect_target_method target_method; + enum effect_subject subject; + enum effect_hook hook; + enum effect_source source; + enum effect_operator operator; + struct effect_value value; + float probability; + }; + + // Create and initialize an effect structure from ghulscript. + extern struct effect *effect_load(class Loader *); + + // Apply an effect (attempt to, anyway). + extern int effect_apply(struct effect *effect, class Object *affected); + + // Properly deallocate an effect structure. + extern void effect_destroy(structeffect *effect); + diff --git a/doc/MAP_HACKERS_GUIDE b/doc/MAP_HACKERS_GUIDE new file mode 100644 index 0000000..006cf68 --- /dev/null +++ b/doc/MAP_HACKERS_GUIDE @@ -0,0 +1,304 @@ +$Id: MAP_HACKERS_GUIDE,v 1.7 2007/01/23 08:32:13 icepic Exp $ + + MAP HACKER'S GUIDE TO NAZGHUL/HAXIMA + + + "The map is not the territory." + --Alfred Korzybski + + + INTRODUCTION + +So you want to modify Haxima? Or maybe you find Haxima pathetic and know you +can do better. Then you've come to the right place. The Haxima scripts will +give you lots of examples on how to do things, if you can figure them +out. Since you're a smart guy I'm sure you can, but an explanation here or +there might speed things up. Here you'll find a discussion of the principles of +how to build a game like Haxima with the nazghul engine. + +This manual is still in its infancy. If you don't find what you're looking for +feel free to email requests or suggestions to + + nazghul-devel@lists.sourceforge.net + +Happy hacking! + + + CONCEPTS + +COMPOSITE SPRITE + First, see SPRITE. A composite sprite is a sprite made up of layers of + other sprites. + +GOB Scheme data associated with a kernel data structure. The kernel never + accesses this data, it is meant to be used by scripts to customize or + augment these data structures. Objects, object types and astral bodies + all optionally have gobs. + +OBJECT Something which exists on the map and is not part of the scenery. + +OBJECT TYPE + Read-only data associated with and shared by a class of objects. A type + is a kernel data structure which describes attributes that are common + to an entire class of objects. For example, all short swords have the + same sprite and basic attributes, and all sword objects refer to the + sword object type to provide these attributes. In fact, simple objects + like short swords may be implemented in the kernel as little more than + an object type and a location. + + There are several classes of object type: a generic base class, an arms + type, a vehicle type, and a field type. Every object type class has a + fixed set of attributes. These can be extended by the script, however, + by attaching a gob to the object type. + +SPRITE An animation sequence which shows an object. Every visible object has a + sprite. Sprites can be composed of other sprites, see COMPOSITE SPRITE. + +SPRITE SET + Usually sprite images are collected into files with lots of images in + them. A sprite set refers to the file and stores information like + how big the images are, how many are in the file, etc. Sprites refer to + sprite sets. Different sprites can share some of the same images, + although few ever do. + +TAG A name given to a kernel data structure so that it can be referred to + by a scheme variable. Tags are important because they can be used when + saving a game to allow objects to refer to one another when the game is + reloaded. + + + QUICK START: HOW TO CHANGE A MAP + +Start haxima with the -d option: + + $ haxima -d + +Start a game, then invoke the terrain editor using the Ctrl-T command. Like a +paint program, terrain editing has the concept of a current "brush", which is a +terrain type. + +The following keybindings are in effect: + + Arrow keys - move the cursor + [0-9]-Arrow - jump the cursor + Space/Enter - change the terrain under the cursor + PgUp/PgDn - scroll the available terrain list to change the brush + Home/End - jump to the top or bottom of the available terrain list + C - copy; set the terrain under the cursor as the brush + F - terrain fill (uses the 4-neighbor algorithm) + ESC - abort edit mode + Ctrl-[0-9] - save the brush in a "quick access" terrain slot + [0-9] - load the brush with the quick access terrain slot + +"Quick Access" slots start as all walls. Palette.scm holds the list of terrain +types. + +When you are done editing, save the game like you normally would. Your changes +will be there the next time you start the game. If you want your changes to be +part of a game started from "Start New Game" the current process involves +modifying some Scheme files. + +To add your changes to the "Start New Game" scripts you need to find your +changes in the file you saved and copy-and-paste them into the proper startup +.scm file. In general, you must find the name of the place which is using the +map and search for it in the .scm files, then replace the starting map with +your own. + + + KERNEL API + +This section documents the kernel calls available to scripts. The document +format is moduled after the UNIX man pages, which, like so many things in UNIX, +have served well enough over the last 30-odd years to be worth emulating. + +---------------------------------------------------------------------------- +NAME + kern-sprite-apply-matrix - apply a color conversion matrix to a sprite + +SYNOPSIS + (kern-sprite-apply-matrix ) + +DESCRIPTION + The purpose of this is to alter the colors of a sprite. The idea is you + create one sprite, probably in grayscale, and use this procedure to + make different colored variations of it. This works by applying the + matrix to the sprite, resulting in a linear remapping of the sprite + colors to another set of colors. The matrix is in the form: + + (list (list ) + (list ) + (list ) + (list )) + + This matrix is applied to the red, green and blue components of each + pixel in the sprite like this: + + r = R * c00 + G * c01 + B * c02 + k1 + g = R * c10 + G * c11 + B * c12 + k2 + b = R * c20 + G * c21 + B * c22 + k3 + + Where r, g and b are the result and R, G and B are the original values + for the pixel. The result for a component will be clamped to [0, 255]. + + The underlying image is copied before being modified. This means that + if the sprite is a clone of another sprite, the other sprite will not + be modified. + +RETURNS + The modified sprite. If something is wrong with the arguments it + returns the original, unmodified sprite. + +EXAMPLES + + This applies an identity matrix, which does nothing: + + (kern-sprite-apply-matrix ksprite + '((1 0 0) + (0 1 0) + (0 0 1) + (0 0 0))) + + This matrix will convert a grayscale image to blue: + + 0 0 0 + 0 0 0 + 0 0 1 + 0 0 0 + + This will swap red and blue: + + 0 0 1 + 0 1 0 + 1 0 0 + 0 0 0 + + This will lighten every pixel by a fixed offset: + + 1 0 0 + 0 1 0 + 0 0 1 + 64 64 64 + + This will darken every pixel by a scale factor: + + 0.5 0 0 + 0 0.5 0 + 0 0 0.5 + 0 0 0 + +---------------------------------------------------------------------------- +NAME + kern-sprite-blit-over - blit one sprite over another one + +SYNOPSIS + (kern-sprite-blit-over ) + +DESCRIPTION + The images of the destination sprite will be copied and then modified + by the blit, so you don't have to worry about other sprites that refer + to the same images. The two sprites should have the same number of + frames and the same dimensions or the results are not defined. The + modification will not be saved with the game, so it needs to be redone + at load time. + + Blitting over uses more memory than decorating sprites because it makes + an extra copy of all the sprite frames. It is faster, though, because + it only blits all the sprite components once when it is created, + instead of every time it is rendered. + + Blitting is also preferrable for composite weapon sprites, because + composite sprite building does not have good support for recursively + composite sprites. Unreadying composite weapon sprites will strip them + down to their bare sprite. But weapon sprites built via blitting over + do not have this problem, because stripping down a blitted-over sprite + has no effect. + +RETURNS + The modified destination sprite. + +EXAMPLES + (define s_fancy_shield (kern-sprite-blit-over s_shield s_emblem)) + +---------------------------------------------------------------------------- +NAME + kern-sprite-clone - copy a sprite + +SYNOPSIS + (kern-sprite-clone ) + +DESCRIPTION + Use this when you want to make a modified version of a sprite but still + want to keep the original intact. You can assign the clone its own tag + and henceforth refer to the tag as a scheme variable, or you can pass + in nil and just use the return value. + +RETURNS + The cloned sprite, or nil if 'original' was a bad arg or a memory + allocation failure prevented creation of the clone. + +EXAMPLES + ;; Clone grass and turn it brown to make dirt + (kern-sprite-clone s_grass 's_dirt) + (kern-sprite-apply-matrix s_dirt green-to-brown-matrix) + +---------------------------------------------------------------------------- +NAME + kern-type-set/get-gob - associate scheme data with an object type + +SYNOPSIS + (kern-type-set-gob ) + (kern-type-get-gob ) + +DESCRIPTION + + kern-type-set-gob associates 'cell' with the object type 'ktype', so + that it can later be found by scripts via kern-type-get-gob. 'ktype' + must be the result of a call to kern-mk-obj-type. + + The purpose is to add game-specific information to a kernel data + structure so that closures called from the kernel can find it. This + information is not visible to the kernel. + + Unlike the gobs attached to objects, gobs attached to object types are + not written to the save-game file. For that matter, object types are + not written, either, and must be reloaded for every game. + +---------------------------------------------------------------------------- +NAME + kern-sprite-strip-decorations - remove all decorations from a base + sprite + +SYNOPSIS + (kern-sprite-strip-decorations ) + +DESCRIPTION + Remove all decorations from and discard them (see + sprite_append_decoration()). Useful for rebuilding decorated sprites + from scratch. + + This does not remove layers built via kern-sprite-blit-over. + +RETURNS + The base sprite. + +EXAMPLES + ;; Make a ship with sails. + (define s_ship (kern-sprite-append-decorations (list s_ship s_sails))) + + ;; Nah, changed my mind. + (define s_ship (kern-sprite-strip-decorations s_ship)) + + +---------------------------------------------------------------------------- +NAME + - + +SYNOPSIS + () + +DESCRIPTION + +RETURNS + +EXAMPLES + diff --git a/doc/USERS_GUIDE b/doc/USERS_GUIDE new file mode 100644 index 0000000..7394adf --- /dev/null +++ b/doc/USERS_GUIDE @@ -0,0 +1,671 @@ + + + USERS GUIDE TO NAZGHUL + +Nazghul is an old-school RPG clone modeled after those made in the heyday of +top-down, 2d tile-based graphics. It is specifically modeled after Ultima V, so +if you've played that game then this should be familiar. + + + INSTALLING THE GAME + +If you downloaded a source distribution see the top-level INSTALL file. + +If you downloaded a windows binary just unzip the distribution using Winzip or +similar. + + + STARTING THE GAME + + +On Linux/UNIX: + + $ haxima.sh + +On Windows: + + Use the start menu or desktop icon + +You can play the Tutorial first or jump right in with Start New Game. + + + SAVING THE GAME + +You can save your game at any time while playing by using the CTRL-S key +sequence for the S)ave command. An unlimited number of saved games is +permitted. When you restart, use the Journey Onward option from the main menu +to select a saved game to continue. + +If you die, the game will exit, and when you restart it will pick up where you +last saved via the Journey Onward option. + + + EXITING THE GAME + +You can quit at any time by pressing Q for the Q)uit commmand. It will prompt +you to save if you like and then exit. + + + ORIENTATION + +If you are unfamiliar with U5 I recommend the Tutorial option available from the +Main Menu when you start the game. Here are some more notes to help you get +started. + + Exploring + +When you start you will have a party consisting of one character known +initially as The Wanderer. The icon for this character will be in the center of +the map view on the left. Explore around a bit using the arrow keys to +move. Below the map you'll see a little window with a prompt. This gives you +hints when you're entering commands to tell you what type of input the command +wants. For example, if you type 'x' (for e[x]amine) the command prompt will +say: + + Xamine-(ESC to exit) + +Which means it wants you to hit the arrow keys and move the targeting +cursor. When you hit 'ESC' instead the command will cancel. Pretty much all +commands can be canceled by hitting 'ESC'. + +To get a detailed explanation of where you are and what time it is, use the AT +command by pressing '@'. There is no displayed clock in the game, so this is the +only way to tell time other than guesstimating from the position of the sun or +finding time telling devices inside the game. + + Talking + +When you start the game, after selecting what kind of character to create, you'll +see your first NPC to the south. To talk to the NPC press 't' for T)alk. +This brings up a targeting crosshair. It might start out on the NPC or +on your character, it it's on you then move it to the NPC with the arrow keys +and hit enter. + +That starts a conversation. During conversation you enter a keyword and the NPC +will respond. For example, type NAME or JOB and see what this NPC says. When +you are done talking type 'bye' or hit enter by itself. + + Getting Stuff + +Eventually you will want to follow the road down to the chamber on the lower +left. The chamber is marked by mysterious runes on its walls. Within the +chamber is a chest. + +Walk over next to the chest and O)pen it by hitting 'o' and using your arrow +keys to indicate a direction. The chest will open and deposit a bunch of stuff +on the ground. + +G)et the stuff using the 'g' key. Among the items will be some basic weapons, +armour and spell reagents as well as some scrolls and potions. + + Equipping + +To see your stuff hit 'z' for Z)tats and scroll around. The left and right +arrow keys will switch between different status panes. Hit ESC when you tire of +admiring yourself and your loot. + +To R)eady the weapons and armor hit 'r' then select them. Hit ESC when done. + + Mixing A Spell + +To M)ix a heal spell type 'm' for mix. Next enter the spell name, in this case +'m' again for "Mani", and hit ENTER. Next, select Ginseng and Spider Silk from +the reagents list, and hit 'm' to mix them. Finally, you can mix batches of a +given spells at once, so you will need to input the quantity of "Mani" spells +you wish to produce. Enter '1' here, and you will have made a "Mani" spell, a +spell of minor healing. More on spells later. + + Entering and Exiting Towns + +When you are ready to face the world walk to the edge of the map and bravely +step off. You will zoom out to Wilderness Mode, and your entire party (all one +of you) will appear as an icon in the center. To re-enter take a step south (at +which point you will see a shrine icon where you just were) and step north +again. Now you know how to enter and exit towns. Congrats. + +When you enter a town, unless you have some enemies there, you will start out +in "follow mode", which means you control the party leader and everybody else +in the party tries to keep up. But if hostiles are in town you will be in +"character mode", which means you control each party member in turn. To switch +between these two mode use the 'f' key. This will make more sense when you have +more characters join your party. + +IMPORTANT: when you eventually get somebody to join you, don't forget about + Follow Mode (the 'f' key). It's much easier to have everybody follow + your main dude around than to always individually control them. + + + USER INTERFACE + +Astronomy Window + + Above the map you'll see a little window embedded in the frame which shows + the position of the sun and two moons. It also shows the phase of the + moons, which is important for moongate travel. + +Wind + + Below the map, embedded in the frame, is the wind direction + indicator. Currently the wind only affects ships. Tacking across the wind + provides the best rate of travel, the wind at your back is second best, and + heading into the wind is the worst. Note that this indicates the direction + the wind is blowing _FROM_. + +Command Prompt + + Unlike u4/u5/u6 the command prompt has its own window, just below the wind + indicator. Interactive command prompts appear here, as well as the things + the player says in conversation. + +Status Window + + In the top right you have a general-purpose window for viewing and + selecting lists of things. Normally it shows some basic party stats, but + its contents change as required by user commands. For example, (R)eady will + turn it into a selection list. + + Normally the window lists all the player's party members and shows their + current hit points and status. The status is reflected in one or more + little icons. For example, if a character is poisoned you'll see a little + green skull-and-crossbones. You can get a better description of the status + by using the Z)tatus command to inspect individual party members. + +Foogod Window + + It sounds sacrilegious, but that's just my acronym for Food/Gold + Window. This little window appears below the status window and shows the + turn, food and gold counters as well as the current combat status and any + active global effects (e.g., "Magic Negated"). If you board a vehicle it + will also show you the hit points for the vehicle. The effects are shown + with cryptic little icons that appear until the effect expires. + + Magic Negated + + Spellcasting fails. + + Quicken + + Party members get extra turns per round. + + Reveal + + Invisible things are visible. + + Time Stop + + Everything in the world suspends while Party members get to move. + + X-ray Vision + + Party members can see through walls. + +Console Window + + Finally on the right hand side you'll find the window where all the game + messages get logged. + + + PLAYER COMMANDS + + +Here's your chance to let the sweat dry on your mouse - all commands are via +the keyboard. As it should be, forever and ever amen. + +Addendum: For the sake of convenience to mousephiles, targeting prompts will +accept input from the mouse. But the shortcut keys are faster. + +General syntax: + + = one of the four arrow keys + = a party member, selected from a list by scrolling with the arrow + keys and pressing or + = an inventory item, selected from a list + = a spell, selected from a list + = spacebar + = a combat target, selected by moving the crosshairs and pressing + or (or using the mouse and left-clicking) +<*> = varies depending on context + +General commands: + + ......................Move in that direction + A)ttack-..............Initiate combat + B)oard.....................Board/exit a vehicle like a ship or horse + C)ast---<*>...Cast a spell (the last argument depends on the + spell) + E)nter.....................Enter a portal, including up or down ladders + F)ire-................Fire vehicle's weapon (e.g., ship cannon) + G)et-.................Get an object from the ground + H)andle--..Activate a switch or lever + L)oiter-<0-9/sunrise>......Loiter a few hours + N)ew-order--...Swap order of two party members + O)pen-................Open a container or door + Q)uit......................Quit & optionally save the game + R)eady--.....Ready an armament like a weapon, shield, etc. + S)earch-..............Look carefully + T)alk-.............Talk to an NPC + U)se--.......Use an item like a torch or potion + X)amine-...........Examine map tiles within view + Z)tats.....................Show party stats like inventory, armaments, etc + @)AT.......................Information about where the party is AT, etc + ....................Pass one turn + CTRL-S)ave.................Save a game + CTRL-R)eload...............Reload a game + +Wilderness-only commands: + + K)amp-<0-9/sunrise>-- + ...........................Camp in the wilderness (to heal and recover + mana) or aboard ship (to repair hull damage as + well) + +Town/Dungeon/Combat-only commands: + + A)ttack-.........Attack the specified target + C)ast--<*>........Cast a spell + F)ollow..................Select follow mode, where the party members + automatically follow the party leader. + [1-9]....................Select a party member for solo mode. + [0]......................Select turn-based party mode, where each party + member takes directions one at a time. + K)amp-<0-9/sunrise>......Sleep on a bed. + +Special commands: + + ....................Aborts most commands + +Editing commands (run nazghul with -d): + + CTRL-E)valuate...........Evaluate a scheme expression within the game. For + example, the string: "(kern-obj-relocate + ch_wanderer (list p_shard 51 47) nil)" will + teleport the player to the surface at coords [51 + 47]. + CTRL-O)..................Save the current map to its own file + CTRL-T)erraform..........Alter terrain. This deserves its own section. [1] + CTRL-Z)oom...............Zoom in or out (like peering at a gem but free) + +Shortcuts: + + +/=......................When targeting an attack, moves cursor to next + hostile npc. + -........................When targeting an attack, moves cursor to previous + hostile npc. + ESC......................When wilderness combat is over, exits to + wilderness map. + + MOVEMENT MODES + + +Party Mode (wilderness) + + The party appears as a single icon in the center of the screen. + +Follow Mode (town/combat/dungeons) + + You control the party leader and the other members follow the + leader. Attacking a target will automatically switch to Round-Robin + Mode. The party leader is always the top person in the list who is alive + and still on the current map. Enter follow mode from Solo or Round Robin + Mode by pressing 'f'. + +Solo Mode (town/combat/dungeons) + + You control one party member while the others stand around looking + bored. Enter Solo Mode by pressing the number key associated with the + party member's order in the list. 1 is the first member in the list. + + NOTE: Solo mode can be very useful if one of your party members has greater + passability than the others. For example, if a gazer joins your party + he can float over water. Now imagine the possibilities if you get a + ghost to join your party. + +Round Robin Mode (town/combat/dungeons) + + You control each member in turn. This is the default mode when you enter + combat. To enter Round Robin Mode from solo mode, press 0. To enter from + Follow Mode press 'f'. Yes, confusing to have two methods. I'll fix it + someday. Let me know if you have an opinion. + + + PLACES + +Wilderness: + + In the outdoor or wilderness map the party moves as a single unit. You can + enter into combat with enemy NPC parties by moving into them or waiting for + them to attack you. Likewise you can enter towns, dungeons or moongates by + simply walking into them. + +Wilderness Combat: + + This is a special temporary combat map that pops up when you engage an + enemy NPC party in the wilderness. In this mode you control individual + party members. You return to the wilderness map by having all of your + living party members walk off the edge of the map. (Hint: if combat is over + you can press to quickly leave the map). + +Towns/Dungeons: + + In towns and dungeons you move just like in combat mode. You can control + the individual party members in turn, have one of them scout around in solo + mode, or control the leader and have the other party members follow. + + + COMBAT + + +What can I say? It's pretty much like u5. Try the flaming oil at night or in an +underground place. Oh, and watch out for gazers. They can charm you. Kill them +or charm them right away. + + + ADVANCEMENT + + +As usual, characters advance a level when they gain sufficient experience +points. There is no maximum level limit. When a character advances his maximum +HP and MP increase, depending on his class, species and personal bonuses. At +the moment of advancment he is fully healed and mana is restored to their new +maximum levels. + + XP Required for Advancement +============================================================================ +Level | XP +============================================================================ +1 | 0 +2 | 32 +3 | 64 +4 | 128 +5 | 256 +6 | 512 +n | 2^(n+5) +============================================================================ + + Attributes + +Characters have three basic attributes: Strength, Dexterity and +Intelligence. These are fixed when the character is created and don't change +during the game. + +Strength + + Strength limits the total weight of readied weapons and armour. Strong + characters do more damage and are better at hitting with heavy or + bludgeoning weapons. It is also used when breaking free of spider webs + (most trolls don't stay ensnared too long...). + +Dexterity + + Dexterity is used when attacking with missile and balanced weaponry, and + helps when avoiding your opponents' blows. It is also needed when + picking locks and disarming trapped chests. + +Intelligence + + Intelligence makes spells more potent and more likely to succeed. + + + MAGIC + + +The example game contains a full complement of spells. The magic system is +similar to Ultima 5 and Ultima 6: you select a spell by entering magic +syllables. A spell name is a combination of one to four syllables. + +The syllables, spell names and reagent mixtures provided in the example game +are a direct ripoff of Ultima 5. If you don't have a u5 reference manual lying +around then the tables below will help: + + Table 1: Reagents +============================================================================ +Name | Abbrev used in spell table +============================================================================ +Black Pearl | BP +Blood Moss | BM +Garlic | GA +Ginseng | GI +Mandrake Root | MR +Nightshade | NI +Spider Silk | SS +Sulphurous Ash | SA +============================================================================ + + Table 2: Spells +============================================================================ +Syllables | Effects | Reagents | Party/Combat +=================================(1)======================================== +An Nox | Cure Poison | GI, GA | PC +An Zu | Awaken | GI, GA | PC +Grav Por | Magic Missile | SA, BP | C +In Lor | Light | SA | PC +Mani | Heal | GI, SS | PC +Wis Sanct | Detect Trap | SA | PC +An Sanct Ylem | Disarm Trap | BM | PC +---------------------------------(2)---------------------------------------- +An Sanct | Unlock | SA, BM | PC +An Xen Corp | Repel Undead | GA, SA | C +In Wis | Locate | NI | P +Rel Hur | Change Wind | SA, BM | P +In Nox Por | Poison Missile | NI, BM, BP | C +Bet Flam Hur | Fire Spray | BP, SA, BM | C +In Bet Xen | Summon Vermin | SS, BM, SA | C +---------------------------------(3)---------------------------------------- +In Flam Grav | Fire Field | SA, BP, SS | C +In Zu Grav | Sleep Field | GI, BP, SS | C +In Nox Grav | Poison Field | NI, BP, SS | C +Vas Flam | Fire Ball | BP, SA | C +Vas Lor | Great Light | SA, MA | PC +---------------------------------(4)---------------------------------------- +An Grav | Dispel Field | BP, SA | PC +In Sanct Grav | Energy Field | MA, BP, SS | C +In Sanct | Protection | SA, GI, GA | PC +Wis Quas | Reveal Hidden | NI, SA | PC +Bet Por | Blink (Caster) | BP, BM | C +---------------------------------(5)---------------------------------------- +In Ex Por | Unlock Magic | SA, BM | PC +An Ex Por | Magic Lock | SA, BM, GA | PC +In Zu | Sleep | GI, NI, SS | C +Vas Mani | Great Heal | GI, SS, MA | PC +Rel Tym | Quickness | SA, BM, MA | PC +Kal Xen | Summon Beast | SS, MA | C +---------------------------------(6)---------------------------------------- +An Xen Ex | Charm | BP, NI, SS | C +In An | Negate Magic | GA, MA, SA | C +In Vas Por Ylem | Earthquake | BM, MA, SA | C +Quas An Wis | Confuse | MA, NI | C +Wis An Ylen | Xray Vision | MA, SA | PC +In Rel Por | Telekinesis | BP, BM, SS | C +Vas Por | Blink (Party) | MA, BP, BM | P +---------------------------------(7)---------------------------------------- +In Nox Hur | Poison Wind | NI, SA, BM | C +In Zu Hur | Sleep Wind | MA, GI, BM | C +In Quas Corp | Fear | NI, MA, GA | C +In Quas Xen | Clone | NI, MA, SA, SS, BM, GI | C +Sanct Lor | Invisibility | NI, MA, BM | C +Xen Corp | Kill | NI, BP | C +---------------------------------(8)---------------------------------------- +An Tym | Stop Time | MA, GA, BM | WC +In Flam Hur | Flame Wind | MA, SA, BM | C +In Vas Grav Corp | Energy Wind | MA, SA, NI | C +In Mani Corp | Resurrect | GA, GI, SS, SA, BM, MA | PC +Kal Xen Corp | Summon Undead | SS, MA, NI | C +Vas Rel Por | Gate Travel | SA, MA, BP | P +============================================================================ + +[1] In Towns and Dungeons teleport spells that can move the party from one + place to another will fail unless combat is over and the party is in Follow + Mode. + + + EFFECTS + +From time to time your characters might run into a little trouble with magical +foes, natural hazards, or their own weakness for alcohol. Don't panic. Most +effects are non-fatal, but a few are. + +Asleep (S) + + Sleeping party members will eventually wake up of their own accord. If you + don't feel like waiting use the An Zu spell. + +Charmed (C) + + Enemy wizards might charm party members, causing them to fight on their + behalf. Charm wears off after 10 minutes. + +Diseased (D) + + Some monsters may infect party members with disease. Disease is not fatal, + but it will not wear off until your party member is nearly out of hit + points. + +Drunk (A) + + Anytime your character buys alcoholic drinks or picks them up from the + ground he gets drunk. Drunkenness lasts an hour or so and causes him to + randomly bump into things. + +Ensnared (E) + + When stuck in a spider web, a character will break free after struggling + for a while. The time required to free himself depends on the character's + strength. + +Paralyzed (Z) + + Spiders inject paralyzing venom to make their foes helpless before feeding + on them. Paralysis will wear off after a short random interval. + +Poisoned (P) + + Bogs or spells may poison party members, causing them to lose hit points + every turn until the poison is cured with a spell or potion. Poison is + fatal! It won't wear off like disease. + + + CONVERSATION + + +Start a conversation with an NPC with the T)alk command. During conversation +you type simple inquiries and the NPC responds, sometimes asking you a question +in return. Conversations with shopkeepers will allow you to BUY and SELL +items. Most NPCs respond to the 'NAME' and 'JOB' queries, as well as queries +about their town and fellow townsmen. Their responses usually give you clues to +further fruitful queries. Also, with the special 'JOIN' query you can ask an +NPC to join your party (some will join you, and some will join you only if you +do or say something that impresses them). + + + MISC + +Food is consumed three times per day, one unit for each living party +member. When the food runs out, party members take a point of damage at each +meal time. + + + APPENDIX A: MAP HACKING + +Like many games, "nazghul" is separated into an engine [2] and some data +files. In this case the data files are written in the Scheme programmming +language. If you examine the default start file 'session.scm' you will see that +it is a scheme file which loads the game types from other files and then +defines the starting game variables. + +I encourage people to experiment with modifying the example files or even using +them as a basis to create their own games. The example script code is all +committed to the public domain. The image and sound files come from various +sources - see the COPYING file in the top nazghul directory for details on +where they came from. + +If you want to make a proprietary game you may use the example script files, +but you will probably need to make your own image and sound resource files as +the ones in the examples directory come from other open-source or freeware +projects and their copyright holders might object to proprietary use. + + + APPENDIX B: Spoilers + +These apply specifically to Haxima, and not necessarily to any other game made +with the Nazghul engine. + + Projectile Weapon Stats +============================================================================ +Name To-Hit Damage To-Def Hnds Rng Ammo Weight +============================================================================ +Sling 1d2-2 1d4 -1 1 4 slingstone 0 +Sling+4 3 1d4+4 0 1 6 slingstone 0 +Bow 1d3-2 2d4 -2 2 6 arrow 2 +Crossbow 1d4-2 4d4 -1 2 4 bolt 3 +Doom Staff 1d4 1 +2 2 5 - 2 +Stun Wand [1] -2 1d4 -1 1 6 - 2 +============================================================================ +[1] Temporarily paralyzes target + + Thrown Weapon Stats +============================================================================ +Name To-Hit Damage To-Def Hnds Rng Weight +============================================================================ +Flaming oil [1] -1 1d6 -2 1 4 1 +Spear 0 1d8 +1 1 4 2 +Boulder -2 3d4+1 -2 2 5 10 +============================================================================ +[1] Leaves a temporary burning patch of ground + + Melee Weapon Stats +============================================================================ +Name To-Hit Damage To-Def Hnds Rng Weight +============================================================================ +Dagger 1d4 1d4 1d2 1 1 0 +Dagger+4 1d4+4 1d4+4 1d2+4 1 1 0 +Mace 1d4 1d6+2 +0 1 1 3 +Axe 1d2 2d3+2 +0 1 1 3 +Sword 1d2 1d8+1 1d2 1 1 2 +Sword+2 1d2+2 1d8+3 1d2+2 1 1 2 +Sword+4 1d2+4 1d8+5 1d2+4 1 1 2 +2H Axe 0 4d3+2 -2 2 1 4 +2H Sword 0 2d8+2 1 2 1 4 +Morning star 1d2+2 1d6+1 -1 1 2 3 +Morning star+2 1d2+4 1d6+3 2 1 2 3 +Halberd 1d3+1 2d8-2 1d2 2 2 4 +Staff 1d3 1d4 1d3 2 2 2 +Eldritch blade 2 2d8+5 +0 2 1 2 +Mystic sword +3 1d10+5 +2 1 1 1 +Flaming sword 1d2 1d10+3 1d2 1 1 2 +============================================================================ + + Armor Stats +============================================================================ +Name To-Hit Damage Armor To-Def Weight +============================================================================ +Leather helm -1 - 1d2 - 0 +Leather helm+2 0 - 1d2+2 - 0 +Leather helm+4 0 - 1d2+4 - 0 +chain coif -1 - 1d3 - 1 +Chain coif+4 0 - 1d3+4 - 1 +iron helm -1 - 1d4 - 2 +Iron helm+4 0 - 1d4+4 - 2 +leather armor -1 - 1d4 - 2 +Leather armor+2 0 - 1d4+2 - 2 +Leather armor+4 0 - 1d4+4 - 2 +chain armor -2 - 2d4 - 4 +Chain armor+4 0 - 2d4+4 - 4 +plate armor -4 - 4d4 - 8 +Plate armor+4 0 - 4d4+4 - 8 +Small shield -1 - 0 2 2 +Small shield+4 0 - 0 6 2 +Spiked shield 0 1d5 0 1 3 +Spiked helm 0 1d4 3 0 2 +============================================================================ + + +--gmcnutt (gmcnutt@cableone.net) + + +FOOTNOTES + +[1] Alas, there isn't one. Yet. + +[2] I like to refer to it as a "kernel". This makes me feel like it is really + cool, and like I'm not a loser since Linus Torvalds and I are about the + same age and he works on a kernel, too. diff --git a/doc/engine_extension_and_design/CVS/Entries b/doc/engine_extension_and_design/CVS/Entries new file mode 100644 index 0000000..6789c80 --- /dev/null +++ b/doc/engine_extension_and_design/CVS/Entries @@ -0,0 +1,5 @@ +/ENGINE_CLEANUP/1.2/Sat Nov 6 23:41:45 2004// +/ENGINE_DESIGN_NOTES/1.2/Sat Nov 6 23:41:45 2004// +/README/1.1/Thu Aug 5 01:53:27 2004// +/my_TODO.2004.05.05.txt/1.1/Thu Aug 5 01:53:27 2004// +D diff --git a/doc/engine_extension_and_design/CVS/Repository b/doc/engine_extension_and_design/CVS/Repository new file mode 100644 index 0000000..4125aad --- /dev/null +++ b/doc/engine_extension_and_design/CVS/Repository @@ -0,0 +1 @@ +nazghul/doc/engine_extension_and_design diff --git a/doc/engine_extension_and_design/CVS/Root b/doc/engine_extension_and_design/CVS/Root new file mode 100644 index 0000000..4d8737a --- /dev/null +++ b/doc/engine_extension_and_design/CVS/Root @@ -0,0 +1 @@ +:ext:gmcnutt@nazghul.cvs.sourceforge.net:/cvsroot/nazghul diff --git a/doc/engine_extension_and_design/ENGINE_CLEANUP b/doc/engine_extension_and_design/ENGINE_CLEANUP new file mode 100644 index 0000000..f77cbad --- /dev/null +++ b/doc/engine_extension_and_design/ENGINE_CLEANUP @@ -0,0 +1,40 @@ +* Command-line args. Go through and remove unused/unwanted commands. Document + others in the USERS_GUIDE. + +* Remove all references to the obsolete Turn counter, including the unused work + queue. + +* Remove the useless spriteInit call + +* The two player_party constructors share a lot of common initialization + code. Pull that into a setup method. In fact, the default one is only used by + the suspect player_init() function traditionally invoked on startup so look + at getting rid of it, first. + +* Pull default formation code into combat.c and get rid of formation.[ch]? + Check that reference to it in Party.cpp first. + +* player_party should at least be per-session (even if the session is globally + accessible) to get rid of the creation/destruction conflict in + kern_mk_player. + +* place.c: replace the tile locks with refcounts + +* Move the global Place variable into the global session struct. + +* Use refcounts on all the read-only structures like sprite sets, sprites, + etc. The session needs to hold a reference until done loading, then it should + traverse everything and release its reference. Hmm... no, that may not + work. Anything clicked with a scm_define() will be referenced by the + interpreter... + +* Convert the ObjectType class to a struct, link all the kernel read-only-types + (ROTs) on their own list on the session struct. Use refcounting on them. Ref + them as they are loaded. Objects should also ref/unref them. Destroy all the + RDWR types first in the session, then unref all the ROTs. If any ROTs remain + we can detect a reference leak. + +* Define an interface for plugging other types of script interpreters into the + kernel. The kern_* API should be made generic, and the scheme unpacking left + to a shim layer. Likewise the save code should use some kind of abstraction + layer to pack objects into script code. \ No newline at end of file diff --git a/doc/engine_extension_and_design/ENGINE_DESIGN_NOTES b/doc/engine_extension_and_design/ENGINE_DESIGN_NOTES new file mode 100644 index 0000000..904a675 --- /dev/null +++ b/doc/engine_extension_and_design/ENGINE_DESIGN_NOTES @@ -0,0 +1,200 @@ +* Startup + +Life begins in main() in nazghul.c. First we parse command-line arguments, then +we initialize all the internal "libs" or "modules" (they aren't really modular, +but they are conceptually separate). + +By the time all this is done SDL has been initialized, all the UI widgets are +ready, the internal libs are ready for use and we have an empty player party +allocated (not sure we need that last thing there). + +** commonInit + +Sets the globals: + +Tick - drives the tick work queue, currently only used by the kern-add-tick-job + call, which in turn is currently only used by the moongate sequence + +Turn - drives the turn work queue, which appears to be completely obsolete and + unfreferenced by anyone + +Also seeds srand() and initializes the busywait loop, which in turn is only +used by map.c to add a small delay to projectile animations. + +** screenInit + +Bunch of stuff related to screen colors and special blitting surfaces, but most +importantly this is where SDL_Init gets called to setup the SDL lib. + +** spriteInit + +Initializes the ticks_to_next_animation counter. This could probably be done +statically, eliminating the need for this call altogether. + +** player_init + +Creates a player party object. Do I still need to do this here, just so I can +blow it away on reload? I hope not. Maybe things will be clear by the time I'm +done writing these notes. + +*** player party constructor + +Bunch of harmless initialization. Creates a view for the party, which may be +interesting later... the base Object class destructor will destroy it. + +** eventInit + +Inits the handler stacks (leaves them empty), sets up to record or playback +events, and enables unicode in SDL. + +** windInit + +Sets up the screen rectangles for the viewer, sets default wind direction to +NORTH. + +** formationInit + +Wow, totally forgot about this one. The formation is just a big array of +vectors. The init sets the default formation to this array, accessible via +formation_get_default(), which is still used to this day in combat.c since most +party types don't specify a formation. Damn, I probably haven't looked at that +code for two years. + +** astar_init + +Allocates the priority heap used by the alg. + +** cmdwinInit + +Sets up the screen rects, allocates the line buffer, clears the cmdwin and +opens the cmdwin log file. + +** consoleInit + +Sets up the screen rect, allocates the text buffer, inits all the pointers and +indices and opens the console log file. + +** mapInit + +Creates a persistent camera view, inits the (empty) list of map views, sets up +the screen rects and some flags. + +** vmask_init + +Initializes some vars to empty/nil/etc. + +** combatInit + +Sets combat state to COMBAT_STATE_DONE and zeros out all the other combat vars. + +** foogodInit + +Sets up the screen rects. + +** statusInit + +Sets up the screen rects and dimensions. + + +** soundInit + +Sets up SDL_audio which will kick off a thread that keeps calling into the +sound_mix() function for more stuff to play. We only do this if the useSound +flag is set. + +** nazghul_splash + +Opens a splash image file and blits it to the screen. + +** tick_start + +Kicks off the timer tick thread to generate tick events. + +** playRun + +This loads the session, starts it up, pushes the default tick and quit handlers +then enters the main loop. If the session fails to load it will return an error +to main(), which will + +*** session_load + +The easy part is now over. The global Session pointer is initialized to NULL +statically. session_load() remembers the existing session so it can try and go +back to it if things go badly setting up the new one. On startup, this is moot +since we don't have a session yet. + +session_load() opens the load file, creates a new instance of scheme, creates a +new session instance, then tells scheme to load from the opened FILE +pointer. Scheme runs all the code, most of which invokes calls into the kern +API to setup kernel data structures, objects and parameters. Calls that setup +read-once things like ObjectTypes put themselves on the session data_objects +list for cleanup. + +An important call which must be made by the script is kern_mk_player(). This +function (unconditionally!) destroys the existing player_party created by +player_init() above. This is a hack, plain and simple, and arose mostly due to +the fact that the player party is a global variable. The player party should at +least be per-session and referenced through the global session pointer, which +at least is reasonably well-managed across reloads. + +Either the result of kern_mk_player() will be fed (by the script) to a place +constructor or the script must make an explicit call to kern_obj_put_at() in +order to position the player party on the map. If the target location is a +town, the latter approach MUST be taken, as it knows that it needs to break out +the player party into town mode. The former approach does not handle this +properly (that's a bug). + +If any errors occur session_load cleans up and returns, leaving the original +session active (but in the case of startup, there is no original session, and +odds are good that the player party we allocated back with player_init() has +been destroyed by the call to kern_mk_player). + +If all seems to be well it will destory the old session and interpreter and +make the new session active. + +The next thing it does is call the startSession() method in the player party +class. See below. Upon exit the global Place will be setup. + +It then runs through the list of all the data_objects created by the scheme +script and runs their start function if they registered one. Currently the only +thing that uses this feature is the place, which registers +place_start(). place_start() runs through all the objects in it and calls their +start method. This in turn traverses all the effects attached to the object and +invokes their "apply" closures, if they have one. Currently, the effects which +use this feature are light/great light, protection, charm and invisibility. All +of these examples could be implemented without the apply closure if each object +saved and loaded its light, defense, charm and invisibility status. Whether or +not future effects will need this feature is not clear to me. If an effect +simply changes state, and the state is saved and loaded, I don't think 'apply' +is necessary. + +The final step is to start painting the auxiliary widgets: the screen frame, +the foogod, console and status windows. + +**** kern_init + +This is where all the kernal API calls get poked into the new scheme +interpreter's environment. + +**** kern_mk_player + +This (unconditionally) blows away the current player party and creates a new +one. The player party constructor creates a new view, among other things, but +doesn't add it just yet. Back in kern_mk_player it unpacks and adds the party +members one by one, connects the party and its vehicle (if applicable), and +adds the party to the session. + +The party is added to the session as a data object because there are times +(especially like right after this call, for instance) where the player party is +in "limbo", meaning it isn't on any map or referenced by any place. When the +player enters a town or dungeon is another example. The reason I need the +player party on the data_objects list is so that it will generate a call to +kern_mk_player outside of the context of any place constructor, so that on load +the party is not physically present as an object/icon in the place where the +party members are. + +Note that this call does not put the player party on the map anywhere - it will +be located as a result of being loaded by its place (this will happen within +kern_mk_place()) or the script will explicitly give it a location via +kern_obj_put_at(). This is the case with the script that starts the game for +the first time. diff --git a/doc/engine_extension_and_design/README b/doc/engine_extension_and_design/README new file mode 100644 index 0000000..25309b6 --- /dev/null +++ b/doc/engine_extension_and_design/README @@ -0,0 +1,8 @@ +This directory contains miscellaneous notes on extending and designing +the Haxima engine. + +The contents of this directory do not necessarily correspond to what +_IS_ in the game engine/kernal, but to things which have been proposed +to be added. Keeping these sort of notes in CVS seems like a better +way to communicate than each developer keeping their own notes which +get lost. diff --git a/doc/engine_extension_and_design/my_TODO.2004.05.05.txt b/doc/engine_extension_and_design/my_TODO.2004.05.05.txt new file mode 100644 index 0000000..0a46a87 --- /dev/null +++ b/doc/engine_extension_and_design/my_TODO.2004.05.05.txt @@ -0,0 +1,180 @@ +--------------------------------------------------------------------------- +My TODO from meeting 2004/04/29 +------------------------------- +- Find / rewrite the stencil API (in C, Perl, whatever) + +- Prototype the Object Browser Pane "pictures" code for UI + specification (in C, Perl, whatever) + +- Write Perl scripts for seeded random map generation + +- Do data tables for weapons, armour, etc. + +- Get a good start on world-building + + +--------------------------------------------------------------------------- +Stencil API: +------------ +A stencil is simply a terrain_map used as a stencil. +Each cell (x,y) contains either NULL, or non-NULL. +When blit_map() or blit_terrain() is called, + NULL cells are not blitted + non-NULL cells indicate to blit + the from_map terrain for blit_map() + the fill_terrain terrain for blit_terrain() + + +blit_map (map * to_map, map * from_map_stencil, + int x, int y, int w, int h) +blit_terrain (map * to_map, map * from_map_stencil, + int x, int y, int w, int h, terrain * tt) + +Blitting starts at (0,0) in from_map_stencil, blitting onto an origin +point of (x,y) in to_map. + +Blitting iterates over a region (w,h) wide,high. + +Blitting truncates any coordinate which is not in-bounds of both +to_map and from_map_stencil. + + +--------------------------------------------------------------------------- +Object Browser "Picture" UI-building Code: +------------------------------------------ +An Object Browser "pane" is a rectangular region whose size is +measured in character cells 8x16 pixels in size. + +Standard-sized tiles can be displayed, taking up 4x2 character cells. + +Panes can be defined for different object types, which have different +data to display and which may have a different display layout. +For example, a Terrain and an Item which is a melee weapon have +different data to display. + +An object type may specify multiple pages of panes. +For example, a Being has a lot of data, which may take multiple pages. + +An object type may specify multiple pane views, depending on the state +of the object instance. For example, an Item subtype might specify +different panes for an object instance which is identified versus an +object instance which is not. + + +Pane Specifications: +-------------------- +Panes can be specified by calling a function whose arguments contain +information describing the display. Multiple such functions are +defined for distinct, common types of pane displays. + +new_text_pane (elements_before, + num_lines, lines_of_text, + elements_after) + + - elements_before + is a pane object of full width. + It will be rendered above the text region. + + - num_lines + defines the height in character cells of the central text region. + + - lines_of_text + Contains text to fill the central text region. + + Any individual lines which are longer/wider than the pane + width will be line-wrapped and treated as multiple lines. + + Explicit line breaks within lines_of_text will be kept. + Leading, trailing, and internal spaces will be kept. + Tab characters will be treated as single spaces. + + Text with fewer lines than num_lines will be + space-padded at the end of the vertical space. + + Text with more lines than num_lines will be scrolled within + the central text region. + + - elements_after + is a pane object of full width. + It will be rendered below the text region. + + +new_pane (picture_lines, ...varargs...) + + - picture_lines + An array of lines, each of full width. + Each line contains some mix of literal text + and "Picture Elements". + + Picture Elements are sequences of reserved characters which + define a rectangular region of character cells, serving a + purpose analogous to a '%' specifier in printf(). + + Picture Elements have an origin (x,y) relative to the origin + (1,1) of the array, and a width,height (w,h). Occupying a + rectangular region, they are like a 2D printf() specifier. + + The characters reserved for Picture Elements are + hash '#', carat '^', underscore '_', and pipe '|'. + + The Nazghul window is 1024 pixels wide + -608 == -(19 * 32) for map view window + -48 == -(16 * 3) for borders + This leaves 368 pixels wide for the Object Browser pane, + which translates to (368 / 16) 23 character cells wide. + + Example: (Obj Browser pane for a Terrain tile + + "#### Terrain: " + "#### ################ " + " " + "Passability: " + + // 1 (4x2 == 32x32 pixels == 1 tile) + // 2 (16x1 characters) + tile(this.tile), // Tile for this object + text(this.name), // Name for this object + + +Hmmm...how to express a "foreach" kind of thing... +I think such a thing is not initial-attempt functionality, unless the +means of implementation and the script syntax become obvious. +For now, a passability display would be hard-coded to display up to N +movement modes. + Note also that we will probably want a distinct set of terrain for + wilderness-scale maps and town-scale maps (which probably means + two terrain palettes), and perhaps two sets of movement modes + since "jumping" perhaps makes no sense at wilderness scale. + Hmmm...or maybe the _party_ has different modes from the + _characters_ or some such thing... + + " ######## ###### (##) " + + // One or more movement modes: + // 1 (8x1 characters) movement mode name + // 2 (6x1 characters) speed adjective "slow", "normal", ... + // 3 (2x1 characters) movement point cost + + +Algorithm for Parsing a "Picture" +--------------------------------- +(See UI_panes.perl) + + + + + + + + + + + + + + + + + + +--------------------------------------------------------------------------- diff --git a/doc/null.gif b/doc/null.gif new file mode 100644 index 0000000..18c5200 Binary files /dev/null and b/doc/null.gif differ diff --git a/doc/users_guide.html b/doc/users_guide.html new file mode 100644 index 0000000..cf97e41 --- /dev/null +++ b/doc/users_guide.html @@ -0,0 +1,2445 @@ + + + +Nazghul Users Guide + + + + +

+ USERS GUIDE TO NAZGHUL +

+

+Nazghul is an old-school RPG clone modeled after those made in the heyday of +top-down, 2d tile-based graphics. It is specifically modeled after Ultima V, so +if you've played that game then this should be familiar. +

+ + +

+ CONTENTS +

+ + + +

+ INSTALLING THE GAME +

+ +

+If you downloaded a source distribution see the top-level INSTALL file. +

+

+If you downloaded a windows binary just unzip the distribution using Winzip or +similar. +

+ + + +

+ STARTING THE GAME +

+ +

+On Linux/UNIX: +

+

+ $ haxima.sh +

+

+On Windows: +

+

+ Use the start menu or desktop icon +

+

+You can play the Tutorial first or jump right in with Start New Game. +

+ + +

+ SAVING THE GAME +

+

+You can save your game at any time while playing by using the CTRL-S key +sequence for the S)ave command. An unlimited number of saved games is +permitted. When you restart, use the Journey Onward option from the main menu +to select a saved game to continue. +

+

+If you die, the game will exit, and when you restart it will pick up where you +last saved via the Journey Onward option. +

+ + +

+ EXITING THE GAME +

+

+You can quit at any time by pressing Q for the Q)uit commmand. It will prompt +you to save if you like and then exit. +

+ + +

+ ORIENTATION +

+

+If you are unfamiliar with U5 I recommend the Tutorial option available from the +Main Menu when you start the game. Here are some more notes to help you get +started. +

+ + +

+ Exploring +

+

+When you start you will have a party consisting of one character known +initially as The Wanderer. The icon for this character will be in the center of +the map view on the left. Explore around a bit using the arrow keys to +move. Below the map you'll see a little window with a prompt. This gives you +hints when you're entering commands to tell you what type of input the command +wants. For example, if you type 'x' (for e[x]amine) the command prompt will +say: +

+

+ Xamine-<target>(ESC to exit) +

+

+Which means it wants you to hit the arrow keys and move the targeting +cursor. When you hit 'ESC' instead the command will cancel. Pretty much all +commands can be canceled by hitting 'ESC'. +

+

+To get a detailed explanation of where you are and what time it is, use the AT +command by pressing '@'. There is no clock in the game, so this is the only way +to tell time other than guesstimating from the position of the sun. +

+ + +

+ Talking +

+

+You'll see your first NPC to the south. To talk to the NPC press 't' for +T)alk. This brings up a targeting crosshair. It might start out on the NPC or +on your character, if it's on you then move it to the NPC with the arrow keys +and hit enter. +

+

+That starts a conversation. During conversation you enter a keyword and the NPC +will respond. For example, type NAME or JOB and see what this NPC says. When +you are done talking type 'bye' or hit enter by itself. +

+ + +

+ Getting Stuff +

+

+Eventually you will want to follow the road down to the chamber on the lower +left. The chamber is marked by mysterious runes on its walls. Within the +chamber is a chest. +

+

+Walk over next to the chest and O)pen it by hitting 'o' and using your arrow +keys to indicate a direction. The chest will open and deposit a bunch of stuff +on the ground. +

+

+G)et the stuff using the 'g' key. Among the items will be some basic weapons, +armour and spell reagents as well as some scrolls and potions. +

+ + +

+ Equipping +

+

+To see your stuff hit 'z' for Z)tats and scroll around. The left and right +arrow keys will switch between different status panes. Hit ESC when you tire of +admiring yourself and your loot. +

+

+To R)eady the weapons and armor hit 'r' then select them. Hit ESC when done. +

+ + +

+ Mixing A Spell +

+

+To M)ix a heal spell type 'm' for mix. Next enter the spell name, in this case +'m' again for "Mani", and hit ENTER. Next, select Ginseng and Spider Silk from +the reagents list, and hit 'm' to mix them. Finally, you can mix batches of a +given spells at once, so you will need to input the quantity of "Mani" spells +you wish to produce. Enter '1' here, and you will have made a "Mani" spell, a +spell of minor healing. More on spells later. +

+ +

+ Entering and Exiting Towns +

+

+When you are ready to face the world walk to the edge of the map and bravely +step off. You will zoom out to Wilderness Mode, and your entire party (all one +of you) will appear as an icon in the center. To re-enter take a step south (at +which point you will see a shrine icon where you just were) and step north +again. Now you know how to enter and exit towns. Congrats. +

+

+When you enter a town, unless you have some enemies there, you will start out +in "follow mode", which means you control the party leader and everybody else +in the party tries to keep up. But if hostiles are in town you will be in +"character mode", which means you control each party member in turn. To switch +between these two mode use the 'f' key. This will make more sense when you add +more characters to your party. +

+

+IMPORTANT: when you eventually get somebody to join you, don't forget about + Follow Mode (the 'f' key). It's much easier to have everybody follow + your main dude around than to always individually control them. +

+ + +

+ USER INTERFACE +

+ +

+Astronomy Window +

+

+ Above the map you'll see a little window embedded in the frame which shows + the position of the sun and two moons. It also shows the phase of the + moons, which is important for moongate travel. +

+ +

+Wind +

+

+ Below the map, embedded in the frame, is the wind direction + indicator. Currently the wind only affects ships. Tacking across the wind + provides the best rate of travel, the wind at your back is second best, and + heading into the wind is the worst. Note that this indicates the direction + the wind is blowing _FROM_. +

+ +

+Command Prompt +

+

+ Unlike u4/u5/u6 the command prompt has its own window, just below the wind + indicator. Interactive command prompts appear here, as well as the things + the player says in conversation. +

+ +

+Status Window +

+

+ In the top right you have a general-purpose window for viewing and + selecting lists of things. Normally it shows some basic party stats, but + its contents change as required by user commands. For example, (R)eady will + turn it into a selection list. +

+

+ Normally the window lists all the player's party members and shows their + current hit points and status. The status is reflected in one or more + little icons. For example, if a character is poisoned you'll see a little + green skull-and-crossbones. You can get a better description of the status + by using the Z)tatus command to inspect individual party members. +

+ +

+Foogod Window +

+

+ It sounds sacrilegious, but that's just my acronym for Food/Gold + Window. This little window appears below the status window and shows the + turn, food and gold counters as well as the current combat status and any + pending Effects. The effects will be printed in cryptic little codes like + "N" for magic negated. If you board a vehicle it will also show you the hit + points for the vehicle. Here are some of the codes and what they mean: +

+ +
+ +
+ Magic Negated +
+
Spellcasting fails.
+ +
+ Quicken +
+
Party members get extra turns per round.
+ +
+ Reveal +
+
Invisible things are visible.
+ +
+ Time Stop +
+
Everything in the world suspends while Party members get to move.
+ +
+ Xray Vision +
+
Party members can see through walls.
+ +
+ + +

+Console Window +

+

+ Finally on the right hand side you'll find the window where all the game + messages get logged. +

+ + +

+ PLAYER COMMANDS +

+

+Here's your chance to let the sweat dry on your mouse - all commands are via +the keyboard. As it should be, forever and ever amen. +

+

+Addendum: For the sake of convenience to mousephiles, targeting prompts will +accept input from the mouse. But the shortcut keys are faster. +

+ + +

+General syntax: +

+
+
dir
+
one of the four arrow keys
+
member
+
a party member, selected from a list by scrolling with the arrow + keys and pressing enter or space
+
item
+
an inventory item, selected from a list
+
spell
+
a spell, selected from a list
+
space
+
spacebar
+
target
+
a combat target, selected by moving the crosshairs and pressing + enter or space (or using the mouse and left-clicking)
+
*
+
varies depending on context
+
+ + +

+General commands: +

+
+
dir
+
Move in that direction
+
A)ttack-dir
+
Initiate combat
+
B)oard
+
Board/exit a vehicle like a ship or horse
+
C)ast-member-spell-*
+
Cast a spell (the last argument depends on the spell)
+
E)nter
+
Enter a portal, including up or down ladders
+
F)ire-dir
+
Fire vehicle's weapon (e.g., ship cannon)
+
G)et-dir
+
Get an object from the ground
+
H)andle-member-
+
Activate a switch or lever
+
L)oiter-0-9/sunrise
+
Loiter a few hours
+
N)ew-order-member-member
+
Swap order of two party members
+
O)pen-dir
+
Open a container or door
+
Q)uit
+
Quit & optionally save the game
+
R)eady-member-item
+
Ready an armament like a weapon, shield, etc.
+
S)earch-dir
+
Look carefully
+
T)alk-target
+
Talk to an NPC
+
U)se-member-item
+
Use an item like a torch or potion
+
X)amine-target
+
Examine map tiles within view
+
Z)tats
+
Show party stats like inventory, armaments, etc
+
@)AT
+
Information about where the party is AT, etc
+
space
+
Pass one turn
+
CTRL-S)ave
+
Save a game
+
CTRL-R)eload
+
Reload a game
+
+ + +

+Wilderness-only commands: +

+
+
K)amp-0-9/sunrise-y/n-player
+
Camp in the wilderness (to heal and recover mana) or aboard ship + (to repair hull damage as well)
+
+ + +

+Town/Dungeon/Combat-only commands: +

+
+
A)ttack-target
+
Attack the specified target
+
F)ollow
+
Select follow mode, where the party members + automatically follow the party leader.
+
[1-9]
+
Select a party member for solo mode.
+
[0]
+
Select turn-based party mode, where each party + member takes directions one at a time.
+
K)amp-0-9/sunrise
+
Sleep on a bed.
+
+ + +

+Special commands: +

+
+
ESC
+
Aborts most commands
+
+ + +

+Shortcuts: +

+
+
+/=
+
When targeting an attack, moves cursor to next + hostile npc.
+
-
+
When targeting an attack, moves cursor to previous + hostile npc.
+
ESC
+
When wilderness combat is over, exits to + wilderness map.
+
+ + +

+Editing commands: +

+
+
CTRL-T)erraform
+
Alter terrain. This deserves its own section.1
+
CTRL-Z)oom
+
Zoom in or out (like peering at a gem but free)
+ + +

+ MOVEMENT MODES +

+ +

+Party Mode (wilderness) +

+

+ The party appears as a single icon in the center of the screen. +

+ + +

+Follow Mode (town/combat/dungeons) +

+

+ You control the party leader and the other members follow the + leader. Attacking a target will automatically switch to Round-Robin + Mode. The party leader is always the top person in the list who is alive + and still on the current map. Enter follow mode from Solo or Round Robin + Mode by pressing 'f'. +

+ + +

+Solo Mode (town/combat/dungeons) +

+

+ You control one party member while the others stand around looking + bored. Enter Solo Mode by pressing the number key associated with the + party member's order in the list. 1 is the first member in the list. +

+

+ NOTE: Solo mode can be very useful if one of your party members has greater + passability than the others. For example, if a gazer joins your party + he can float over water. Now imagine the possibilities if you get a + ghost to join your party. +

+ + +

+Round Robin Mode (town/combat/dungeons) +

+

+ You control each member in turn. This is the default mode when you enter + combat. To enter Round Robin Mode from solo mode, press 0. To enter from + Follow Mode press 'f'. Yes, confusing to have two methods. I'll fix it + someday. Let me know if you have an opinion. +

+ + +

+ PLACES +

+ + +

+Wilderness: +

+

+ In the outdoor or wilderness map the party moves as a single unit. You can + enter into combat with enemy NPC parties by moving into them or waiting for + them to attack you. Likewise you can enter towns, dungeons or moongates by + simply walking into them. +

+ + +

+Wilderness Combat: +

+

+ This is a special temporary combat map that pops up when you engage an + enemy NPC party in the wilderness. In this mode you control individual + party members. You return to the wilderness map by having all of your + living party members walk off the edge of the map. (Hint: if combat is over + you can press ESC to quickly leave the map). +

+ + +

+Towns/Dungeons: +

+

+ In towns and dungeons you move just like in combat mode. You can control + the individual party members in turn, have one of them scout around in solo + mode, or control the leader and have the other party members follow. +

+ + +

+COMBAT +

+

+What can I say? It's pretty much like u5. Try the flaming oil at night or in an +underground place. Oh, and watch out for gazers. They can charm you. Kill them +or charm them right away. +

+ + +

+ADVANCEMENT +

+

+As usual, characters advance a level when they gain sufficient experience +points. There is no maximum level limit. When a character advances his maximum +HP and MP increase, depending on his class, species and personal bonuses. At +the moment of advancment he is fully healed and mana is restored to their new +maximum levels. +

+ + +

+XP Required for Advancement +

+ + + + + + + + + + + + + + + + + + +
+ Level + + XP +
+ 1 + + 0 +
+ 2 + + 32 +
+ 3 + + 64 +
+ 4 + + 128 +
+ 5 + + 256 +
+ 6 + + 512 +
+ n + + 2^(n+5) +
+ + +

+ Attributes +

+

+Characters have three basic attributes: Strength, Dexterity and +Intelligence. These are fixed when the character is created and don't change +during the game. +

+ + +

+Strength +

+

+ Strength limits the total weight of readied weapons and armour. Strong + characters do more damage and are better at hitting with heavy or + bludgeoning weapons. It is also used when breaking free of spider webs + (most trolls don't stay ensnared too long...). +

+ +

+Dexterity +

+

+ Dexterity is used when attacking with missile and balanced weaponry, and + helps when avoiding your opponents' blows. It is also needed when + picking locks and disarming trapped chests. +

+ +

+Intelligence +

+

+ Intelligence makes spells more potent and more likely to succeed. +

+ + +

+MAGIC +

+

+The example game contains a full complement of spells. The magic system is +similar to Ultima 5 and Ultima 6: you select a spell by entering magic +syllables. A spell name is a combination of one to four syllables. +

+

+The syllables, spell names and reagent mixtures provided in the example game +are a direct ripoff of Ultima 5. If you don't have a u5 reference manual lying +around then the tables below will help: +

+ + +

+Table 1: Reagents +

+ + + + + + + + + + + + + + + + + + + + +
+ Name + + Abbrev used in spell table +
+ Black Pearl + + BP +
+ Blood Moss + + BM +
+ Garlic + + GA +
+ Ginseng + + GI +
+ Mandrake Root + + MR +
+ Nightshade + + NI +
+ Spider Silk + + SS +
+ Sulphurous Ash + + SA +
+ + +

+ Table 2: Spells +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Syllables + + Effects + + Reagents + + Party/Combat +
+ 1 +
+ An Nox + + Cure Poison + + GI, GA + + PC +
+ An Zu + + Awaken + + GI, GA + + PC +
+ Grav Por + + Magic Missile + + SA, BP + + C +
+ In Lor + + Light + + SA + + PC +
+ Mani + + Heal + + GI, SS + + PC +
+ Wis Sanct + + Detect Trap + + SA + + PC +
+ An Sanct Ylem + + Disarm Trap + + BM + + PC +
+ 2 +
+ An Sanct + + Unlock + + SA, BM + + PC +
+ An Xen Corp + + Repel Undead + + GA, SA + + C +
+ In Wis + + Locate + + NI + + P +
+ Rel Hur + + Change Wind + + SA, BM + + P +
+ In Nox Por + + Poison Missile + + NI, BM, BP + + C +
+ In Bet Xen + + Summon Vermin + + SS, BM, SA + + C +
+ 3 +
+ In Flam Grav + + Fire Field + + SA, BP, SS + + C +
+ In Zu Grav + + Sleep Field + + GI, BP, SS + + C +
+ In Nox Grav + + Poison Field + + NI, BP, SS + + C +
+ Vas Flam + + Fire Ball + + BP, SA + + C +
+ Vas Lor + + Great Light + + SA, MA + + PC +
+ 4 +
+ An Grav + + Dispel Field + + BP, SA + + PC +
+ In Sanct Grav + + Energy Field + + MA, BP, SS + + C +
+ In Sanct + + Protection + + SA, GI, GA + + PC +
+ Wis Quas + + Reveal Hidden + + NI, SA + + PC +
+ Bet Por + + Blink (Caster) + + BP, BM + + C +
+ 5 +
+ In Ex Por + + Unlock Magic + + SA, BM + + PC +
+ An Ex Por + + Magic Lock + + SA, BM, GA + + PC +
+ Kal Xen + + Summon Beast + + SS, MA + + C +
+ In Zu + + Sleep + + GI, NS, SS + + C +
+ Vas Mani + + Great Heal + + GI, SS, MA + + PC +
+ Rel Tym + + Quickness + + SA, BM, MA + + PC +
+ 6 +
+ An Xen Ex + + Charm + + BP, NI, SS + + C +
+ In An + + Negate Magic + + GA, MA, SA + + C +
+ In Vas Por Ylem + + Earthquake + + BM, MA, SA + + C +
+ Quas An Wis + + Confuse + + MA, NI + + C +
+ Wis An Ylen + + Xray Vision + + MA, SA + + PC +
+ In Rel Por + + Telekinesis + + BP, BM, SS + + C +
+ Vas Por + + Blink (Party) + + MA, BP, BM + + P +
+ 7 +
+ In Nox Hur + + Poison Wind + + NI, SA, BM + + C +
+ In Quas Corp + + Fear + + NI, MA, GA + + C +
+ In Quas Wis + + Peer + + NI, MA + + PC +
+ In Quas Xen + + Clone + + NI, MA, SA, SS, BM, GI + + C +
+ Sanct Lor + + Invisibility + + NI, MA, BM + + C +
+ Xen Corp + + Kill + + NI, BP + + C +
+ 8 +
+ An Tym + + Stop Time + + MA, GA, BM + + WC +
+ In Flam Hur + + Flame Wind + + MA, SA, BM + + C +
+ In Vas Grav Corp + + Energy Wind + + MA, SA, NI + + C +
+ In Mani Corp + + Resurrect + + GA, GI, SS, SA, BM, MA + + PC +
+ Kal Xen Corp + + Summon Undead + + SS, MA, NI + + C +
+ Vas Rel Por + + Gate Travel + + SA, MA, BP + + P +
+

+[1] In Towns and Dungeons teleport spells that can move the party from one + place to another will fail unless combat is over and the party is in Follow + Mode. +

+ + +

+EFFECTS +

+

+From time to time your characters might run into a little trouble with magical +foes, natural hazards, or their own weakness for alcohol. Don't panic. Most +effects are non-fatal, but a few are. +

+
+
+ +Asleep +
+
+ Sleeping party members will eventually wake up of their own accord. If you + don't feel like waiting use the An Zu spell. +
+
+ +Charmed +
+
+ Enemy wizards might charm party members, causing them to fight on their + behalf. Charm wears off after 10 minutes. +
+
+ +Diseased +
+
+ Some monsters may infect party members with disease. Disease is not fatal, + but it will not wear off until your party member is nearly out of hit + points. +
+
+ +Drunk +
+
+ Anytime your character buys alcoholic drinks or picks them up from the + ground he gets drunk. Drunkenness lasts an hour or so and causes him to + randomly bump into things. +
+
+ +Ensnared +
+
+ When stuck in a spider web, a character will break free after struggling + for a while. The time required to free himself depends on the character's + strength. +
+
+ +Paralyzed +
+
+ Spiders inject paralyzing venom to make their foes helpless before feeding + on them. Paralysis will wear off after a short random interval. +
+
+ +Poisoned +
+
+ Bogs or spells may poison party members, causing them to lose hit points + every turn until the poison is cured with a spell or potion. Poison is + fatal! It won't wear off like disease. +
+
+ + +

+CONVERSATION +

+

+Start a conversation with an NPC with the T)alk command. During conversation +you type simple inquiries and the NPC responds, sometimes asking you a question +in return. Conversations with shopkeepers will allow you to buy and sell +items. Most NPCs respond to the 'NAME' and 'JOB' queries, as well as queries +about their town and fellow townsmen. Their responses usually give you clues to +further fruitful queries. Also, with the special 'JOIN' query you can ask an +NPC to join your party (some will join you, and some will join you only if you +do or say something that impresses them). +

+ + +

+MISC +

+

+Food is consumed three times per day, one unit for each living party +member. When the food runs out, party members take a point of damage at each +meal time. +

+ + +

+APPENDIX A: MAP HACKING +

+

+Like many games, "nazghul" is separated into an engine2 and some data +files. In this case the data files are written in the Scheme programmming +language. If you examine the default start file 'session.scm' you will see that +it is a scheme file which loads the game types from other files and then +defines the starting game variables. +

+

+I encourage people to experiment with modifying the example files or even using +them as a basis to create their own games. The example script code is all +committed to the public domain. The image and sound files come from various +sources - see the COPYING file in the top nazghul directory for details on +where they came from. +

+

+If you want to make a proprietary game you may use the example script files, +but you will probably need to make your own image and sound resource files as +the ones in the examples directory come from other open-source or freeware +projects and their copyright holders might object to proprietary use. +

+ + +

+APPENDIX B: Spoilers +

+

+These apply specifically to Haxima, and not necessarily to any other game made +with the Nazghul engine. +

+ + +

+Projectile Weapon Stats +

+ + + + + + + + + + + + + + + + +
+ Name + + To-Hit + + Damage + + To-Def + + Hnds + + Rng + + Ammo + + Weight +
+ Sling + + 1d2-2 + + 1d4 + + -1 + + 1 + + 4 + + slingstone 1 + + 0 +
+ Sling+4 + + 3 + + 1d4+4 + + 0 + + 1 + + 6 + + slingstone 1 + + 0 +
+ Bow + + 1d3-2 + + 2d4 + + -2 + + 2 + + 6 + + arrow + + 2 +
+ Crossbow + + 1d4-2 + + 4d4 + + -1 + + 2 + + 4 + + bolt + + 3 +
+ Doom Staff 2 + + 1d4 + + 1 + + +2 + + 2 + + 6 + + - + + 2 +
+ Stun Wand 3 + + -2 + + 1d4 + + -1 + + 1 + + 6 + + - + + 2 +
+

+ +[1] Considered 'ubiquitous' (ie you always have enough ammo) +

+

+ +[2] Also inflicts fire damage +

+

+ +[3] Temporarily paralyzes target +

+ + +

+Thrown Weapon Stats +

+ + + + + + + + + + +
+ Name + + To-Hit + + Damage + + To-Def + + Hnds + + Rng + + Weight +
+ Flaming oil 1 + + -1 + + 1d6 + + -2 + + 1 + + 4 + + 1 +
+ Spear + + 0 + + 1d8 + + +1 + + 1 + + 4 + + 2 +
+ Boulder + + -2 + + 3d4+1 + + -2 + + 2 + + 5 + + 10 +
+

+ +[1] Leaves a temporary burning patch of ground +

+ + +

+Melee Weapon Stats +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + To-Hit + + Damage + + To-Def + + Hnds + + Rng + + Weight +
+ Dagger + + 1d4 + + 1d4 + + 1d2 + + 1 + + 1 + + 0 +
+ Dagger+4 + + 1d4+4 + + 1d4+4 + + 1d2+4 + + 1 + + 1 + + 0 +
+ Mace + + 1d4 + + 1d6+2 + + +0 + + 1 + + 1 + + 3 +
+ Axe + + 1d2 + + 2d3+2 + + +0 + + 1 + + 1 + + 3 +
+ Sword + + 1d2 + + 1d8+1 + + 1d2 + + 1 + + 1 + + 2 +
+ Sword+2 + + 1d2+2 + + 1d8+3 + + 1d2+2 + + 1 + + 1 + + 2 +
+ Sword+4 + + 1d2+4 + + 1d8+5 + + 1d2+4 + + 1 + + 1 + + 2 +
+ 2H Axe + + 0 + + 4d3+2 + + -2 + + 2 + + 1 + + 4 +
+ 2H Sword + + 0 + + 2d8+2 + + 1 + + 2 + + 1 + + 4 +
+ Morning star + + 1d2+2 + + 1d6+1 + + -1 + + 1 + + 2 + + 3 +
+ Morning star+2 + + 1d2+4 + + 1d6+3 + + 2 + + 1 + + 2 + + 3 +
+ Halberd + + 1d3+1 + + 2d8-2 + + 1d2 + + 2 + + 2 + + 4 +
+ Staff + + 1d3 + + 1d4 + + 1d3 + + 2 + + 2 + + 2 +
+ Eldritch blade + + 2 + + 2d8+5 + + +0 + + 2 + + 1 + + 2 +
+ Mystic sword + + +3 + + 1d10+5 + + +2 + + 1 + + 1 + + 1 +
+ Flaming sword + + 1d2 + + 1d10+3 + + 1d2 + + 1 + + 1 + + 2 +
+ + +

+Armor Stats +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + To-Hit + + Damage + + Armor + + To-Def + + Weight +
+ Leather helm + + -1 + + - + + 1d2 + + - + + 0 +
+ Leather helm+2 + + 0 + + - + + 1d2+2 + + - + + 0 +
+ Leather helm+4 + + 0 + + - + + 1d2+4 + + - + + 0 +
+ chain coif + + -1 + + - + + 1d3 + + - + + 1 +
+ Chain coif+4 + + 0 + + - + + 1d3+4 + + - + + 1 +
+ iron helm + + -1 + + - + + 1d4 + + - + + 2 +
+ Iron helm+4 + + 0 + + - + + 1d4+4 + + - + + 2 +
+ leather armor + + -1 + + - + + 1d4 + + - + + 2 +
+ Leather armor+2 + + 0 + + - + + 1d4+2 + + - + + 2 +
+ Leather armor+4 + + 0 + + - + + 1d4+4 + + - + + 2 +
+ chain armor + + -2 + + - + + 2d4 + + - + + 4 +
+ Chain armor+4 + + 0 + + - + + 2d4+4 + + - + + 4 +
+ plate armor + + -4 + + - + + 4d4 + + - + + 8 +
+ Plate armor+4 + + 0 + + - + + 4d4+4 + + - + + 8 +
+ Small shield + + -1 + + - + + 0 + + 2 + + 2 +
+ Small shield+4 + + 0 + + - + + 0 + + 6 + + 2 +
+ Spiked shield + + 0 + + 1d5 + + 0 + + 1 + + 3 +
+ Spiked helm + + 0 + + 1d4 + + 3 + + 0 + + 2 +
+ + +

+FOOTNOTES +

+

+ +[1] Alas, there isn't one. Yet. +

+ +

+[2] I like to refer to it as a "kernel". This makes me feel like it is really + cool, and like I'm not a loser since Linus Torvalds and I are about the + same age and he works on a kernel, too. +

+

+--gmcnutt (gmcnutt@cableone.net) +

\ No newline at end of file diff --git a/doc/world_building/CVS/Entries b/doc/world_building/CVS/Entries new file mode 100644 index 0000000..9b21877 --- /dev/null +++ b/doc/world_building/CVS/Entries @@ -0,0 +1,10 @@ +/advancement.rogue.txt/1.1/Thu Sep 2 05:52:22 2004// +/advancement.warrior.txt/1.1/Thu Sep 2 05:52:22 2004// +/advancement.wizard.txt/1.1/Thu Sep 2 05:52:22 2004// +/advancement.wright.txt/1.1/Thu Sep 2 05:52:22 2004// +/being_tile_media.txt/1.3/Thu Sep 2 05:52:22 2004// +/music_loop_media.txt/1.2/Thu Sep 2 05:52:22 2004// +/sound_sample_media.txt/1.3/Tue Jan 23 08:32:14 2007// +/town_scale_tile_media.txt/1.2/Thu Sep 2 05:52:22 2004// +/wilderness_scale_tile_media.txt/1.2/Thu Sep 2 05:52:22 2004// +D diff --git a/doc/world_building/CVS/Repository b/doc/world_building/CVS/Repository new file mode 100644 index 0000000..90c5636 --- /dev/null +++ b/doc/world_building/CVS/Repository @@ -0,0 +1 @@ +nazghul/doc/world_building diff --git a/doc/world_building/CVS/Root b/doc/world_building/CVS/Root new file mode 100644 index 0000000..4d8737a --- /dev/null +++ b/doc/world_building/CVS/Root @@ -0,0 +1 @@ +:ext:gmcnutt@nazghul.cvs.sourceforge.net:/cvsroot/nazghul diff --git a/doc/world_building/advancement.rogue.txt b/doc/world_building/advancement.rogue.txt new file mode 100644 index 0000000..1b73949 --- /dev/null +++ b/doc/world_building/advancement.rogue.txt @@ -0,0 +1,29 @@ +--------------------------------------------------------------------------- +Advancement Path: Rogue +--------------------------------------------------------------------------- +Rogue Skills by Category +------------------------ + +Physical (swim, climb, jump, ...) + +Sensory (see, hear, evaluate foe, search, detect traps, ...) + +Stealth (overall, urban, wilderness, ...) + +Roguery (pick pockets, pick lock, disable mechanism, set trap, ...) + +Social (lie, detect lie, intimidate, bluff, seduce, haggle, ...) + +Rogue Combat ( + rogue weapons (knife, sap, lasso, net, small crossbows, + shuriken, darts) + critical strike, stunning blow, surprise strike, + feint/riposte, dodge/tumble, ...) + + + + + + + +--------------------------------------------------------------------------- diff --git a/doc/world_building/advancement.warrior.txt b/doc/world_building/advancement.warrior.txt new file mode 100644 index 0000000..9851971 --- /dev/null +++ b/doc/world_building/advancement.warrior.txt @@ -0,0 +1,8 @@ +--------------------------------------------------------------------------- +Advancement Path: Warrior +--------------------------------------------------------------------------- + + + + +--------------------------------------------------------------------------- diff --git a/doc/world_building/advancement.wizard.txt b/doc/world_building/advancement.wizard.txt new file mode 100644 index 0000000..b6636c8 --- /dev/null +++ b/doc/world_building/advancement.wizard.txt @@ -0,0 +1,8 @@ +--------------------------------------------------------------------------- +Advancement Path: Wizard +--------------------------------------------------------------------------- + + + + +--------------------------------------------------------------------------- diff --git a/doc/world_building/advancement.wright.txt b/doc/world_building/advancement.wright.txt new file mode 100644 index 0000000..fd095a6 --- /dev/null +++ b/doc/world_building/advancement.wright.txt @@ -0,0 +1,49 @@ +--------------------------------------------------------------------------- +Character Advancement Path: Wright +--------------------------------------------------------------------------- + +Items/Objects created/gathered by Wright skills: + +Weapons +Armor and worn items +Tools +Materials +Alchemical goods +Furniture +Vehicles +Structures (buildings, non-portable objects and tools) +Public Works (terrain modifications) + + +Materials +--------- +Reagents + herbal (plants and parts thereof) + mineral (powders, stones, ...) + organic (animals and parts thereof) + essences (moonlight, abstract essences, + ordinary materials infused with essences) + +Food + plant + animal + other (honey, ...) + +Ores + +Fibers + +Wood + +Hides + +... + + +--------------------------------------------------------------------------- + +Pick the top 3 Wright skills for early implementation... + + + +--------------------------------------------------------------------------- diff --git a/doc/world_building/being_tile_media.txt b/doc/world_building/being_tile_media.txt new file mode 100644 index 0000000..b52dd2d --- /dev/null +++ b/doc/world_building/being_tile_media.txt @@ -0,0 +1,11 @@ +Being Sprites Wanted +-------------------- +Troll (horns, unarmed or club/hammer) -- exists in U4 and U5 tilesets +Spider - Wolf Spider -- exists in U4/U5 tileset +Spider - Black Widow +Deer + +Female Townsman -- create by modifying townsman sprite? +Cat (domestic) -- create by modifying dog sprite? +Sheep +Goat diff --git a/doc/world_building/music_loop_media.txt b/doc/world_building/music_loop_media.txt new file mode 100644 index 0000000..60a11e9 --- /dev/null +++ b/doc/world_building/music_loop_media.txt @@ -0,0 +1,16 @@ +--------------------------------------------------------------------------- +Music and other Looped Sound Media +--------------------------------------------------------------------------- + +Bardic tune "He is brace Sir Robin..." + +Bach - "Tocatta En Fugue" +Edvard Grieg (?) - "Hall of the Mountain King" + + + + + + + +--------------------------------------------------------------------------- diff --git a/doc/world_building/sound_sample_media.txt b/doc/world_building/sound_sample_media.txt new file mode 100644 index 0000000..542c168 --- /dev/null +++ b/doc/world_building/sound_sample_media.txt @@ -0,0 +1,233 @@ +--------------------------------------------------------------------------- +Non-Looped Sound Media +--------------------------------------------------------------------------- + + +Music (loops, once-off) +Atmospheric / environment sounds +Utterances + Words + Runes + spell names + species names + target specifier names (ground, object, foe type, unseen foe, ...) + Non-verbal +Other Sounds + UI + Command names + Action + Object + Movement + Combat + + + +Movement Sounds +--------------- +1 per movement mode (including vehicles/riding) +2 per terrain + +snd = movement_sound(terrain, mode) ??? + +Moongate sounds + open + close + enter + arrival / exit + + +--------------------------------------------------------------------------- +Sounds for +---------- +Change to + Walking + Stealth mode + Riding + Swimming + Sailing + Flying + +Change to + Combat Mode + Peace Mode + +Change to + Solo Mode + Follow Mode + Round-Robin mode + +Rendezvous + begin "Let's go", "follow me" + end (success) + failed "I'm stuck", "Wait for me!" + +Combat + Initiate combat + Victory + Character Fled + Party Fled + +UI Sounds + Cursor movement + + list element up/down + list scrolling + list PgUp/PgDn + List Home/End + + type a character (when entering text, such as when talking) + backspace + + CANCEL action (Escape key) + select (character, item, coordinates, targeted being + + +Command names + "Attack" + "Board" / "Disembark" + -- per vehicle, a board and disembark sound + "Mount" / "Dismount" + "Board " / "Disembark " + "Cast" + ... + + +--------------------------------------------------------------------------- +Combat UI Sounds +---------------- +hit armor vs flesh? + +Blunt, Edged, Piercing +Melee, Thrown, Bow/Xbow, Boomerang, Sling + +Attacker + fumbles (various) + miss + miss (parried with weapon, blocked by shield, dodged blow) + hit (soaked, damaging, armor-defeating) + critical + +Defender + parry/block/dodge + suffer knockdown / knockback + suffer wound + suffer KO + suffer death + +Spellcasting + ... + + +--------------------------------------------------------------------------- +Runes and Such +-------------- + +Ultima IV / V Runes +------------------- +An - Negate +Bet - Small +Corp - Death / Undead +Des - Down +Ex - Freedom +Flam - Flame / Fire +Grav - Energy +Hur - Wind +In - Create +Jux - Trap +Kal - Invoke / Summon +Lor - Light +Mani - Life / Health +Nox - Poison +Ort - Magic +Por - Movement +Quis - Illusion +Rel - Control / Change +Sanct - Protection +Tym - Time +Uus - Up +Vas - Great +Wis - Vision / Percieve +Xen - Creature / Being +Ylem - Earth +Zu - Sleep + +Jzeth - Ether +Orax - Water / Waves + + + +Ultima Virtues / Mantras / Dungeons / Power Words +-------------------------------------------------------------- +Honesty / Ahm / Deceit / Fallax +Compassion / Mu / Depise / Vilis +Valor / Ra / Destard / Inopia +Sacrifice / Cah / Covetous / Avidus +Justice / Beh / Wrong / Malum +Honor / Summ / Shame / Infama +Spirituality / Om / Hythloth / Ignavus +Humility / Lum / Stygia / Mul + +Truth / Ver / Falsehood / Faulinei +Love / Amo / Hatred / Astaroth +Courage / Cor / Cowardice / Nosfentor + +Veramocor +Infinity + + +Ultima VI Gargoyle Virtues / Principles +--------------------------------------- +Control +Passion +Diligence + +C - Direction +P - Feeling +D - Persistence +CP - Balance +PD - Achievement +CD - Precision +CPD - Order / Chaos + - Singularity + + +Dungeon Master Runes +-------------------- +Power +----- +Lo - 1 +Um - 2 +On - 3 +Ee - 4 +Pal - 5 +Mon - 6 + +Elemental +--------- +Ya - Earth (stamina) +Vi - Water (health) +Oh - Air +Ful - Fire +Des - Negativity +Zo - Energy + +Form +---- +Ven - Poison +Ew - Elemental Creature +Kath - Explosive / Shock +Ir - Motion +Bro - Support / Friendship +Gor - Destruction + +Class/Alignment +--------------- +Ku - Fighter (strength) +Ros - Ninja (dexterity) +Dain - Wizard (wisdom) +Neta - Priest (vitality) +Ra - Order / Sun +Sar - Chaos / Darkness + + +--------------------------------------------------------------------------- diff --git a/doc/world_building/town_scale_tile_media.txt b/doc/world_building/town_scale_tile_media.txt new file mode 100644 index 0000000..9a37c35 --- /dev/null +++ b/doc/world_building/town_scale_tile_media.txt @@ -0,0 +1,237 @@ +--------------------------------------------------------------------------- +Small-Scale Terrain and Tile Media Wanted +--------------------------------------------------------------------------- +Terrain +Terrain Features (static) + Furniture +Terrain Features (mechanism-like) + Doors, gates, portcullis, drawbridge + well, forge, anvil, bellows +Items + weapons, armor/wearable items, + consumable/commodity items (food, drink, potions, oils, herbs, ...) + readable items, tools, reagents, musical instruments + + +--------------------------------------------------------------------------- +Small-Scale Environments +------------------------ +Outdoors +Village / Urban +Indoors +Caves +Subterranean Chambers (built areas, worked stone) +Exotic locales + + +Small-Scale Terrain +------------------- +Water + (shallow, deep, oceanic) + (stream, river, lake, ocean) + (clear, murky) + (still, rippling, flowing N,S,E,W, fast flowing N,S,E,W) + shoals, coral, sandbar, rocky shallows, mudbar + Other non-solid terrains: + lava + acid lake + boiling mud + +Land + Grass + TF: trails/roads, bridges, droos, portcullis, gates + Bog/march/swamp + badlands + tilled land, crops + desert + wasteland + + flooring + bare earth + planks / deck / wooden floors + cobblestones + flagstones + stone/tile floors (various block/tile shapes, colors) + various colors / patterns of rugs + + walls + (crude stone, brick, giant stone blocks) + (frame and plaster, wooden (logs, boards), tent walls) + (various colors of stone / plaster / paint) + + Runic signs + Latin alphabet (A-Z) + -- Add (0-9), (a-z), (I,II,III,IV, V, X, L, C, M) ??? + Runic alphabet + + vegetation + brush, small trees, hedges + TF: single tree, fruiting tree, dead tree, stump + + +Small-Scale Terrain Features +---------------------------- +signs/walls (Terrain or Terrain Feature?) +cobblestones +brick paths +carpets +plank flooring +roads +bridges +fences +gates +doors +portcullis +drawbridge +signs +gravestones +standing stones +boulders + +campfire +firepit +stove/oven +fireplace +forge +anvil +bellows +winch +hitching posts +gears +counterweights +levers +floor pressure plate + +Portal-type Mechanisms + trapdoor + ladders + stairs + moongates (blue, red, black, ...) + +tables +chairs +thrones +privy / outhouse + +force fields (force waves like U3, colors like U4, ...) +emplaced traps + blades + boulder + net + trap door + +organ +waterclock +horse trough +cistern +pipes + +levers +folding counter sections (like in U6) +fence stiles + + +Semi-Portable Features +---------------------- +round boulders +giant ice cubes +barrels +chests +crates +potted plants +chairs +(smaller) tables +beds +dresser / cabinet +(large) harp +harpsichord +mirror +clock +cannons + + +Vehicles and Such +----------------- +skiff +raft +magic carpet +saddle + + +Porable Items +------------- +wall torches (lit, unlit, torch burnt out) +keys + + +chimney +fire pit +cauldron (empty / full, with / without bubbles) +skeletons +bones +manacles +pillories +torture rack +iron maiden + +many types of doors + + +Missing Item Sprites +-------------------- +Weapons + boomerang + +Armor / Worn Items + belts + normal clothing (male, female) + +Commodities / Consumable Items + meal / place setting (to put on tables) + more food sprites + more drink sprites + more single gems + +Tools + crystal ball + telescope (large) + spyglass / telescope (small) + mirror + tongs + scissors + sextant + theodolite + keys + +Readable Items + normal scrolls, books, tablets, maps + +Reagents + various powders, liquids, gases + body parts (heads, hand, feet, ears, hearts, skulls, bones, + scales, tails, features, ...) + + +Various Laboratory Furniture (think: wizard's lab or mad scientist) +---------------------------- +giant crystals +huge runic stones, tablets +stone slabs (for corpse / patient / victim) +statues + + + +tapestries, paintings + +various colors of + walls + roads / cobblestone / floors + rugs + +non-stone walls + wooden + plaster + tent wall + + +--------------------------------------------------------------------------- diff --git a/doc/world_building/wilderness_scale_tile_media.txt b/doc/world_building/wilderness_scale_tile_media.txt new file mode 100644 index 0000000..04463ad --- /dev/null +++ b/doc/world_building/wilderness_scale_tile_media.txt @@ -0,0 +1,138 @@ +--------------------------------------------------------------------------- +Large-Scale Terrain and Tile Media Wanted +--------------------------------------------------------------------------- + +Water Terrain Tiles +------------------- +Oceanic water +Deep water +Shallow water + + +Differentiate water tiles as (river, lake, ocean) + - Direction of flow: N,S,E,W, rippling-in-place + - different shades/colors of water (clear, murky) + +Tidal Terrain is proposed + - Shard Tilt Tides + - Lunar Tides + +Streams (passable by walking, zoom-in contains a stream) + +ford +rapids + +rocks / shoals +sandbar +mud bank +reefs +algae bloom +kelp +jellyfish +fish spawning +wave crests +fog banks + +Light-emitting water terrain/features + coral + jellyfish + ... + + +Other non-solid Terrains +------------------------ +Acid Lake +Boiling Mud +Lava +Astral Void +Swirling Fog + + +Land Terrain Tiles +------------------ +Grasslands + - High Grass +Fields +Orchards +Brush +Forest +Hills + - Forested Hills +Mountains + - Forested Mountains +Mountain Peaks + - Snow-covered peaks +Swamp / Marsh / Fens / Bog + - Flooded Swamp + - Wooded Swamp (blocks LOS) +Desert (depletes water rations) +Tundra + - Many other terrain types covered in snow +Wasteland / Blasted Ground +Rocky Ground + +Badlands + - Mesas -- Not for Haxima I, too much art required + - Rifts/Canyons + - Cliffs -- Not for Haxima I, too much art required + + +Light-emitting Terrain + magical woods + towns + some coral + jellyfish + lava + swamp glow + + +Large-Scale Terrain Features +---------------------------- +Roads - Made with transparency, goes over most any terrain +Trails - Made with transparency, goes over most any terrain +Bridges +Fords (terrain or terrain feature?) +Piers / Ports / Landings (terrain or terrain feature?) +Signs +Markers / Monuments (many of these sprites are also used for sub-places) + - Standing Stone(s) + - Battlefield marker + - Ancient graveyard / battlefield + - Ancient ruins +Fog Banks +Walls (Hadrian's Wall, Great Wall of China, LCB) + + +Portal Types +------------ +Castle (major, minor, ...) +Tower +Town (walled) +Village +Ruins +Hut +Dungeon Entrance +Cave Entrance +Mine Entrance +Transparent Portal (no visible sprite, no description shown) +Moongate (blue, red, black, other colors) + + +--------------------------------------------------------------------------- +What attributes Terrain / Terrain Features Have +----------------------------------------------- +- Display a sprite +- Affect passability / movement by movement mode +- Affect LOS +- Provide illumination +- Invoke an effect upon successful/failed movement +- Act as a portal (auto-enter or no, directional or not) + - Portals can invoke a method, often used for confirmation of + entering the portal + + + + + + +--------------------------------------------------------------------------- diff --git a/haxima.desktop b/haxima.desktop new file mode 100644 index 0000000..abf77e6 --- /dev/null +++ b/haxima.desktop @@ -0,0 +1,11 @@ +[Desktop Entry] +Encoding=UTF-8 +Name=Haxima +GenericName=Role Playing Game +Comment=An old school role playing game +Exec=haxima +Icon=haxima.png +Terminal=false +Type=Application +Categories=Application;Game; +Version=1.002 diff --git a/icons/CVS/Entries b/icons/CVS/Entries new file mode 100644 index 0000000..dc8fb22 --- /dev/null +++ b/icons/CVS/Entries @@ -0,0 +1,4 @@ +/haxima.ico/1.2/Fri Jan 26 22:42:48 2007// +/haxima.png/1.2/Fri Jan 26 22:42:48 2007// +/haxima.xcf/1.2/Fri Jan 26 22:42:48 2007// +D diff --git a/icons/CVS/Repository b/icons/CVS/Repository new file mode 100644 index 0000000..2ddffbb --- /dev/null +++ b/icons/CVS/Repository @@ -0,0 +1 @@ +nazghul/icons diff --git a/icons/CVS/Root b/icons/CVS/Root new file mode 100644 index 0000000..4d8737a --- /dev/null +++ b/icons/CVS/Root @@ -0,0 +1 @@ +:ext:gmcnutt@nazghul.cvs.sourceforge.net:/cvsroot/nazghul diff --git a/icons/haxima.ico b/icons/haxima.ico new file mode 100644 index 0000000..ca1068b Binary files /dev/null and b/icons/haxima.ico differ diff --git a/icons/haxima.png b/icons/haxima.png new file mode 100644 index 0000000..428e292 Binary files /dev/null and b/icons/haxima.png differ diff --git a/icons/haxima.xcf b/icons/haxima.xcf new file mode 100644 index 0000000..3b4edec Binary files /dev/null and b/icons/haxima.xcf differ diff --git a/install-sh b/install-sh new file mode 100644 index 0000000..6781b98 --- /dev/null +++ b/install-sh @@ -0,0 +1,520 @@ +#!/bin/sh +# install - install a program, script, or datafile + +scriptversion=2009-04-28.21; # UTC + +# This originates from X11R5 (mit/util/scripts/install.sh), which was +# later released in X11R6 (xc/config/util/install.sh) with the +# following copyright and license. +# +# Copyright (C) 1994 X Consortium +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- +# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +# +# Except as contained in this notice, the name of the X Consortium shall not +# be used in advertising or otherwise to promote the sale, use or other deal- +# ings in this Software without prior written authorization from the X Consor- +# tium. +# +# +# FSF changes to this file are in the public domain. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. + +nl=' +' +IFS=" "" $nl" + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit=${DOITPROG-} +if test -z "$doit"; then + doit_exec=exec +else + doit_exec=$doit +fi + +# Put in absolute file names if you don't have them in your path; +# or use environment vars. + +chgrpprog=${CHGRPPROG-chgrp} +chmodprog=${CHMODPROG-chmod} +chownprog=${CHOWNPROG-chown} +cmpprog=${CMPPROG-cmp} +cpprog=${CPPROG-cp} +mkdirprog=${MKDIRPROG-mkdir} +mvprog=${MVPROG-mv} +rmprog=${RMPROG-rm} +stripprog=${STRIPPROG-strip} + +posix_glob='?' +initialize_posix_glob=' + test "$posix_glob" != "?" || { + if (set -f) 2>/dev/null; then + posix_glob= + else + posix_glob=: + fi + } +' + +posix_mkdir= + +# Desired mode of installed file. +mode=0755 + +chgrpcmd= +chmodcmd=$chmodprog +chowncmd= +mvcmd=$mvprog +rmcmd="$rmprog -f" +stripcmd= + +src= +dst= +dir_arg= +dst_arg= + +copy_on_change=false +no_target_directory= + +usage="\ +Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE + or: $0 [OPTION]... SRCFILES... DIRECTORY + or: $0 [OPTION]... -t DIRECTORY SRCFILES... + or: $0 [OPTION]... -d DIRECTORIES... + +In the 1st form, copy SRCFILE to DSTFILE. +In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. +In the 4th, create DIRECTORIES. + +Options: + --help display this help and exit. + --version display version info and exit. + + -c (ignored) + -C install only if different (preserve the last data modification time) + -d create directories instead of installing files. + -g GROUP $chgrpprog installed files to GROUP. + -m MODE $chmodprog installed files to MODE. + -o USER $chownprog installed files to USER. + -s $stripprog installed files. + -t DIRECTORY install into DIRECTORY. + -T report an error if DSTFILE is a directory. + +Environment variables override the default commands: + CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG + RMPROG STRIPPROG +" + +while test $# -ne 0; do + case $1 in + -c) ;; + + -C) copy_on_change=true;; + + -d) dir_arg=true;; + + -g) chgrpcmd="$chgrpprog $2" + shift;; + + --help) echo "$usage"; exit $?;; + + -m) mode=$2 + case $mode in + *' '* | *' '* | *' +'* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; + + -o) chowncmd="$chownprog $2" + shift;; + + -s) stripcmd=$stripprog;; + + -t) dst_arg=$2 + shift;; + + -T) no_target_directory=true;; + + --version) echo "$0 $scriptversion"; exit $?;; + + --) shift + break;; + + -*) echo "$0: invalid option: $1" >&2 + exit 1;; + + *) break;; + esac + shift +done + +if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then + # When -d is used, all remaining arguments are directories to create. + # When -t is used, the destination is already specified. + # Otherwise, the last argument is the destination. Remove it from $@. + for arg + do + if test -n "$dst_arg"; then + # $@ is not empty: it contains at least $arg. + set fnord "$@" "$dst_arg" + shift # fnord + fi + shift # arg + dst_arg=$arg + done +fi + +if test $# -eq 0; then + if test -z "$dir_arg"; then + echo "$0: no input file specified." >&2 + exit 1 + fi + # It's OK to call `install-sh -d' without argument. + # This can happen when creating conditional directories. + exit 0 +fi + +if test -z "$dir_arg"; then + trap '(exit $?); exit' 1 2 13 15 + + # Set umask so as not to create temps with too-generous modes. + # However, 'strip' requires both read and write access to temps. + case $mode in + # Optimize common cases. + *644) cp_umask=133;; + *755) cp_umask=22;; + + *[0-7]) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw='% 200' + fi + cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; + *) + if test -z "$stripcmd"; then + u_plus_rw= + else + u_plus_rw=,u+rw + fi + cp_umask=$mode$u_plus_rw;; + esac +fi + +for src +do + # Protect names starting with `-'. + case $src in + -*) src=./$src;; + esac + + if test -n "$dir_arg"; then + dst=$src + dstdir=$dst + test -d "$dstdir" + dstdir_status=$? + else + + # Waiting for this to be detected by the "$cpprog $src $dsttmp" command + # might cause directories to be created, which would be especially bad + # if $src (and thus $dsttmp) contains '*'. + if test ! -f "$src" && test ! -d "$src"; then + echo "$0: $src does not exist." >&2 + exit 1 + fi + + if test -z "$dst_arg"; then + echo "$0: no destination specified." >&2 + exit 1 + fi + + dst=$dst_arg + # Protect names starting with `-'. + case $dst in + -*) dst=./$dst;; + esac + + # If destination is a directory, append the input filename; won't work + # if double slashes aren't ignored. + if test -d "$dst"; then + if test -n "$no_target_directory"; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 + fi + dstdir=$dst + dst=$dstdir/`basename "$src"` + dstdir_status=0 + else + # Prefer dirname, but fall back on a substitute if dirname fails. + dstdir=` + (dirname "$dst") 2>/dev/null || + expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$dst" : 'X\(//\)[^/]' \| \ + X"$dst" : 'X\(//\)$' \| \ + X"$dst" : 'X\(/\)' \| . 2>/dev/null || + echo X"$dst" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q' + ` + + test -d "$dstdir" + dstdir_status=$? + fi + fi + + obsolete_mkdir_used=false + + if test $dstdir_status != 0; then + case $posix_mkdir in + '') + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 + + if (umask $mkdir_umask && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writeable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + ls_ld_tmpdir=`ls -ld "$tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/d" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null + fi + trap '' 0;; + esac;; + esac + + if + $posix_mkdir && ( + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + ) + then : + else + + # The umask is ridiculous, or mkdir does not conform to POSIX, + # or it failed possibly due to a race condition. Create the + # directory the slow way, step by step, checking for races as we go. + + case $dstdir in + /*) prefix='/';; + -*) prefix='./';; + *) prefix='';; + esac + + eval "$initialize_posix_glob" + + oIFS=$IFS + IFS=/ + $posix_glob set -f + set fnord $dstdir + shift + $posix_glob set +f + IFS=$oIFS + + prefixes= + + for d + do + test -z "$d" && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ + done + + if test -n "$prefixes"; then + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true + fi + fi + fi + + if test -n "$dir_arg"; then + { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && + { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || + test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 + else + + # Make a couple of temp file names in the proper directory. + dsttmp=$dstdir/_inst.$$_ + rmtmp=$dstdir/_rm.$$_ + + # Trap to clean up those temp files at exit. + trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 + + # Copy the file name to the temp name. + (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + + # and set any options; do chmod last to preserve setuid bits. + # + # If any of these fail, we abort the whole thing. If we want to + # ignore errors from any of these, just make sure not to ignore + # errors from the above "$doit $cpprog $src $dsttmp" command. + # + { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && + { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && + { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && + { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && + + # If -C, don't bother to copy if it wouldn't change the file. + if $copy_on_change && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + + eval "$initialize_posix_glob" && + $posix_glob set -f && + set X $old && old=:$2:$4:$5:$6 && + set X $new && new=:$2:$4:$5:$6 && + $posix_glob set +f && + + test "$old" = "$new" && + $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 + then + rm -f "$dsttmp" + else + # Rename the file to the real destination. + $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || + + # The rename failed, perhaps because mv can't rename something else + # to itself, or perhaps because mv is so ancient that it does not + # support -f. + { + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" + } + fi || exit 1 + + trap '' 0 + fi +done + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/m4/ChangeLog b/m4/ChangeLog new file mode 100644 index 0000000..2847b9e --- /dev/null +++ b/m4/ChangeLog @@ -0,0 +1,21 @@ +2002-10-06 gettextize + + * codeset.m4: New file, from gettext-0.11.5. + * gettext.m4: New file, from gettext-0.11.5. + * glibc21.m4: New file, from gettext-0.11.5. + * iconv.m4: New file, from gettext-0.11.5. + * intdiv0.m4: New file, from gettext-0.11.5. + * inttypes.m4: New file, from gettext-0.11.5. + * inttypes_h.m4: New file, from gettext-0.11.5. + * inttypes-pri.m4: New file, from gettext-0.11.5. + * isc-posix.m4: New file, from gettext-0.11.5. + * lcmessage.m4: New file, from gettext-0.11.5. + * lib-ld.m4: New file, from gettext-0.11.5. + * lib-link.m4: New file, from gettext-0.11.5. + * lib-prefix.m4: New file, from gettext-0.11.5. + * progtest.m4: New file, from gettext-0.11.5. + * stdint_h.m4: New file, from gettext-0.11.5. + * uintmax_t.m4: New file, from gettext-0.11.5. + * ulonglong.m4: New file, from gettext-0.11.5. + * Makefile.am: New file. + diff --git a/m4/Makefile.am b/m4/Makefile.am new file mode 100644 index 0000000..1c938cb --- /dev/null +++ b/m4/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST = sdl.m4 acinclude.m4 +MAINTAINERCLEANFILES = Makefile.in diff --git a/m4/Makefile.in b/m4/Makefile.in new file mode 100644 index 0000000..cd69d0f --- /dev/null +++ b/m4/Makefile.in @@ -0,0 +1,340 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +subdir = m4 +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/sdl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +SOURCES = +DIST_SOURCES = +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = sdl.m4 acinclude.m4 +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu m4/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu m4/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +tags: TAGS +TAGS: + +ctags: CTAGS +CTAGS: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic distclean \ + distclean-generic distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic pdf pdf-am ps ps-am uninstall uninstall-am + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/m4/acinclude.m4 b/m4/acinclude.m4 new file mode 100644 index 0000000..90725dd --- /dev/null +++ b/m4/acinclude.m4 @@ -0,0 +1,13 @@ +AC_DEFUN([PETI_ENABLED_DYNAMIC_LINKING], [ +AC_MSG_CHECKING(whether what binaries we shall create) +AC_ARG_ENABLE(dynamic-link, +[ --enable-dynamic-link Create dynamically linked binaries (default)], +if test "$enableval" = "yes"; then + AC_MSG_RESULT(dynamically linked) +else + LDFLAGS="$LDFLAGS -static" + AC_MSG_RESULT(statically linked) +fi, +AC_MSG_RESULT(dynamically linked)) +]) + diff --git a/m4/sdl.m4 b/m4/sdl.m4 new file mode 100644 index 0000000..5105810 --- /dev/null +++ b/m4/sdl.m4 @@ -0,0 +1,175 @@ +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN([AM_PATH_SDL], +[dnl +dnl Get the cflags and libraries from the sdl-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + if test x$sdl_exec_prefix != x ; then + sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_args="$sdl_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + + AC_REQUIRE([AC_CANONICAL_HOST]) + PATH="$prefix/bin:$prefix/usr/bin:$PATH" + AC_PATH_PROG(SDL_CONFIG, sdl-config, no, [$PATH]) + min_sdl_version=ifelse([$1], ,0.11.0,$1) + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl-config to some extent +dnl + rm -f conf.sdltest + AC_TRY_RUN([ +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main (int argc, char *argv[]) +{ + int major, minor, micro; + char *tmp_version; + + /* This hangs on some systems (?) + system ("touch conf.sdltest"); + */ + { FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); } + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_TRY_LINK([ +#include +#include "SDL.h" + +int main(int argc, char *argv[]) +{ return 0; } +#undef main +#define main K_and_R_C_main +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) diff --git a/missing b/missing new file mode 100644 index 0000000..28055d2 --- /dev/null +++ b/missing @@ -0,0 +1,376 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. + +scriptversion=2009-04-28.21; # UTC + +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009 Free Software Foundation, Inc. +# Originally by Fran,cois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: +sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' +sed_minuso='s/.* -o \([^ ]*\).*/\1/p' + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case $1 in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + autom4te touch the output file, or create a stub one + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. + +Send bug reports to ." + exit $? + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + exit $? + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + +esac + +# normalize program name to check for. +program=`echo "$1" | sed ' + s/^gnu-//; t + s/^gnu//; t + s/^g//; t'` + +# Now exit if we have it, but it failed. Also exit now if we +# don't have it and --version was passed (most likely to detect +# the program). This is about non-GNU programs, so use $1 not +# $program. +case $1 in + lex*|yacc*) + # Not GNU programs, they don't have --version. + ;; + + tar*) + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + exit 1 + fi + ;; + + *) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + elif test "x$2" = "x--version" || test "x$2" = "x--help"; then + # Could not run --version or --help. This is probably someone + # running `$TOOL --version' or `$TOOL --help' to check whether + # $TOOL exists and not knowing $TOOL uses missing. + exit 1 + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case $program in + aclocal*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case $f in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te*) + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison*|yacc*) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if test ! -f y.tab.h; then + echo >y.tab.h + fi + if test ! -f y.tab.c; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex*|flex*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if test $# -ne 1; then + eval LASTARG="\${$#}" + case $LASTARG in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if test -f "$SRCFILE"; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if test ! -f lex.yy.c; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit $? + fi + ;; + + makeinfo*) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + # The file to touch is that specified with -o ... + file=`echo "$*" | sed -n "$sed_output"` + test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` + if test -z "$file"; then + # ... or it is the one specified with @setfilename ... + infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n ' + /^@setfilename/{ + s/.* \([^ ]*\) *$/\1/ + p + q + }' $infile` + # ... or it is derived from the source name (dir/f.texi becomes f.info) + test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info + fi + # If the file does not exist, the user really needs makeinfo; + # let's fail without touching anything. + test -f $file || exit 1 + touch $file + ;; + + tar*) + shift + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case $firstarg in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case $firstarg in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: diff --git a/src/Arms.cpp b/src/Arms.cpp new file mode 100644 index 0000000..e9c91bf --- /dev/null +++ b/src/Arms.cpp @@ -0,0 +1,389 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include +#include + +#include "Arms.h" +#include "character.h" +#include "dice.h" +#include "screen.h" +#include "sprite.h" +#include "map.h" +#include "place.h" +#include "Missile.h" +#include "sound.h" +#include "player.h" +#include "log.h" + +ArmsType::ArmsType(const char *tag, const char *name, struct sprite *sprite, + int slotMask, + char *to_hit_dice, + char *to_defend_dice, + int numHands, + int range, + int weight, + char *damage_dice, + char *armor_dice, + int reqActPts, + int AP_mod, + bool thrown, + bool ubiquitousAmmo, + sound_t *fireSound, + class MissileType *missileType, + class ObjectType *ammo_type, + int strAttackMod, + int dexAttackMod, + int charDamageMod, + float charAvoidMod, + bool isBeam + ) + : ObjectType(tag, name, sprite, item_layer), + slotMask(slotMask), + numHands(numHands), + range(range), + weight(weight), + thrown(thrown), + ubiquitousAmmo(ubiquitousAmmo) +{ + toHitDice = strdup(to_hit_dice); + toDefendDice = strdup(to_defend_dice); + damageDice = strdup(damage_dice); + armorDice = strdup(armor_dice); + assert(toHitDice && toDefendDice && damageDice && armorDice); + this->fire_sound = fireSound; + + if (missileType) + { + missile = new Missile(missileType); + assert(missile); + } else { + missile = NULL; + } + + ammoType = ammo_type; + + if (thrown) + { + setAmmoType(this); + } + + str_attack_mod = strAttackMod; + dex_attack_mod = dexAttackMod; + char_damage_mod = charDamageMod; + char_avoid_mod = charAvoidMod; + + required_action_points = reqActPts; + modifier_to_AP_of_user = AP_mod; + beam = isBeam; +} + +ArmsType::ArmsType() +{ + // Don't ever expect to call this. Defining it to override the default + // one c++ automatically creates. + assert(false); + + missile = NULL; + ammoType = NULL; + thrown = false; + weight = 0; + ubiquitousAmmo = false; + layer = item_layer; + fire_sound = NULL_SOUND; + required_action_points = 1; + modifier_to_AP_of_user = 0; +} + +ArmsType::~ArmsType() +{ + if (missile != NULL) + delete missile; + if (toHitDice) + free(toHitDice); + if (toDefendDice) + free(toDefendDice); + if (damageDice) + free(damageDice); + if (armorDice) + free(armorDice); +} + +bool ArmsType::isType(int classID) +{ + if (classID == ARMS_TYPE_ID) + return true; + return ObjectType::isType(classID); +} + +int ArmsType::getType() +{ + return ARMS_TYPE_ID; +} + +class MissileType *ArmsType::getMissileType() +{ + if (missile == NULL) + return NULL; + return (class MissileType *) missile->getObjectType(); +} + +void ArmsType::setMissileType(class MissileType * missileType) +{ + if (missile != NULL) { + delete missile; + missile = NULL; + } + + if (missileType == NULL) + return; + + missile = new Missile(missileType); +} + +class ObjectType *ArmsType::getAmmoType() +{ + return ammoType; +} + +void ArmsType::setAmmoType(class ObjectType * ammo_type) +{ + ammoType = ammo_type; +} + +bool ArmsType::isMissileWeapon() +{ + return (missile != NULL && !thrown); +} + +bool ArmsType::isBeam() +{ + return beam; +} + +/* + triggers a hit-loc ifc event if appropriate for either weapon or missile +*/ +void ArmsType::fireHitLoc(Object *attacker, Object *target, struct place *place, int x, int y, int dam) +{ + if (isMissileWeapon() || isThrownWeapon()) + { + missile->fireHitLoc(attacker, target, place, x, y, dam); + } + if (canHitLocation()) + hitLocation(NULL, attacker, target, place, x, y, dam); +} + +/* + Fires a missile at a specific target, returns true if it reaches the target's location + updates misx and misy to be the location the missile reaches. +*/ +bool ArmsType::fire(class Character * target, int ox, int oy, int *misx, int *misy) +{ + if (isMissileWeapon() || isThrownWeapon()) { + *misx = target->getX(); + *misy = target->getY(); + missile->setPlace(target->getPlace()); + missile->setX(ox); + missile->setY(oy); + int frange = 0; + if (missile->getObjectType()->isFixedRange()) + { + frange = getRange(); + } + missile->animate(ox, oy, misx, misy, 0, frange); + if (!missile->hitTarget()) + return false; + } + return true; +} + +/* + Fires a missile at a specific tile, returns true if it reaches the target's location + updates tx and ty to be the location the missile reaches. +*/ +bool ArmsType::fire(struct place * place, int ox, int oy, int *tx, int *ty) +{ + if (isMissileWeapon() || isThrownWeapon()) { + missile->setPlace(place); + missile->setX(ox); + missile->setY(oy); + int frange = 0; + if (missile->getObjectType()->isFixedRange()) + { + frange = getRange(); + } + missile->animate(ox, oy, tx, ty, 0, frange); + if (!missile->hitTarget()) + return false; + } + return true; +} + +bool ArmsType::fireInDirection(struct place *place, int ox, int oy, + int dx, int dy, class Object *user) +{ + if (!isMissileWeapon() && !isThrownWeapon()) + return false; + + if (fire_sound) + sound_play(fire_sound, SOUND_MAX_VOLUME); + + int misx = dx * getRange() + ox; + int misy = dy * getRange() + oy; + + missile->setPlace(place); + missile->setX(ox); + missile->setY(oy); + missile->animate(ox, oy, + &misx, + &misy, + MISSILE_IGNORE_LOS|MISSILE_HIT_PARTY,0); + + if (!missile->hitTarget() || !missile->getStruck()) + return false; + + log_begin("%s hit ", getName()); + missile->getStruck()->describe(); + log_end("!"); + + // Reference the object while damaging it, since damage can remove it + // from the map. + obj_inc_ref(missile->getStruck()); + + missile->getStruck()->damage(dice_roll(damageDice)); + + if (missile->getStruck()->isDestroyed()) { + log_begin("%s destroyed ", getName()); + missile->getStruck()->describe(); + log_end("!"); + mapSetDirty(); + } + + // Release the reference + obj_dec_ref(missile->getStruck()); + + if (user) + user->decActionPoints(getRequiredActionPoints()); + + return true; +} + +void ArmsType::setThrown(bool val) +{ + if (val == thrown) + return; + thrown = val; + + if (!val) { + if (missile != NULL) { + delete missile; + missile = NULL; + } + return; + } + // the usual case: + setAmmoType(this); +} + +int ArmsType::getSlotMask() +{ + return slotMask; +} + +char * ArmsType::getToHitDice() +{ + return toHitDice; +} + +char * ArmsType::getDamageDice() +{ + return damageDice; +} + +char * ArmsType::getToDefendDice() +{ + return toDefendDice; +} + +char * ArmsType::getArmorDice() +{ + return armorDice; +} + +int ArmsType::getNumHands() +{ + return numHands; +} + +int ArmsType::getRange() +{ + return range; +} + +bool ArmsType::isThrownWeapon() +{ + return thrown; +} + +void ArmsType::setUbiquitousAmmo(bool val) +{ + ubiquitousAmmo = val; +} + +bool ArmsType::ammoIsUbiquitous() +{ + return ubiquitousAmmo; +} + +void ArmsType::setWeight(int val) +{ + weight = val; +} + +int ArmsType::getWeight(void) +{ + return weight; +} + +int ArmsType::modifyStrAttack(int strBonus) +{ + return strBonus * str_attack_mod; +} + +int ArmsType::modifyDexAttack(int dexBonus) +{ + return dexBonus * dex_attack_mod; +} + +int ArmsType::modifyDamageBonus(int damBonus) +{ + return damBonus * char_damage_mod; +} + +float ArmsType::modifyAvoidBonus(float avoidBonus) +{ + return avoidBonus * char_avoid_mod; +} + +int ArmsType::get_AP_mod(void) { + return modifier_to_AP_of_user; +} diff --git a/src/Arms.h b/src/Arms.h new file mode 100644 index 0000000..7356439 --- /dev/null +++ b/src/Arms.h @@ -0,0 +1,114 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef Arms_h +#define Arms_h + +#include "object.h" +#include "sound.h" + +class Missile; + +class ArmsType:public ObjectType { + + public: + + virtual bool isType(int classID); + virtual int getType(); + ArmsType(); + ArmsType(const char *tag, const char *name, struct sprite *sprite, + int slotMask, + char *to_hit_dice, + char *to_defend_dice, + int numHands, + int range, + int weight, + char *damage_dice, + char *armor_dice, + int reqActPts, + int AP_mod, + bool thrown, + bool ubiquitousAmmo, + sound_t *fireSound, + class MissileType *missileType, + class ObjectType *ammo_type, + int strAttackMod, + int dexAttackMod, + int charDamageMod, + float charAvoidMod, + bool isBeam + ); + virtual ~ ArmsType(); + + virtual char * getArmorDice(); + virtual char * getDamageDice(); + virtual int getSlotMask(); + virtual char * getToDefendDice(); + virtual char * getToHitDice(); + + virtual int getNumHands(); + virtual int getRange(); + virtual bool isMissileWeapon(); + virtual bool isBeam(); + virtual void setMissileType(class MissileType * missileType); + virtual class MissileType *getMissileType(); + virtual bool fire(class Character * target, int ox, int oy, int* misx, int* misy); + virtual bool fire(struct place *place, int ox, int oy, int* tx, int* ty); + virtual bool fireInDirection(struct place *place, int ox, int oy, int dx, int dy, class Object *user); + virtual void fireHitLoc(Object *attacker, Object *target, struct place *place, int x, int y, int dam); + virtual bool isThrownWeapon(); + virtual void setThrown(bool val); + virtual class ObjectType *getAmmoType(); + virtual void setAmmoType(ObjectType * ammo_type); + virtual void setUbiquitousAmmo(bool val); + virtual bool ammoIsUbiquitous(); + virtual void setWeight(int val); + virtual int getWeight(void); + virtual int modifyStrAttack(int strBonus); + virtual int modifyDexAttack(int dexBonus); + virtual int modifyDamageBonus(int damBonus); + virtual float modifyAvoidBonus(float avoidBonus); + virtual int get_AP_mod(void); + + + protected: + int slotMask; + int numHands; + int range; + int weight; + int modifier_to_AP_of_user; + bool thrown; + bool ubiquitousAmmo; + char *armorDice; + char *damageDice; + char *toDefendDice; + char *toHitDice; + sound_t *fire_sound; + bool beam; + int str_attack_mod; + int dex_attack_mod; + int char_damage_mod; + float char_avoid_mod; + class Missile *missile; + class ObjectType *ammoType; +}; + +#endif diff --git a/src/Being.cpp b/src/Being.cpp new file mode 100644 index 0000000..2274413 --- /dev/null +++ b/src/Being.cpp @@ -0,0 +1,382 @@ +#include "astar.h" +#include "factions.h" +#include "Being.h" +#include "map.h" +#include "place.h" +#include "session.h" +#include "log.h" +#include "terrain.h" +#include "kern_intvar.h" + +// USE_CACHED_PATH works but it can cause some strange-seeming behavior. If a +// new, better route opens than the cached path then the being won't find it, +// but will blindly follow the cached path. Unless pathfinding becomes a +// performance issue leave this off. +// +// Addendum: actually, we need it on, because otherwise the member will +// "thrash" when, for example, a portcullis remains closed: pathfinding around +// it, then pathfinding through it and trying to open it, then around it again, +// etc... +#ifndef USE_CACHED_PATH +# define USE_CACHED_PATH true +#endif + +Being::Being() +{ + setDefaults(); +} + +Being::Being(class ObjectType *type) + : Object(type) +{ + setDefaults(); +} + +void Being::setDefaults() +{ + name = NULL; + cachedPath = NULL; + cachedPathPlace = NULL; + setBaseFaction(INVALID_FACTION); +} + +Being::~Being() +{ + if (cachedPath) { + astar_path_destroy(cachedPath); + } + if (name) { + free(name); + } +} + +void Being::setBaseFaction(int faction) +{ + baseFaction = faction; + setCurrentFaction(faction); +} + +int Being::getBaseFaction() +{ + return baseFaction; +} + +int Being::getCurrentFaction() +{ + return currentFaction; +} + +enum layer Being::getLayer() +{ + return being_layer; +} + +void Being::switchPlaces(class Being *occupant) +{ + int oldx = getX(); + int oldy = getY(); + int newx = occupant->getX(); + int newy = occupant->getY(); + + struct place *oldPlace = getPlace(); + occupant->relocate(oldPlace, oldx, oldy); + relocate(oldPlace, newx, newy); + decActionPoints(place_get_diagonal_movement_cost(getPlace(), + oldx, oldy, + newx, newy, + this, 0)); +} + +bool Being::pathfindTo(struct place *destplace, int destx, int desty, + int flags) +{ + struct astar_search_info as_info; + struct astar_node *pathPtr; + + if (!flags) + flags = PFLAG_IGNORECOMPANIONS | PFLAG_IGNOREMECHS; + + if (isStationary()) + return false; + + // For now, don't try to pathfind between places. + if (destplace != getPlace()) + { + warn("%s in %s, can't pathfind to %s", getName(), + getPlace()->name, destplace->name); + return false; + } + + //dbg("%s pathfind from (%d %d) to (%d %d)\n", + //getName(), getX(), getY(), destx, desty); + + // Check the cachedPath + if (USE_CACHED_PATH && cachedPath) + { + + //dbg("cachedPath: "); + //astar_dbg_dump_path(cachedPath); + + // If the cached path is for a different place then we can't + // use it + if (getPlace() != cachedPathPlace) + { + //dbg("old place\n"); + clearCachedPath(); + } + else + { + pathPtr = cachedPath; + + + // If the cached path does not start from the current + // coordinates then we can't use it. + if (pathPtr->x != getX() || pathPtr->y != getY()) + { + //dbg("old start\n"); + clearCachedPath(); + } + else if (pathPtr->x != destx || pathPtr->y != desty) + { + pathPtr = pathPtr->next; + + // if we are about to hit nasty terrain, reevaluate our options + if (pathPtr && place_get_terrain(getPlace(),pathPtr->x,pathPtr->y)->effect) + { + dbg("recheck path (terrain)\n"); + pathPtr = NULL; + } + if (pathPtr && place_get_object(getPlace(),pathPtr->x,pathPtr->y, field_layer) != NULL) + { + dbg("recheck path (field)\n"); + pathPtr = NULL; + } + + //dbg("tracing\n"); + // Trace down the path until it ends or hits + // the target + while (pathPtr && + (pathPtr->x != destx || pathPtr->y != desty)) + pathPtr = pathPtr->next; + + // If this path is no good then destroy it, + // we'll have to get a new one. + if (! pathPtr) + { + //dbg("won't reach\n"); + clearCachedPath(); + } + } + } + } + + // If we don't have a valid path then try to find one, first by + // ignoring mechanisms. + if (! USE_CACHED_PATH || ! cachedPath) { + //dbg("searching\n"); + memset(&as_info, 0, sizeof (as_info)); + as_info.x0 = getX(); + as_info.y0 = getY(); + as_info.x1 = destx; + as_info.y1 = desty; + as_info.flags = flags; + cachedPath = place_find_path(getPlace(), &as_info, this); + } + + // If we still don't have a valid path then give up + if (!cachedPath) { + //dbg("none found\n"); + return false; + } + + // If the path does not lead anywhere then we must be at our + // destination, so we can destroy it and return. + pathPtr = cachedPath->next; + if (! pathPtr) { + //dbg("already there\n"); + clearCachedPath(); + return true; + } + + // Otherwise the path is good, so cache the place. + cachedPathPlace = getPlace(); + //dbg("Found path: "); + //astar_dbg_dump_path(cachedPath); + + enum MoveResult result; + result = move(pathPtr->x - getX(), + pathPtr->y - getY()); + + // Was the move blocked by an occupant? + if (result == WasOccupied) { + + // Yes - are we supposed to ignore beings? + if (flags & PFLAG_IGNOREBEINGS) { + + // Yes - try to switch. I don't know why I need to + // check for isOnMap() (when would we not be on a map? + // multi-place scehdules maybe?), but it looks like + // something we probably added to fix a corner case, so + // I'm leaving it in. + class Character *occupant; + if (isOnMap() + && (occupant = (class Character *) place_get_object(getPlace(), + pathPtr->x, pathPtr->y, + being_layer))) { + if (!are_hostile(this, occupant) + && occupant->isIncapacitated()) + { + if (!place_is_passable(getPlace(), getX(), getY(), + occupant, 0)) + { + relocate(getPlace(), pathPtr->x, pathPtr->y); + runHook(OBJ_HOOK_MOVE_DONE, "pdd", getPlace(), + pathPtr->x, pathPtr->y); + decActionPoints(place_get_diagonal_movement_cost + ( + getPlace(), + getX(), getY(), + pathPtr->x, pathPtr->y, + this, PFLAG_IGNOREMECHS + )); + } + switchPlaces(occupant); + } + } + } else { + // No, we are not ignoring beings. We're probably using + // a cached path that was built when the tile was + // unoccupied. Let's just null out the cachedPath now + // and let the being try again on the next turn. + clearCachedPath(); + } + } + + // If the move failed because something impassable is there then check + // for a mech and try to handle it. This is good enough to get through + // the usual implementation of a door. + if (result == WasImpassable && isOnMap()) { + + //dbg("impassable\n"); + class Object *mech; + mech = place_get_object(getPlace(), + pathPtr->x, + pathPtr->y, + mech_layer); + if (mech && mech->getObjectType()->canHandle()) { + // workaround for [ 1114054 ] messages for off-screen + // NPC's getting printed: temporarily prevent the mech + // script from generating log messages + log_disable(); + mech->getObjectType()->handle(mech, this); + log_enable(); + mapSetDirty(); + + // Now try and move again. + result = move(pathPtr->x - getX(), + pathPtr->y - getY()); + + // Workaround an infinite loop in Character::exec() + // where a party member is trying to rendezvous on a + // path through a mech, and it keeps handling the mech, + // thus decrementing its action points, but in fact it + // can't move on any path. + if (MovedOk == result) { + this->decActionPoints(kern_intvar_get("AP_COST:handle_mechanism")); + } + + } + + if (WasImpassable == result && isOnMap()) { + + //dbg("still impassable\n"); + // If the move was still impassable then try and find a + // path that avoids mechanisms. Destroy this path + // first. + clearCachedPath(); + + // Redo the search + memset(&as_info, 0, sizeof (as_info)); + as_info.x0 = getX(); + as_info.y0 = getY(); + as_info.x1 = destx; + as_info.y1 = desty; + as_info.flags = PFLAG_IGNORECOMPANIONS; + cachedPath = place_find_path(getPlace(), &as_info, + this); + + // If we still don't have a valid path then give up + if (!cachedPath) { + //dbg("no path\n"); + return false; + } + + //dbg("New path: "); + //astar_dbg_dump_path(cachedPath); + + // Otherwise the path is good, so cache the place. + cachedPathPlace = getPlace(); + pathPtr = cachedPath->next; + + // Check if already there (can happen if the target changes) + if (! pathPtr) { + //dbg("already there\n"); + clearCachedPath(); + return true; + } + + // Try to take the next step along the path. + result = move(pathPtr->x - getX(), + pathPtr->y - getY()); + + } + } + + // If the move worked (as evidenced by the fact that our location + // changed to the next node) then free the first node and make the next + // node the head of the path so we can continue using it next turn. + if (getX() == pathPtr->x && + getY() == pathPtr->y) { + //dbg("ok\n"); + if (USE_CACHED_PATH) { + astar_node_destroy(cachedPath); + cachedPath = pathPtr; + } else { + clearCachedPath(); + } + return true; + } + + return false; +} + +const char *Being::getName() +{ + if (name) + return name; + return ""; +} + +void Being::setName(const char *val) +{ + if (val) + name = strdup(val); + else if (name) { + free(name); + name = NULL; + } +} + +void Being::setCurrentFaction(int faction) +{ + currentFaction = faction; +} + +void Being::clearCachedPath() +{ + if (cachedPath) { + astar_path_destroy(cachedPath); + cachedPath = NULL; + cachedPathPlace = NULL; + } +} diff --git a/src/Being.h b/src/Being.h new file mode 100644 index 0000000..4bad5c7 --- /dev/null +++ b/src/Being.h @@ -0,0 +1,63 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef Being_h +#define Being_h + +#include "object.h" + +#define obj_is_being(obj) ((obj)->getLayer() == being_layer) + +class Being:public Object { + + public: + + Being(); + Being(class ObjectType *type); + + virtual ~Being(); + virtual int getCurrentFaction(); + virtual enum layer getLayer(); + virtual const char *getName(); + virtual void setCurrentFaction(int faction); + + int getBaseFaction(); + bool pathfindTo(struct place *place, int x, int y, int flags = 0); + void setBaseFaction(int faction); + void setName(const char *name); + + // These are public because player_party::rendezvous makes heavy use of + // them... + struct astar_node *cachedPath; // for pathfinding + struct place *cachedPathPlace; // for pathfinding + + protected: + void setDefaults(); + virtual void switchPlaces(class Being *); + + private: + char *name; + int baseFaction; + int currentFaction; + void clearCachedPath(); +}; + +#endif diff --git a/src/Container.cpp b/src/Container.cpp new file mode 100644 index 0000000..4a07145 --- /dev/null +++ b/src/Container.cpp @@ -0,0 +1,266 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "common.h" +#include "Container.h" +#include "session.h" + +static void move_to_map(struct inv_entry *ie, void *data) +{ + class Container *box = (class Container *) data; + assert(ie->count); + + class Object *obj = new Object(); + assert(obj); + + obj->init(ie->type); + obj->setCount(ie->count); + obj->relocate(box->getPlace(), box->getX(), box->getY()); + + box->takeOut(ie->type, ie->count); +} + +static void destroy_content(struct inv_entry *ie, void *data) +{ + list_remove(&ie->list); + delete ie; +} + +Container::Container() +{ + list_init(&contents); +} + +Container::~Container() +{ + return; + forEach(destroy_content, NULL); +} + +bool Container::add(class ObjectType * type, int quantity) +{ + struct inv_entry *ie; + + if (quantity <= 0) + return false; + + ie = search(type); + if (!ie) { + ie = new struct inv_entry; + list_add(&contents, &ie->list); + ie->ref = 0; + ie->count = 0; + ie->type = type; + } + + ie->count += quantity; + + return true; +} + +int Container::numAvail(class ObjectType *type) +{ + struct inv_entry *ie; + + ie = search(type); + if (!ie) + return 0; + return ie->count; + +} + +bool Container::takeOut(class ObjectType * type, int quantity) +{ + struct inv_entry *ie; + + ie = search(type); + if (!ie) + return false; + + if (ie->count < quantity) + return false; + + ie->count -= quantity; + assert(ie->count >= 0); + + if (!ie->count) { + list_remove(&ie->list); + delete ie; + } + + return true; +} + +void Container::open() +{ + forEach(move_to_map, this); + assert(list_empty(&contents)); +} + +void Container::forEach(void (*fx) (struct inv_entry *, void *), void *data) +{ + struct list *elem = contents.next; + while (elem != &contents) { + struct list *tmp = elem->next; + struct inv_entry *ie = outcast(elem, struct inv_entry, list); + fx(ie, data); + elem = tmp; + } +} + +struct inv_entry *Container::search(class ObjectType * type) +{ + struct list *elem = contents.next; + while (elem != &contents) { + struct list *tmp = elem->next; + struct inv_entry *ie = outcast(elem, struct inv_entry, list); + if (ie->type == type) + return ie; + elem = tmp; + } + return NULL; +} + +void Container::saveContents(struct save *save) +{ + struct list *elem; + struct inv_entry *ie; + int count; + + save->enter(save, "(list "); + + // Iterate backwards to save/reload in the same order + for (elem = contents.prev; elem != &contents; elem = elem->prev) { + ie = outcast(elem, struct inv_entry, list); + count = ie->count - ie->ref; + if (count) { + save->write(save, "(list %d %s)\n", + count, + ie->type->getTag()); + } + } + save->exit(save, ")\n"); +} + +void Container::save(struct save *save) +{ + assert(saved < save->session_id); + + saved = save->session_id; + + save->enter(save, "(kern-mk-inventory\n"); + save->write(save, ";; contents\n"); + if (list_empty(&contents)) { + save->write(save, "nil\n"); + } else { + saveContents(save); + } + + Object::saveHooks(save); + + save->exit(save, ")\n"); +} + +int Container::filter_count(struct filter *filter) +{ + struct inv_entry *ie; + int q = 0; + + ie = first(filter); + while (ie) { + q++; + ie = next(ie, filter); + } + + return q; +} + +struct inv_entry *Container::first(struct filter *filter) +{ + struct list *elem; + struct inv_entry *ie; + + elem = contents.next; + while (elem != &contents) { + ie = outcast(elem, struct inv_entry, list); + if (!filter || + filter->fx(ie, filter->fdata)) + return ie; + elem = elem->next; + } + return NULL; +} + +struct inv_entry *Container::next(struct inv_entry *ie, struct filter *filter) +{ + struct list *elem; + + if (ie == NULL) + return first(filter); + + elem = ie->list.next; + while (elem != &contents) { + ie = outcast(elem, struct inv_entry, list); + if (!filter || + filter->fx(ie, filter->fdata)) + return ie; + elem = elem->next; + } + return NULL; +} + +struct inv_entry *Container::prev(struct inv_entry *ie, struct filter *filter) +{ + struct list *elem; + + elem = ie->list.prev; + while (elem != &contents) { + ie = outcast(elem, struct inv_entry, list); + if (!filter || + filter->fx(ie, filter->fdata)) + return ie; + elem = elem->prev; + } + return NULL; +} + +bool Container::isEmpty() +{ + return list_empty(&contents); +} + +void Container::moveToFront(struct inv_entry *ie) +{ + list_remove(&ie->list); + list_add(&contents, &ie->list); +} + +void Container::relocate(struct place *newplace, int newx, int newy, int flags, + struct closure *place_switch_hook) +{ + // Spill the contents but don't try to put this down on the map as a + // physical object, because it's not. + setPlace(newplace); + setX(newx); + setY(newy); + open(); +} diff --git a/src/Container.h b/src/Container.h new file mode 100644 index 0000000..4d87965 --- /dev/null +++ b/src/Container.h @@ -0,0 +1,57 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef Container_h +#define Container_h + +#include "object.h" + +class Container:public Object { + public: + Container(); + virtual ~ Container(); + void open(); + virtual struct inv_entry *search(class ObjectType * type); + bool isEmpty(); + + // Virtual methods from base class + virtual bool add(class ObjectType * type, int quantity); + virtual void save(struct save *save); + virtual bool takeOut(class ObjectType * type, int quantity); + virtual void relocate(struct place *newplace, int newx, int newy, + int flags = 0, + struct closure *place_switch_hook = NULL); + int numAvail(class ObjectType * type); + + int filter_count(struct filter *); + struct inv_entry *first(struct filter *); + struct inv_entry *next(struct inv_entry *ie, struct filter*); + struct inv_entry *prev(struct inv_entry *ie, struct filter*); + void moveToFront(struct inv_entry *ie); + + void forEach(void (*fx) (struct inv_entry *, void *), void *); + + protected: + void saveContents(struct save *save); + struct list contents; +}; + +#endif diff --git a/src/Field.cpp b/src/Field.cpp new file mode 100644 index 0000000..1a3dda6 --- /dev/null +++ b/src/Field.cpp @@ -0,0 +1,143 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "Field.h" +#include "common.h" +#include "session.h" + +bool FieldType::isType(int classID) +{ + if (classID == FIELD_TYPE_ID) + return true; + return ObjectType::isType(classID); +} + +int FieldType::getType() +{ + return FIELD_TYPE_ID; +} + +FieldType::FieldType(const char *tag, const char *name, struct sprite *sprite, + int light_, int duration_, int pclass_, closure_t *clx) + : ObjectType(tag, name, sprite, field_layer), + pclass(pclass_), light(light_), duration(duration_) +{ + if (clx) { + closure_ref(clx); + effect = clx; + } else { + effect = NULL; + } +} + +FieldType::~FieldType() +{ + closure_unref_safe(effect); +} + +int FieldType::getLight() +{ + return light; +} + +void FieldType::setLight(int val) +{ + light = val; +} + +void FieldType::setDuration(int val) +{ + duration = val; +} + +int FieldType::getDuration() +{ + return duration; +} + +class Object *FieldType::createInstance() +{ + return new Field(this); +} + +class FieldType * Field::getObjectType() +{ + return (class FieldType *) Object::getObjectType(); +} + +bool FieldType::isPermanent() +{ + return (duration < 0); +} + +////////////////////////////////////////////////////////////////////////////// + +Field::Field(FieldType *type) + : Object(type) +{ + duration = type->getDuration(); +} + +Field::Field(FieldType *type, int dur) + : Object(type) +{ + duration = dur; +} + +Field::Field() : duration(0) +{ +} + +Field::~ Field() +{ +} + +int Field::getLight() +{ + return getObjectType()->getLight(); +} + +void Field::exec() +{ + startTurn(); + if (isDestroyed()) + return; + + if (getObjectType()->isPermanent()) + return; + + duration--; + assert(duration >= 0); + if (duration == 0) + destroy(); +} + +void Field::save(struct save *save) +{ + save->write(save, "(kern-mk-field %s %d)", getObjectType()->getTag(), + duration); +} + +int Field::getPclass() +{ + return getObjectType()->pclass; +} diff --git a/src/Field.h b/src/Field.h new file mode 100644 index 0000000..0644960 --- /dev/null +++ b/src/Field.h @@ -0,0 +1,69 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef Field_h +#define Field_h + +#include "object.h" +#include "closure.h" + +class FieldType:public ObjectType { + + public: + FieldType(const char *tag, const char *name, struct sprite *sprite, int light, + int duration, int pclass, closure_t *effect); + virtual ~FieldType(); + virtual bool isType(int classID); + virtual int getType(); + virtual int getLight(); + virtual void setLight(int val); + virtual void setDuration(int val); + virtual int getDuration(); + virtual class Object *createInstance(); + + bool isPermanent(); + + closure_t *effect; /* when stepped on */ + int pclass; + + protected: + int light; + int duration; +}; + +class Field:public Object { + + public: + virtual class FieldType * getObjectType(); + Field(); + Field(class FieldType *type); + Field(class FieldType *type, int duration); + virtual ~ Field(); + virtual int getLight(); + virtual void exec(); + virtual void save(struct save *save); + virtual int getPclass(); + + protected: + int duration; +}; + +#endif diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..a1ffae4 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,786 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# src/Makefile. Generated from Makefile.in by configure. + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + + + +pkgdatadir = $(datadir)/nazghul +pkgincludedir = $(includedir)/nazghul +pkglibdir = $(libdir)/nazghul +pkglibexecdir = $(libexecdir)/nazghul +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = i686-pc-linux-gnu +host_triplet = i686-pc-linux-gnu +target_triplet = i686-pc-linux-gnu +bin_PROGRAMS = nazghul$(EXEEXT) +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/sdl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am_nazghul_OBJECTS = angband.$(OBJEXT) Arms.$(OBJEXT) ascii.$(OBJEXT) \ + astar.$(OBJEXT) character.$(OBJEXT) cmdwin.$(OBJEXT) \ + combat.$(OBJEXT) common.$(OBJEXT) console.$(OBJEXT) \ + Container.$(OBJEXT) cursor.$(OBJEXT) debug.$(OBJEXT) \ + event.$(OBJEXT) Field.$(OBJEXT) floodfill.$(OBJEXT) \ + foogod.$(OBJEXT) formation.$(OBJEXT) hash.$(OBJEXT) \ + heap.$(OBJEXT) images.$(OBJEXT) knapsack.$(OBJEXT) \ + los.$(OBJEXT) map.$(OBJEXT) nazghul.$(OBJEXT) Party.$(OBJEXT) \ + object.$(OBJEXT) occ.$(OBJEXT) olist.$(OBJEXT) place.$(OBJEXT) \ + play.$(OBJEXT) player.$(OBJEXT) Reagent.$(OBJEXT) \ + sched.$(OBJEXT) screen.$(OBJEXT) sky.$(OBJEXT) sound.$(OBJEXT) \ + species.$(OBJEXT) sprite.$(OBJEXT) status.$(OBJEXT) \ + terrain.$(OBJEXT) terrain_map.$(OBJEXT) tree.$(OBJEXT) \ + vehicle.$(OBJEXT) wind.$(OBJEXT) wq.$(OBJEXT) \ + Missile.$(OBJEXT) cmd.$(OBJEXT) clock.$(OBJEXT) \ + vmask.$(OBJEXT) ctrl.$(OBJEXT) scheme.$(OBJEXT) \ + session.$(OBJEXT) closure.$(OBJEXT) kern.$(OBJEXT) \ + dice.$(OBJEXT) gob.$(OBJEXT) magic.$(OBJEXT) effect.$(OBJEXT) \ + conv.$(OBJEXT) ptable.$(OBJEXT) mmode.$(OBJEXT) log.$(OBJEXT) \ + dtable.$(OBJEXT) Being.$(OBJEXT) node.$(OBJEXT) tick.$(OBJEXT) \ + dimensions.$(OBJEXT) cfg.$(OBJEXT) menus.$(OBJEXT) \ + file.$(OBJEXT) skill.$(OBJEXT) skill_set.$(OBJEXT) \ + skill_set_entry.$(OBJEXT) repstr.$(OBJEXT) templ.$(OBJEXT) \ + objectfreezer.$(OBJEXT) kern_intvar.$(OBJEXT) ztats.$(OBJEXT) \ + ztats_pane.$(OBJEXT) ztats_pm.$(OBJEXT) \ + ztats_container_pane.$(OBJEXT) ztats_arms.$(OBJEXT) \ + ztats_reagents.$(OBJEXT) ztats_spells.$(OBJEXT) \ + ztats_items.$(OBJEXT) ztats_misc.$(OBJEXT) escape.$(OBJEXT) \ + terrain_editor.$(OBJEXT) +nazghul_OBJECTS = $(am_nazghul_OBJECTS) +nazghul_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +SOURCES = $(nazghul_SOURCES) +DIST_SOURCES = $(nazghul_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = ${SHELL} /home/gmcnutt/projects/haxima/nazghul/missing --run aclocal-1.11 +AMTAR = ${SHELL} /home/gmcnutt/projects/haxima/nazghul/missing --run tar +AUTOCONF = ${SHELL} /home/gmcnutt/projects/haxima/nazghul/missing --run autoconf +AUTOHEADER = ${SHELL} /home/gmcnutt/projects/haxima/nazghul/missing --run autoheader +AUTOMAKE = ${SHELL} /home/gmcnutt/projects/haxima/nazghul/missing --run automake-1.11 +AWK = gawk +CC = g++ +CCDEPMODE = depmode=gcc3 +CFLAGS = -g -O2 -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT +CPP = gcc -E +CPPFLAGS = +CXX = g++ +CXXCPP = g++ -E -g -O2 -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT +CXXDEPMODE = depmode=gcc3 +CXXFLAGS = -g -O2 -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT +CYGPATH_W = echo +DEFS = -DHAVE_CONFIG_H +DEPDIR = .deps +ECHO_C = +ECHO_N = -n +ECHO_T = +EGREP = /bin/grep -E +EXEEXT = +GREP = /bin/grep +INSTALL = /usr/bin/install -c +INSTALL_DATA = ${INSTALL} -m 644 +INSTALL_PROGRAM = ${INSTALL} +INSTALL_SCRIPT = ${INSTALL} +INSTALL_STRIP_PROGRAM = $(install_sh) -c -s +LDFLAGS = +LIBOBJS = +LIBS = -lSDL_mixer -lSDL_image -lpng -lSDL -lpthread +LTLIBOBJS = +MAINT = +MAKEINFO = ${SHELL} /home/gmcnutt/projects/haxima/nazghul/missing --run makeinfo +MKDIR_P = /bin/mkdir -p +OBJEXT = o +PACKAGE = nazghul +PACKAGE_BUGREPORT = nazghul-devel@lists.sourceforge.net +PACKAGE_NAME = nazghul +PACKAGE_STRING = nazghul 0.7.1 +PACKAGE_TARNAME = nazghul +PACKAGE_VERSION = 0.7.1 +PATH_SEPARATOR = : +SDL_CFLAGS = -I/usr/include/SDL -D_GNU_SOURCE=1 -D_REENTRANT +SDL_CONFIG = /usr/bin/sdl-config +SDL_LIBS = -lSDL -lpthread +SET_MAKE = +SHELL = /bin/sh +STRIP = +VERSION = 0.7.1 +abs_builddir = /home/gmcnutt/projects/haxima/nazghul/src +abs_srcdir = /home/gmcnutt/projects/haxima/nazghul/src +abs_top_builddir = /home/gmcnutt/projects/haxima/nazghul +abs_top_srcdir = /home/gmcnutt/projects/haxima/nazghul +ac_ct_CC = gcc +ac_ct_CXX = g++ +am__include = include +am__leading_dot = . +am__quote = +am__tar = ${AMTAR} chof - "$$tardir" +am__untar = ${AMTAR} xf - +bindir = ${exec_prefix}/bin +build = i686-pc-linux-gnu +build_alias = +build_cpu = i686 +build_os = linux-gnu +build_vendor = pc +builddir = . +datadir = ${datarootdir} +datarootdir = ${prefix}/share +docdir = ${datarootdir}/doc/${PACKAGE_TARNAME} +dvidir = ${docdir} +exec_prefix = ${prefix} +host = i686-pc-linux-gnu +host_alias = +host_cpu = i686 +host_os = linux-gnu +host_vendor = pc +htmldir = ${docdir} +includedir = ${prefix}/include +infodir = ${datarootdir}/info +install_sh = ${SHELL} /home/gmcnutt/projects/haxima/nazghul/install-sh +libdir = ${exec_prefix}/lib +libexecdir = ${exec_prefix}/libexec +localedir = ${datarootdir}/locale +localstatedir = ${prefix}/var +mandir = ${datarootdir}/man +mkdir_p = /bin/mkdir -p +oldincludedir = /usr/include +pdfdir = ${docdir} +prefix = /usr/local +program_transform_name = s,x,x, +psdir = ${docdir} +sbindir = ${exec_prefix}/sbin +sharedstatedir = ${prefix}/com +srcdir = . +sysconfdir = ${prefix}/etc +target = i686-pc-linux-gnu +target_alias = +target_cpu = i686 +target_os = linux-gnu +target_vendor = pc +top_build_prefix = ../ +top_builddir = .. +top_srcdir = .. +AM_CXXFLAGS = -Wall -DDATADIR=\"${datarootdir}\" -DPREFIX=\"/usr/local\" +AM_CFLAGS = ${AM_CXXFLAGS} + +#nazghul_SOURCES = $(wildcard *.c) $(wildcard *.cpp) $(wildcard *.h) +nazghul_SOURCES = \ + angband.c \ + Arms.cpp \ + Arms.h \ + ascii.c \ + ascii.h \ + astar.c \ + astar.h \ + character.cpp \ + character.h \ + cmdwin.c \ + cmdwin.h \ + combat.c \ + combat.h \ + common.c \ + common.h \ + console.c \ + console.h \ + constants.h \ + Container.cpp \ + Container.h \ + cursor.cpp \ + cursor.h \ + debug.h \ + debug.c \ + dup_constants.h \ + event.c \ + event.h \ + Field.h \ + Field.cpp \ + floodfill.c \ + foogod.c \ + foogod.h \ + formation.h \ + formation.c \ + hash.c \ + hash.h \ + heap.c \ + heap.h \ + images.c \ + images.h \ + knapsack.c \ + knapsack.h \ + list.h \ + los.c \ + los.h \ + Makefile \ + map.c \ + map.h \ + nazghul.h \ + nazghul.c \ + Party.cpp \ + Party.h \ + object.c \ + object.h \ + occ.c \ + occ.h \ + olist.c \ + olist.h \ + pinfo.h \ + place.c \ + place.h \ + play.c \ + player.cpp \ + player.h \ + play.h \ + Reagent.cpp \ + Reagent.h \ + sched.c \ + sched.h \ + screen.c \ + screen.h \ + sky.c \ + sky.h \ + sound.c \ + sound.h \ + species.c \ + species.h \ + sprite.c \ + sprite.h \ + status.c \ + status.h \ + terrain.c \ + terrain.h \ + terrain_map.c \ + terrain_map.h \ + tree.c \ + tree.h \ + vehicle.cpp \ + vehicle.h \ + wind.c \ + wind.h \ + wq.c \ + wq.h \ + Missile.cpp \ + Missile.h \ + cmd.c \ + cmd.h \ + clock.c \ + clock.h \ + vmask.h \ + vmask.c \ + ctrl.h \ + ctrl.c \ + scheme.c \ + scheme.h \ + scheme-private.h \ + opdefines.h \ + macros.h \ + session.c \ + session.h \ + closure.h \ + closure.c \ + kern.h \ + kern.c \ + dice.h \ + dice.c \ + gob.c \ + gob.h \ + magic.h \ + magic.c \ + effect.h \ + effect.c \ + conv.h \ + conv.c \ + ptable.c \ + ptable.h \ + mmode.c \ + mmode.h \ + log.h \ + log.c \ + dtable.h \ + dtable.c \ + Being.h \ + Being.cpp \ + factions.h \ + result.h \ + node.h \ + node.c \ + tick.h \ + tick.c \ + blender.h \ + dimensions.h dimensions.c \ + cfg.h cfg.c \ + menus.h menus.c \ + file.h file.c \ + screen_dims.h \ + skill.h skill.c \ + skill_set.h skill_set.c \ + skill_set_entry.h skill_set_entry.c \ + repstr.h repstr.c \ + templ.h templ.c \ + objectfreezer.h objectfreezer.c \ + kern_intvar.c kern_intvar.h \ + ztats.h ztats.c \ + ztats_pane.h ztats_pane.c \ + ztats_pm.h ztats_pm.c \ + ztats_container_pane.h ztats_container_pane.c \ + ztats_arms.h ztats_arms.c \ + ztats_reagents.h ztats_reagents.c \ + ztats_spells.h ztats_spells.c \ + ztats_items.h ztats_items.c \ + ztats_misc.h ztats_misc.c \ + applet.h \ + session_hooks.h \ + session_queries.h \ + bitset.h \ + escape.c escape.h \ + terrain_editor.c terrain_editor.h + +INCLUDES = -I$(includedir) \ + -I$(srcdir) -I$(top_srcdir)/include -I$(top_srcdir) \ + -I$(top_builddir) -I$(top_builddir)/include -I. + +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +nazghul$(EXEEXT): $(nazghul_OBJECTS) $(nazghul_DEPENDENCIES) + @rm -f nazghul$(EXEEXT) + $(CXXLINK) $(nazghul_OBJECTS) $(nazghul_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +include ./$(DEPDIR)/Arms.Po +include ./$(DEPDIR)/Being.Po +include ./$(DEPDIR)/Container.Po +include ./$(DEPDIR)/Field.Po +include ./$(DEPDIR)/Missile.Po +include ./$(DEPDIR)/Party.Po +include ./$(DEPDIR)/Reagent.Po +include ./$(DEPDIR)/angband.Po +include ./$(DEPDIR)/ascii.Po +include ./$(DEPDIR)/astar.Po +include ./$(DEPDIR)/cfg.Po +include ./$(DEPDIR)/character.Po +include ./$(DEPDIR)/clock.Po +include ./$(DEPDIR)/closure.Po +include ./$(DEPDIR)/cmd.Po +include ./$(DEPDIR)/cmdwin.Po +include ./$(DEPDIR)/combat.Po +include ./$(DEPDIR)/common.Po +include ./$(DEPDIR)/console.Po +include ./$(DEPDIR)/conv.Po +include ./$(DEPDIR)/ctrl.Po +include ./$(DEPDIR)/cursor.Po +include ./$(DEPDIR)/debug.Po +include ./$(DEPDIR)/dice.Po +include ./$(DEPDIR)/dimensions.Po +include ./$(DEPDIR)/dtable.Po +include ./$(DEPDIR)/effect.Po +include ./$(DEPDIR)/escape.Po +include ./$(DEPDIR)/event.Po +include ./$(DEPDIR)/file.Po +include ./$(DEPDIR)/floodfill.Po +include ./$(DEPDIR)/foogod.Po +include ./$(DEPDIR)/formation.Po +include ./$(DEPDIR)/gob.Po +include ./$(DEPDIR)/hash.Po +include ./$(DEPDIR)/heap.Po +include ./$(DEPDIR)/images.Po +include ./$(DEPDIR)/kern.Po +include ./$(DEPDIR)/kern_intvar.Po +include ./$(DEPDIR)/knapsack.Po +include ./$(DEPDIR)/log.Po +include ./$(DEPDIR)/los.Po +include ./$(DEPDIR)/magic.Po +include ./$(DEPDIR)/map.Po +include ./$(DEPDIR)/menus.Po +include ./$(DEPDIR)/mmode.Po +include ./$(DEPDIR)/nazghul.Po +include ./$(DEPDIR)/node.Po +include ./$(DEPDIR)/object.Po +include ./$(DEPDIR)/objectfreezer.Po +include ./$(DEPDIR)/occ.Po +include ./$(DEPDIR)/olist.Po +include ./$(DEPDIR)/place.Po +include ./$(DEPDIR)/play.Po +include ./$(DEPDIR)/player.Po +include ./$(DEPDIR)/ptable.Po +include ./$(DEPDIR)/repstr.Po +include ./$(DEPDIR)/sched.Po +include ./$(DEPDIR)/scheme.Po +include ./$(DEPDIR)/screen.Po +include ./$(DEPDIR)/session.Po +include ./$(DEPDIR)/skill.Po +include ./$(DEPDIR)/skill_set.Po +include ./$(DEPDIR)/skill_set_entry.Po +include ./$(DEPDIR)/sky.Po +include ./$(DEPDIR)/sound.Po +include ./$(DEPDIR)/species.Po +include ./$(DEPDIR)/sprite.Po +include ./$(DEPDIR)/status.Po +include ./$(DEPDIR)/templ.Po +include ./$(DEPDIR)/terrain.Po +include ./$(DEPDIR)/terrain_editor.Po +include ./$(DEPDIR)/terrain_map.Po +include ./$(DEPDIR)/tick.Po +include ./$(DEPDIR)/tree.Po +include ./$(DEPDIR)/vehicle.Po +include ./$(DEPDIR)/vmask.Po +include ./$(DEPDIR)/wind.Po +include ./$(DEPDIR)/wq.Po +include ./$(DEPDIR)/ztats.Po +include ./$(DEPDIR)/ztats_arms.Po +include ./$(DEPDIR)/ztats_container_pane.Po +include ./$(DEPDIR)/ztats_items.Po +include ./$(DEPDIR)/ztats_misc.Po +include ./$(DEPDIR)/ztats_pane.Po +include ./$(DEPDIR)/ztats_pm.Po +include ./$(DEPDIR)/ztats_reagents.Po +include ./$(DEPDIR)/ztats_spells.Po + +.c.o: + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c $< + +.c.obj: + $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` + $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) \ +# $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.cpp.o: + $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< + $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: + $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` + $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +# source='$<' object='$@' libtool=no \ +# DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) \ +# $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-binPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..44ea19e --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,185 @@ +AM_CXXFLAGS = -Wall -DDATADIR=\"@datadir@\" -DPREFIX=\"@prefix@\" +AM_CFLAGS = ${AM_CXXFLAGS} + +bin_PROGRAMS = nazghul + +#nazghul_SOURCES = $(wildcard *.c) $(wildcard *.cpp) $(wildcard *.h) + +nazghul_SOURCES = \ + angband.c \ + Arms.cpp \ + Arms.h \ + ascii.c \ + ascii.h \ + astar.c \ + astar.h \ + character.cpp \ + character.h \ + cmdwin.c \ + cmdwin.h \ + combat.c \ + combat.h \ + common.c \ + common.h \ + console.c \ + console.h \ + constants.h \ + Container.cpp \ + Container.h \ + cursor.cpp \ + cursor.h \ + debug.h \ + debug.c \ + dup_constants.h \ + event.c \ + event.h \ + Field.h \ + Field.cpp \ + floodfill.c \ + foogod.c \ + foogod.h \ + formation.h \ + formation.c \ + hash.c \ + hash.h \ + heap.c \ + heap.h \ + images.c \ + images.h \ + knapsack.c \ + knapsack.h \ + list.h \ + los.c \ + los.h \ + Makefile \ + map.c \ + map.h \ + nazghul.h \ + nazghul.c \ + Party.cpp \ + Party.h \ + object.c \ + object.h \ + occ.c \ + occ.h \ + olist.c \ + olist.h \ + pinfo.h \ + place.c \ + place.h \ + play.c \ + player.cpp \ + player.h \ + play.h \ + Reagent.cpp \ + Reagent.h \ + sched.c \ + sched.h \ + screen.c \ + screen.h \ + sky.c \ + sky.h \ + sound.c \ + sound.h \ + species.c \ + species.h \ + sprite.c \ + sprite.h \ + status.c \ + status.h \ + terrain.c \ + terrain.h \ + terrain_map.c \ + terrain_map.h \ + tree.c \ + tree.h \ + vehicle.cpp \ + vehicle.h \ + wind.c \ + wind.h \ + wq.c \ + wq.h \ + Missile.cpp \ + Missile.h \ + cmd.c \ + cmd.h \ + clock.c \ + clock.h \ + vmask.h \ + vmask.c \ + ctrl.h \ + ctrl.c \ + scheme.c \ + scheme.h \ + scheme-private.h \ + opdefines.h \ + macros.h \ + session.c \ + session.h \ + closure.h \ + closure.c \ + kern.h \ + kern.c \ + dice.h \ + dice.c \ + gob.c \ + gob.h \ + magic.h \ + magic.c \ + effect.h \ + effect.c \ + conv.h \ + conv.c \ + ptable.c \ + ptable.h \ + mmode.c \ + mmode.h \ + log.h \ + log.c \ + dtable.h \ + dtable.c \ + Being.h \ + Being.cpp \ + factions.h \ + result.h \ + node.h \ + node.c \ + tick.h \ + tick.c \ + blender.h \ + dimensions.h dimensions.c \ + cfg.h cfg.c \ + menus.h menus.c \ + file.h file.c \ + screen_dims.h \ + skill.h skill.c \ + skill_set.h skill_set.c \ + skill_set_entry.h skill_set_entry.c \ + repstr.h repstr.c \ + templ.h templ.c \ + objectfreezer.h objectfreezer.c \ + kern_intvar.c kern_intvar.h \ + ztats.h ztats.c \ + ztats_pane.h ztats_pane.c \ + ztats_pm.h ztats_pm.c \ + ztats_container_pane.h ztats_container_pane.c \ + ztats_arms.h ztats_arms.c \ + ztats_reagents.h ztats_reagents.c \ + ztats_spells.h ztats_spells.c \ + ztats_items.h ztats_items.c \ + ztats_misc.h ztats_misc.c \ + applet.h \ + session_hooks.h \ + session_queries.h \ + bitset.h \ + escape.c escape.h \ + terrain_editor.c terrain_editor.h + +INCLUDES = -I$(includedir) \ + -I$(srcdir) -I$(top_srcdir)/include -I$(top_srcdir) \ + -I$(top_builddir) -I$(top_builddir)/include -I. + +LIBS = @LIBS@ + +MAINTAINERCLEANFILES = Makefile.in + diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..1312e14 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,786 @@ +# Makefile.in generated by automake 1.11.1 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, +# Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +target_triplet = @target@ +bin_PROGRAMS = nazghul$(EXEEXT) +subdir = src +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/acinclude.m4 \ + $(top_srcdir)/m4/sdl.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" +PROGRAMS = $(bin_PROGRAMS) +am_nazghul_OBJECTS = angband.$(OBJEXT) Arms.$(OBJEXT) ascii.$(OBJEXT) \ + astar.$(OBJEXT) character.$(OBJEXT) cmdwin.$(OBJEXT) \ + combat.$(OBJEXT) common.$(OBJEXT) console.$(OBJEXT) \ + Container.$(OBJEXT) cursor.$(OBJEXT) debug.$(OBJEXT) \ + event.$(OBJEXT) Field.$(OBJEXT) floodfill.$(OBJEXT) \ + foogod.$(OBJEXT) formation.$(OBJEXT) hash.$(OBJEXT) \ + heap.$(OBJEXT) images.$(OBJEXT) knapsack.$(OBJEXT) \ + los.$(OBJEXT) map.$(OBJEXT) nazghul.$(OBJEXT) Party.$(OBJEXT) \ + object.$(OBJEXT) occ.$(OBJEXT) olist.$(OBJEXT) place.$(OBJEXT) \ + play.$(OBJEXT) player.$(OBJEXT) Reagent.$(OBJEXT) \ + sched.$(OBJEXT) screen.$(OBJEXT) sky.$(OBJEXT) sound.$(OBJEXT) \ + species.$(OBJEXT) sprite.$(OBJEXT) status.$(OBJEXT) \ + terrain.$(OBJEXT) terrain_map.$(OBJEXT) tree.$(OBJEXT) \ + vehicle.$(OBJEXT) wind.$(OBJEXT) wq.$(OBJEXT) \ + Missile.$(OBJEXT) cmd.$(OBJEXT) clock.$(OBJEXT) \ + vmask.$(OBJEXT) ctrl.$(OBJEXT) scheme.$(OBJEXT) \ + session.$(OBJEXT) closure.$(OBJEXT) kern.$(OBJEXT) \ + dice.$(OBJEXT) gob.$(OBJEXT) magic.$(OBJEXT) effect.$(OBJEXT) \ + conv.$(OBJEXT) ptable.$(OBJEXT) mmode.$(OBJEXT) log.$(OBJEXT) \ + dtable.$(OBJEXT) Being.$(OBJEXT) node.$(OBJEXT) tick.$(OBJEXT) \ + dimensions.$(OBJEXT) cfg.$(OBJEXT) menus.$(OBJEXT) \ + file.$(OBJEXT) skill.$(OBJEXT) skill_set.$(OBJEXT) \ + skill_set_entry.$(OBJEXT) repstr.$(OBJEXT) templ.$(OBJEXT) \ + objectfreezer.$(OBJEXT) kern_intvar.$(OBJEXT) ztats.$(OBJEXT) \ + ztats_pane.$(OBJEXT) ztats_pm.$(OBJEXT) \ + ztats_container_pane.$(OBJEXT) ztats_arms.$(OBJEXT) \ + ztats_reagents.$(OBJEXT) ztats_spells.$(OBJEXT) \ + ztats_items.$(OBJEXT) ztats_misc.$(OBJEXT) escape.$(OBJEXT) \ + terrain_editor.$(OBJEXT) +nazghul_OBJECTS = $(am_nazghul_OBJECTS) +nazghul_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) +CXXLD = $(CXX) +CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ + -o $@ +SOURCES = $(nazghul_SOURCES) +DIST_SOURCES = $(nazghul_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target = @target@ +target_alias = @target_alias@ +target_cpu = @target_cpu@ +target_os = @target_os@ +target_vendor = @target_vendor@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CXXFLAGS = -Wall -DDATADIR=\"@datadir@\" -DPREFIX=\"@prefix@\" +AM_CFLAGS = ${AM_CXXFLAGS} + +#nazghul_SOURCES = $(wildcard *.c) $(wildcard *.cpp) $(wildcard *.h) +nazghul_SOURCES = \ + angband.c \ + Arms.cpp \ + Arms.h \ + ascii.c \ + ascii.h \ + astar.c \ + astar.h \ + character.cpp \ + character.h \ + cmdwin.c \ + cmdwin.h \ + combat.c \ + combat.h \ + common.c \ + common.h \ + console.c \ + console.h \ + constants.h \ + Container.cpp \ + Container.h \ + cursor.cpp \ + cursor.h \ + debug.h \ + debug.c \ + dup_constants.h \ + event.c \ + event.h \ + Field.h \ + Field.cpp \ + floodfill.c \ + foogod.c \ + foogod.h \ + formation.h \ + formation.c \ + hash.c \ + hash.h \ + heap.c \ + heap.h \ + images.c \ + images.h \ + knapsack.c \ + knapsack.h \ + list.h \ + los.c \ + los.h \ + Makefile \ + map.c \ + map.h \ + nazghul.h \ + nazghul.c \ + Party.cpp \ + Party.h \ + object.c \ + object.h \ + occ.c \ + occ.h \ + olist.c \ + olist.h \ + pinfo.h \ + place.c \ + place.h \ + play.c \ + player.cpp \ + player.h \ + play.h \ + Reagent.cpp \ + Reagent.h \ + sched.c \ + sched.h \ + screen.c \ + screen.h \ + sky.c \ + sky.h \ + sound.c \ + sound.h \ + species.c \ + species.h \ + sprite.c \ + sprite.h \ + status.c \ + status.h \ + terrain.c \ + terrain.h \ + terrain_map.c \ + terrain_map.h \ + tree.c \ + tree.h \ + vehicle.cpp \ + vehicle.h \ + wind.c \ + wind.h \ + wq.c \ + wq.h \ + Missile.cpp \ + Missile.h \ + cmd.c \ + cmd.h \ + clock.c \ + clock.h \ + vmask.h \ + vmask.c \ + ctrl.h \ + ctrl.c \ + scheme.c \ + scheme.h \ + scheme-private.h \ + opdefines.h \ + macros.h \ + session.c \ + session.h \ + closure.h \ + closure.c \ + kern.h \ + kern.c \ + dice.h \ + dice.c \ + gob.c \ + gob.h \ + magic.h \ + magic.c \ + effect.h \ + effect.c \ + conv.h \ + conv.c \ + ptable.c \ + ptable.h \ + mmode.c \ + mmode.h \ + log.h \ + log.c \ + dtable.h \ + dtable.c \ + Being.h \ + Being.cpp \ + factions.h \ + result.h \ + node.h \ + node.c \ + tick.h \ + tick.c \ + blender.h \ + dimensions.h dimensions.c \ + cfg.h cfg.c \ + menus.h menus.c \ + file.h file.c \ + screen_dims.h \ + skill.h skill.c \ + skill_set.h skill_set.c \ + skill_set_entry.h skill_set_entry.c \ + repstr.h repstr.c \ + templ.h templ.c \ + objectfreezer.h objectfreezer.c \ + kern_intvar.c kern_intvar.h \ + ztats.h ztats.c \ + ztats_pane.h ztats_pane.c \ + ztats_pm.h ztats_pm.c \ + ztats_container_pane.h ztats_container_pane.c \ + ztats_arms.h ztats_arms.c \ + ztats_reagents.h ztats_reagents.c \ + ztats_spells.h ztats_spells.c \ + ztats_items.h ztats_items.c \ + ztats_misc.h ztats_misc.c \ + applet.h \ + session_hooks.h \ + session_queries.h \ + bitset.h \ + escape.c escape.h \ + terrain_editor.c terrain_editor.h + +INCLUDES = -I$(includedir) \ + -I$(srcdir) -I$(top_srcdir)/include -I$(top_srcdir) \ + -I$(top_builddir) -I$(top_builddir)/include -I. + +MAINTAINERCLEANFILES = Makefile.in +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .cpp .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(bindir)" && rm -f $$files + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +nazghul$(EXEEXT): $(nazghul_OBJECTS) $(nazghul_DEPENDENCIES) + @rm -f nazghul$(EXEEXT) + $(CXXLINK) $(nazghul_OBJECTS) $(nazghul_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Arms.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Being.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Container.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Field.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Missile.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Party.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Reagent.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/angband.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ascii.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/astar.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cfg.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/character.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clock.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/closure.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmd.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cmdwin.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/combat.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/console.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ctrl.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cursor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/debug.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dice.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dimensions.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dtable.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/effect.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/escape.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/file.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/floodfill.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/foogod.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/formation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gob.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/images.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kern.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kern_intvar.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/knapsack.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/los.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/magic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/menus.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmode.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nazghul.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/node.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/object.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/objectfreezer.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/occ.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/olist.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/place.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/play.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/player.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ptable.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/repstr.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sched.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scheme.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/screen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/session.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skill.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skill_set.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skill_set_entry.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sky.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sound.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/species.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sprite.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/status.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/templ.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/terrain.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/terrain_editor.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/terrain_map.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tick.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tree.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vehicle.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vmask.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wind.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wq.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ztats.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ztats_arms.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ztats_container_pane.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ztats_items.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ztats_misc.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ztats_pane.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ztats_pm.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ztats_reagents.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ztats_spells.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.cpp.o: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< + +.cpp.obj: +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(bindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-binPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ + clean-generic ctags distclean distclean-compile \ + distclean-generic distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-binPROGRAMS \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \ + uninstall-am uninstall-binPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/Missile.cpp b/src/Missile.cpp new file mode 100644 index 0000000..f2d12fa --- /dev/null +++ b/src/Missile.cpp @@ -0,0 +1,194 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "Missile.h" +#include "dice.h" +#include "character.h" +#include "screen.h" +#include "mmode.h" +#include "sprite.h" +#include "map.h" +#include "console.h" +#include "Field.h" +#include "place.h" +#include "player.h" +#include "vehicle.h" +#include "session.h" + +MissileType::MissileType() +{ + // Don't ever expect to call this. Defining it to override the default + // one c++ automatically creates. + assert(false); + + beam = false; +} + +MissileType::MissileType(const char *tag, const char *name, struct sprite *sprite, bool isBeam, bool isFixedRange, struct mmode *mmode) + : ObjectType(tag, name, sprite, item_layer), + beam(isBeam), + fixedrange(isFixedRange) +{ + setMovementMode(mmode); +} + +MissileType::~MissileType() +{ + //dont think theres anything here that needs cleaning up? +} + +bool MissileType::isType(int classID) +{ + if (classID == MISSILE_TYPE_ID) + return true; + return ObjectType::isType(classID); +} + +int MissileType::getType() +{ + return MISSILE_TYPE_ID; +} + +bool MissileType::isBeam() +{ + return beam; +} + +// A fixed range missile always fires to its maximum range (LOS allowing). +// target selection merely affects the angle it travels at +bool MissileType::isFixedRange() +{ + return fixedrange; +} + +void MissileType::fireHitLoc(Object *attacker, Object *target, struct place *place, int x, int y, int dam) +{ + if (canHitLocation()) + hitLocation(NULL, attacker, target, place, x, y, dam); +} + +bool MissileType::fireEnterTile(Missile *missile, struct place *place, int x, int y) +{ + if (closure_exec(gifc, "yppdd", "enter", missile, place, x, y)) + { + return true; + } + else + { + return false; + } +} + +Missile::Missile(MissileType* type) + : Object(type) +{ + +} + +Missile::~Missile() +{ +} + +class MissileType *Missile::getObjectType() +{ + return (class MissileType *) Object::getObjectType(); +} + +/* set hit=true if a party or object has been struck +return true if the missile has not been interupted */ +bool Missile::enterTile(struct place *place, int x, int y) +{ + if (! (flags & MISSILE_IGNORE_LOS)) + { + int obstruction = place_get_movement_cost(place, x, y, this,0); + //int opacity = place_visibility(place, x, y); + return ((obstruction != 20) && (dice_roll_numeric(1,100,0)>obstruction)); + } + + if (! (flags & MISSILE_HIT_PARTY)) + return true; + + struck = place_get_Party(place, x, y); + + if (struck != NULL) { + hit = true; + return false; + } + + // fugly hack... + if (player_party->getPlace() == place && + player_party->getX() == x && + player_party->getY() == y) { + struck = player_party; + hit = true; + return false; + } + + /* Allow wilderness-scale weapons to destroy empty vehicles. */ + struck = place_get_vehicle(place, x, y); + if (struck != NULL) { + hit = true; + return false; + } + + return true; +} + +/* + triggers a hit-loc ifc event if appropriate +*/ +void Missile::fireHitLoc(Object *attacker, Object *target, struct place *place, int x, int y, int dam) +{ + if (getObjectType()->canHitLocation()) + getObjectType()->hitLocation(this, attacker, target, place, x, y, dam); +} + +/* + Calculates & animates trajectory, returns true if the missile reached the target location + alters Bx, By to be where it reached (so you can tell where it wound up if blocked) +*/ +void Missile::animate(int Ax, int Ay, int *Bx, int *By, int _flags, float fixedrange) +{ + int origBx = *Bx; + int origBy = *By; + + hit = false; + struck = NULL; + flags = _flags; + + struct sprite *tmpSprite = sprite_clone(getSprite(), 0); + mapAnimateProjectile(Ax, Ay, Bx, By, tmpSprite, getPlace(), this, fixedrange); + sprite_del(tmpSprite); + + hit = (hit || (origBx == *Bx && origBy == *By)); +} + +bool Missile::hitTarget() +{ + return hit; +} + +class Object * Missile::getStruck() +{ + return struck; +} + diff --git a/src/Missile.h b/src/Missile.h new file mode 100644 index 0000000..fc0cbe0 --- /dev/null +++ b/src/Missile.h @@ -0,0 +1,70 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef Missile_h +#define Missile_h + +#include "object.h" +#include "Arms.h" + +#define MISSILE_IGNORE_LOS (1 << 0) +#define MISSILE_HIT_PARTY (1 << 1) + +class MissileType:public ObjectType +{ + public: + MissileType(); + MissileType(const char *tag, const char *name, struct sprite *sprite, bool isBeam, bool isFixedRange, struct mmode *mmode); + virtual ~ MissileType(); + + virtual bool isType(int classID); + virtual int getType(); + + virtual bool isBeam(); + virtual bool isFixedRange(); + virtual void fireHitLoc(Object *attacker, Object *target, struct place *place, int x, int y, int dam); + virtual bool fireEnterTile(Missile* missile, struct place *place, int x, int y); + + protected: + bool beam; + bool fixedrange; +}; + +class Missile:public Object +{ + public: + Missile(MissileType*); + virtual ~Missile(); + + virtual class MissileType *getObjectType(); + virtual void animate(int Ax, int Ay, int *Bx, int *By, int flags, float fixedrange); + virtual void fireHitLoc(Object *attacker, Object *target, struct place *place, int x, int y, int dam); + virtual bool hitTarget(); + virtual class Object *getStruck(); + virtual bool enterTile(struct place *place, int x, int y); + + protected: + bool hit; + class Object *struck; + int flags; +}; + +#endif diff --git a/src/Party.cpp b/src/Party.cpp new file mode 100644 index 0000000..56614c1 --- /dev/null +++ b/src/Party.cpp @@ -0,0 +1,1156 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "Party.h" +#include "dice.h" +#include "place.h" +#include "player.h" +#include "combat.h" +#include "species.h" +#include "occ.h" +#include "wind.h" +#include "vehicle.h" +#include "console.h" +#include "formation.h" +#include "ctrl.h" +#include "session.h" +#include "sched.h" +#include "log.h" +#include "event.h" +#include "cmd.h" +#include "cmdwin.h" +#include "factions.h" +#include "sprite.h" + +#include + +#define DIRLOC(dir,place,coord) { \ + if ((dir) < 0) \ + (coord) = place_w((place)) - 1; \ + else if (! (dir)) \ + (coord) = place_w((place)) / 2; \ + else \ + (coord) = 0; \ +} + +// Convenience macro for iterating over party members: +#define FOR_EACH_MEMBER(e,c) \ + for ((e) = node_next(&members), (c) = (class Character *)(e)->ptr; \ + (e) != &members; \ + (e) = node_next(e), (c) = (class Character *)(e)->ptr) + + +Party::Party() + : vehicle(NULL) + , size(0) + , formation(NULL) + , wandering(false) + , ctrl(ctrl_party_ai) +{ + node_init(&members); + memset(&pinfo, 0, sizeof(pinfo)); +} + +static bool party_remove_member(class Character *ch, void *data) +{ + ((Party*)data)->removeMember(ch); + return false; +} + +Party::~Party() +{ + /* Dereference all the members by removing them from the party. If no + * other container references them then they will be automatically + * destoyed. */ + forEachMember(party_remove_member, this); + obj_dec_ref_safe(vehicle); +} + +bool Party::isType(int classID) +{ + return (classID == PARTY_ID); + return true; + return Object::isType(classID); +} + +int Party::getType() +{ + return PARTY_ID; +} + +int Party::getVisionRadius() +{ + int maxVal=0; + struct node *entry; + class Character *member; + + FOR_EACH_MEMBER(entry, member) { + if (!member->isDead()) { + int val = member->getVisionRadius(); + maxVal = max(val, maxVal); + } + } + + return maxVal; +} + +int Party::getSize(void) +{ + return size; +} + + +bool Party::turn_vehicle(void) +{ + int cost = 0; + + // Three possible outcomes: + // + // 1. We do NOT turn any vehicle, therefore we want to continue + // processing the move() command which calls us and we do NOT want to + // consume any turns (e.g., no vehicle, or horse turning north/south). + // + // 2. We DO turn a vehicle, but it does not cost us anything (e.g., + // horse turning east/west). + // + // 3. We do turn a vehicle and it cost us a turn (e.g., ship). + + if (!vehicle || !vehicle->turn(dx, dy, &cost) || !vehicle->mustTurn()) + return false; + + action_points -= cost; + + return true; +} + +bool Party::attackPlayer(int dx, int dy) +{ + // Subtle: check if the player party is on the map. This + // catches the case where the player has just engaged another + // npc party in combat on this turn. I don't want this npc + // party to move to that spot because then when the player + // party exits combat they will be on top of this npc party. + if (! player_party->isOnMap()) + return false; + + struct move_info info; + struct combat_info cinfo; + + memset(&info, 0, sizeof(info)); + + + /* Check for a diagonal attack. */ + if (dx && dy) + { + int xgoodness=0; + int ygoodness=0; + if (place_is_passable(getPlace(), getX() + dx, getY(), + this, 0)) + { + if (place_is_hazardous(getPlace(), getX() + dx, getY())) + { + xgoodness=1; + } + else + { + xgoodness=2; + } + } + if ((xgoodness<2) && place_is_passable(getPlace(), getX(), getY() + dy, + this, 0)) + { + if (place_is_hazardous(getPlace(), getX() + dx, getY())) + { + ygoodness=1; + } + else + { + ygoodness=2; + } + } + if (xgoodness && xgoodness > ygoodness) + { + //changing x is better + info.x = getX() + dx; + info.y = getY(); + info.dx = 0; + info.dy = dy; + } + else if (ygoodness) + { + //changing y is better + info.x = getX(); + info.y = getY() + dy; + info.dy = 0; + info.dx = dx; + } + else + { + //cant actually get there! + return false; + } + } + else + { + info.x = getX(); + info.y = getY(); + info.dx = dx; + info.dy = dy; + } + + info.place = getPlace(); + info.px = player_party->getX(); + info.py = player_party->getY(); + info.npc_party = this; + + memset(&cinfo, 0, sizeof(cinfo)); + cinfo.defend = true; + cinfo.move = &info; + + combat_enter(&cinfo); + endTurn(); + return true; +} + +MoveResult Party::move(int dx, int dy) +{ + struct place *newplace; + int newx; + int newy; + struct place *oldplace; + int oldx; + int oldy; + class Object *mech; + + this->dx = dx; + this->dy = dy; + + /* Check if the party is in a vehicle that must turn its facing before + * moving */ + if (turn_vehicle()) + return ChangedFacing; + + /* Remember old (current) coordinates */ + oldplace = getPlace(); + oldx = getX(); + oldy = getY(); + + /* Setup new coordinates */ + newx = place_wrap_x(oldplace, oldx + dx); + newy = place_wrap_y(oldplace, oldy + dy); + newplace = oldplace; + + /* Walking off the edge of a map */ + if (place_off_map(oldplace, newx, newy)) { + return OffMap; + } + + /* Check if the player is there. */ + if (newx == player_party->getX() && + newy == player_party->getY()) { + + /* If this party is hostile to the player then begin combat */ + if (are_hostile(this, player_party) + && attackPlayer(dx, dy)) { + return EngagedEnemy; + + } + + return WasOccupied; + } + + /* Check if another entity is already there */ + if (place_is_occupied(oldplace, newx, newy)) { + return WasOccupied; + } + + /* Check for a vehicle. */ + class Vehicle *veh = place_get_vehicle(newplace, newx, newy); + if (veh && (vehicle || veh->getOccupant())) { + return WasOccupied; + } + + /* Check passability */ + if (!place_is_passable(oldplace, newx, newy, this, + PFLAG_MOVEATTEMPT)) { + return WasImpassable; + } + + /* When wandering, don't wander over terrain hazards. When pathfinding, + * assume that braving the hazard is the best course. */ + if (wandering && place_is_hazardous(newplace, newx, newy)) + return AvoidedHazard; + + + // Check for a mech (not for passability, for sending the STEP + // signal) + + mech = place_get_object(getPlace(), newx, newy, mech_layer); + if (mech) { + // Bugfix 1411788: avoid step triggers; dungeon step triggers + // are relocating the NPC party into non-wilderness places, + // corrupting them (note: the code here used to call + // mech->step(this), not only did this invoke the step but it + // was redundant, because the relocate() call checks for step + // trigger mechs) + return AvoidedHazard; + } + + relocate(newplace, newx, newy); + + action_points -= place_get_diagonal_movement_cost(getPlace(), oldx, oldy, getX(), getY(), this,0); + + return MovedOk; +} + +bool Party::gotoSpot(int mx, int my) +{ + // Common routine used by work() and commute(). + struct astar_node *path; + struct astar_node *next; + struct astar_search_info as_info; + int dx; + int dy; + enum MoveResult ret = NotApplicable; + + if (isStationary()) + return StationaryObject; + + /* Look for a path. */ + memset(&as_info, 0, sizeof(as_info)); + as_info.x0 = getX(); + as_info.y0 = getY(); + as_info.x1 = mx; + as_info.y1 = my; + as_info.flags = PFLAG_IGNOREMECHS; + path = place_find_path(Place, &as_info, this); + + if (!path) + return false; + + //dump_path(path); + + /* The first node in the path is the starting location. Get the next + * step. */ + next = path->next; + if (next) { + + /* Get the movement vector */ + dx = next->x - getX(); + dy = next->y - getY(); + + /* Attempt to move */ + ret = move(dx, dy); + + } + + /* Cleanup */ + astar_path_destroy(path); + + return (ret == MovedOk || ret == EngagedEnemy); +} + +bool Party::attack_with_ordnance(int d) +{ + class ArmsType *ordnance; + int dx, dy; + bool ret; + + if (!vehicle || !(ordnance = vehicle->getOrdnance())) + return false; + + // Check if the player is in range. + if (d > ordnance->getRange()) { + return false; + } + // Get the normalized vector to the player. + place_get_direction_vector(getPlace(), + getX(), getY(), + player_party->getX(), player_party->getY(), + &dx, &dy); + clamp(dx, -1, 1); + clamp(dy, -1, 1); + + // Check if the player is on a major axes (assumes we must fire in a + // straight line -- always true for now). + if (player_party->getY() == getY()) { + + // If necessary, turn the vehicle to broadside the player (this + // assumes we must use a broadside, again always true for now). + // If we do turn return true to end this turn. + if (vehicle->getFacing() != NORTH && + vehicle->getFacing() != SOUTH) { + int cost; + vehicle->turn(0, 1, &cost); + action_points -= cost; + return true; + } + + ret = vehicle->fire_weapon(dx, dy, this); + assert(ret); // to remind me if I change some assumptions + return true; + } + // Ditto but for the other axis. + if (player_party->getX() == getX()) { + if (vehicle->getFacing() != EAST && + vehicle->getFacing() != WEST) { + int cost; + vehicle->turn(1, 0, &cost); + return true; + } + ret = vehicle->fire_weapon(dx, dy, this); + assert(ret); // to remind me if I change some assumptions + return true; + } + // In range but no lined up on an axis. For now just return and let out + // strategy be to close with the player's ship. In future I might want + // to try and go to find and move toward the nearest axis point. + return false; +} + + +void Party::exec() +{ + assert(!isDestroyed()); + + startTurn(); + + while (action_points > 0 && !isDestroyed()) { + + int initial_points = action_points; + ctrl(this); + /* If we didn't use any action points then we're idle and need + * to break to prevent an endless loop. */ + if (action_points == initial_points) + break; + } + + endTurn(); + Object::decrementTTL(this); // might destroy this! +} + + +void Party::forEachMember(bool (*fx) (class Character *, void *), void *data) +{ + struct node *elem; + + elem = node_next(&members); + while (elem != &members) { + class Character *c; + + c = (class Character *)elem->ptr; + elem = node_next(elem); + + if (fx(c, data)) + return; + } +} + + +void Party::forEachReverseMember(bool (*fx) (class Character *, void *), void *data) +{ + struct node *elem; + + elem = node_prev(&members); + while (elem != &members) { + class Character *c; + + c = (class Character *)elem->ptr; + elem = node_prev(elem); + + if (fx(c, data)) + return; + } +} + +static bool party_destroy_and_remove_member(class Character * c, void *data) +{ + class Party *party = (class Party *) data; + + c->destroy(); + party->removeMember(c); + + return false; +} + +void Party::destroy() +{ + // Note: this is a case of destroying an object in a container: + disembark(); + + forEachMember(party_destroy_and_remove_member, this); + assert(node_list_empty(&members)); + Object::destroy(); // removes it +} + +void Party::removeMember(class Character * c) +{ + struct node *node; + + /* Convenienve pointer to node */ + node = c->plnode; + + /* Should be valid */ + assert(node); + + /* Unlink the node from the member list */ + node_remove(node); + + /* Break the link from the char back to the node */ + c->plnode = NULL; + + /* Break the link from the char back to the party */ + c->party = NULL; + + /* Reduce party size counter */ + size--; + + /* Release the node */ + node_unref(node); + + /* Release the char */ + obj_dec_ref(c); +} + +bool Party::addMember(class Character * c) +{ + struct node *node; + + /* Add ref to char to prevent destruction */ + obj_inc_ref(c); + + /* Make a new list node for the member list */ + node = node_new(c); + + /* Link the new member in at the END of the list (otherwise, in the + * case of the player party, the order shown in status gets screwed + * up) */ + node_add_tail(&members, node); + + /* Point the member back to its node (for fast removal) */ + c->plnode = node; + + /* Point the member back to its party */ + c->party = this; + + /* Set the character's order in the party */ + c->setOrder(size); + + /* Increase the party size counter */ + size++; + + /* Make the member loyal to the party */ + c->setBaseFaction(getBaseFaction()); + + return true; +} + +static bool add_to_player_party(class Character * c, void *data) +{ + // Note: I'll leave the party set as-is. It does no harm and might do + // some good later. Note: The order will be forgotten (changed to + // match player party order). + + if (!c->joinPlayer()) + assert(false); + return false; +} + +bool Party::joinPlayer(void) +{ + remove(); + forEachMember(add_to_player_party, 0); + return true; +} + +void Party::paint(int sx, int sy) +{ + if (vehicle) + vehicle->paint(sx, sy); + else + Object::paint(sx, sy); +} + +struct sprite *Party::getSprite() +{ + if (vehicle) + return vehicle->getSprite(); + + return Object::getSprite(); +} + +void Party::disembark() +{ + if (vehicle) { + assert(getPlace()); + vehicle->setOccupant(0); + if (!vehicle->isDestroyed()) { + vehicle->relocate(getPlace(), getX(), getY()); + } + obj_dec_ref(vehicle); + vehicle = NULL; + } +} + + +int Party::getSpeed() +{ + if (vehicle) + return vehicle->getSpeed(); + + int minVal=255; // something big, whatever + struct node *entry; + class Character *member; + + FOR_EACH_MEMBER(entry, member) { + if (!member->isDead()) { + int val = member->getSpeed(); + minVal = min(val, minVal); + } + } + + return minVal; + +} + +struct damage_member_info { + int damage; + bool any_alive; +}; + +static bool damage_member(class Character * member, void *data) +{ + struct damage_member_info *dm_info = (struct damage_member_info *) data; + + // apply damage + member->damage(dm_info->damage); + + // check if dead and remove from party + if (member->isDead()) { + member->party->removeMember(member); + return false; + } + // otherwise at least one still alive + dm_info->any_alive = true; + + return false; +} + +void Party::damage(int damage) +{ + struct damage_member_info dm_info; + + Object::damage(damage); + + // First apply damage to the vehicle. If the vehicle is destroyed then + // destroy the party, too. + if (vehicle) { + vehicle->damage(damage); + + // If the vehicle was destroyed by the above damage, it has + // already called destroy() on its occupants (that's us right + // here!) and we've already disembarked. So there's really + // nothing to do. + return; + + } + + // Apply damage to all party members. If they all die then the party is + // destroyed, too. + dm_info.damage = damage; + dm_info.any_alive = false; + forEachMember(damage_member, &dm_info); + if (!dm_info.any_alive) { + destroy(); + } +} + +void Party::distributeMembers() +{ + // ------------------------------------------------------------------- + // Emulate what I currently do for the player party. + // ------------------------------------------------------------------- + + // ------------------------------------------------------------------- + // The combat alg requires me to fill out a "position info" structure + // based on the player party destination. + // ------------------------------------------------------------------- + + combat_fill_position_info(&pinfo, getPlace(), getX(), getY(), dx, dy, false); + + // ------------------------------------------------------------------- + // Set the party formation to a sane default. + // ------------------------------------------------------------------- + + if (NULL == pinfo.formation) + pinfo.formation = formation_get_default(); + + // ------------------------------------------------------------------- + // Party members must be placed such that they can pathfind back to the + // party. This minimizes the chance of a party member getting stranded + // (which in turn will strand the whole party in that place). + // ------------------------------------------------------------------- + + pinfo.find_party = true; + + // ------------------------------------------------------------------- + // Remove the party from the current place before distributing members. + // ------------------------------------------------------------------- + + remove(); + mapSetDirty(); + + // ------------------------------------------------------------------- + // Use the combat algorithm to place each member. Currently this will + // never fail, in the degenerate case all party members will end up + // "stranded" on top of the destination tile. + // ------------------------------------------------------------------- + + forEachMember(combat_place_character, &pinfo); + +} + +struct formation *Party::get_formation() +{ + if (vehicle && vehicle->get_formation()) + return vehicle->get_formation(); + return formation; +} + +void Party::describe() +{ + assert(Session->subject); + const char *diplstr = diplomacy_string(this, Session->subject); + if (isvowel(diplstr[0])) + log_continue("an "); + else + log_continue("a "); + + log_continue("%s %s", diplstr, getName()); + + if (vehicle) { + log_continue(" in "); + vehicle->describe(); + } +} + +static bool member_examine(class Character *member, void *data) +{ + log_begin(""); + member->examine(); + log_end(""); + return false; +} + +void Party::examine() +{ + describe(); + log_end(":"); + forEachMember(member_examine, this); + log_begin(""); + //todo: more details? +} + + +static bool get_member_movement_sound(class Character * member, void *data) +{ + sound_t **sound = (sound_t **)data; + *sound = member->get_movement_sound(); + return data != 0; +} + + +sound_t *Party::get_movement_sound() +{ + sound_t *sound = NULL_SOUND; + + if (vehicle) + return vehicle->get_movement_sound(); + forEachMember(get_member_movement_sound, &sound); + return sound; +} + +static bool member_burn(class Character *member, void *data) +{ + member->burn(); + return false; +} + +static bool member_sleep(class Character *member, void *data) +{ + member->sleep(); + return false; +} + +void Party::burn() +{ + forEachMember(member_burn, NULL); + if (allDead()) + destroy(); +} + +void Party::sleep() +{ + forEachMember(member_sleep, NULL); + if (allDead()) + destroy(); +} + +static bool member_check_if_alive(class Character *member, void *data) +{ + if (!member->isDead()) { + *((bool*)data) = false; + return true; + } + return false; +} + +bool Party::allDead() +{ + bool dead = true; + forEachMember(member_check_if_alive, &dead); + return dead; +} + +void Party::switchOrder(class Character *ch1, class Character *ch2) +{ + int tmp; + node_switch(ch1->plnode, ch2->plnode); + tmp = ch1->getOrder(); + ch1->setOrder(ch2->getOrder()); + ch2->setOrder(tmp); +} + +void Party::setPlace(struct place *place) +{ + struct node *entry; + class Character *member; + Object::setPlace(place); + if (this!=player_party + && !place_is_wilderness(place)) { + warn("putting %s in non-wilderness %s\n", + getName(), place->name); + assert(0); + } + FOR_EACH_MEMBER(entry, member) { + member->setPlace(place); + } +} + +void Party::setX(int x) +{ + struct node *entry; + class Character *member; + Object::setX(x); + FOR_EACH_MEMBER(entry, member) { + member->setX(x); + } +} + +void Party::setY(int y) +{ + struct node *entry; + class Character *member; + Object::setY(y); + FOR_EACH_MEMBER(entry, member) { + member->setY(y); + } +} + +bool Party::addEffect(struct effect *effect, struct gob *gob) +{ + struct node *entry; + class Character *member; + bool result = false; + + // NOTE: in the future we'll probably want to distinguish between + // start-of-char-turn and start-of-party-turn for characters. Also, + // we'll want to specify if the hook should really apply to the party + // object or to its members. + FOR_EACH_MEMBER(entry, member) + result = member->addEffect(effect, gob) || result; + + return result; +} + +bool Party::removeEffect(struct effect *effect) +{ + struct node *entry; + class Character *member; + bool result = false; + + FOR_EACH_MEMBER(entry, member) { + result = member->removeEffect(effect) || result; + } + + return result; +} + +void Party::startTurn() +{ + struct node *entry; + class Character *member; + + Object::startTurn(); + if (isDestroyed()) + return; + + // NOTE: in the future we'll probably want to distinguish between + // start-of-char-turn and start-of-party-turn for characters. Also, to + // be authentic we really should iterate over this in proportion to the + // map scale. + FOR_EACH_MEMBER(entry, member) + member->runHook(OBJ_HOOK_START_OF_TURN, 0); + + if (allDead()) + destroy(); + +} + +void Party::applyEffect(closure_t *effect) +{ + struct node *entry; + class Character *member; + + FOR_EACH_MEMBER(entry, member) + member->applyEffect(effect); +} + +void Party::save(struct save *save) +{ + struct node *entry; + class Character *member; + + save->enter(save, "(let ((kparty (kern-mk-party)))\n"); + if (getName()) + save->write(save, "(kern-being-set-name kparty \"%s\")\n", getName()); + save->write(save, "(kern-obj-set-sprite kparty %s)\n", + sprite_get_tag(getSprite())); + save->write(save, "(kern-being-set-base-faction kparty %d)\n", getBaseFaction()); + if (vehicle) { + save->enter(save, "(kern-party-set-vehicle kparty"); + vehicle->save(save); + save->exit(save, ") ;; end kern-party-set-vehicle\n"); + } + FOR_EACH_MEMBER(entry, member) { + save->enter(save, "(kern-party-add-member kparty\n"); + member->save(save); + save->exit(save, ") ;; end kern-party-add-member\n"); + } + if (getTTL() != -1) { + save->write(save, "(kern-obj-set-ttl kparty %d)\n", getTTL()); + } + save->write(save, "kparty\n"); + save->exit(save, ") ;; end let\n"); +} + +static bool member_remove(class Character *member, void *data) +{ + member->remove(); + return false; +} + +void Party::removeMembers() +{ + forEachMember(member_remove, NULL); +} + +static bool memberStart(class Character *member, void *data) +{ + member->start(); + return false; +} + +void Party::start() +{ + forEachMember(memberStart, NULL); +} + +int Party::getMovementCost(int pclass) +{ + struct node *entry; + class Character *member; + int maxCost = 0; + + if (vehicle) + return vehicle->getMovementCost(pclass); + + FOR_EACH_MEMBER(entry, member) { + if (!member->isDead()) { + int cost = member->getMovementCost(pclass); + maxCost = max(cost, maxCost); + } + } + + return maxCost; +} + +bool Party::isStationary() +{ + struct node *entry; + class Character *member; + + FOR_EACH_MEMBER(entry, member) { + if (!member->isDead()) { + if (member->isStationary()) + return true; + } + } + + return false; +} + +class Character *Party::getMemberByOrder(int order) +{ + struct node *entry; + class Character *member; + + FOR_EACH_MEMBER(entry, member) { + if (! order) + return member; + order--; + } + + return NULL; +} + +Object *Party::getSpeaker() +{ + struct node *entry; + class Character *member; + struct stat_list_entry *statlist; + int list_sz = 0; + class Character *selected = NULL; + enum StatusMode orig_stat_mode; + struct KeyHandler kh; + struct ScrollerContext sc; + + // Allocate an array of status list entries big enough for the entire + // party (this is probably more than we need, but it's only temporary). + statlist = (struct stat_list_entry*) + calloc(getSize(), sizeof(struct stat_list_entry)); + assert(statlist); + + + // For each party member that has a conversation, add it to the list. + FOR_EACH_MEMBER(entry, member) { + + // Fix for crasher: 'conv' is a member of this object, so don't use + // it as a temp variable! + if (!member->getConversation()) { + continue; + } + + statlist[list_sz].sprite = member->getSprite(); + snprintf(statlist[list_sz].line1, STAT_LIST_CHARS_PER_LINE, + member->getName()); + statlist[list_sz].data = member; + list_sz++; + } + + // Remember the current stat mode so we can restore it. + orig_stat_mode = statusGetMode(); + + // Check if nobody has a conversation. + if (! list_sz) + goto done; + + // Check if only one has a conversation. + if (list_sz == 1) { + selected = (class Character*)statlist[0].data; + goto done; + } + + // The player has to choose. Poke the list into the status state. + statusSetGenericList("Choose Speaker", list_sz, statlist); + + // Switch the status mode over to list selection. + statusSetMode(GenericList); + + // Setup a keyhandler for handling the scrolling + sc.selector = Generic; + sc.selection = NULL; + kh.fx = scroller; + kh.data = ≻ + + // Push the handler and wait for the player to make a selection. + eventPushKeyHandler(&kh); + cmdwin_spush(""); + eventHandle(); + cmdwin_pop(); + eventPopKeyHandler(); + + foogodSetMode(FOOGOD_DEFAULT); + + ie = (struct inv_entry *) sc.selection; + if (ie == NULL) { + cmdwin_push("none!"); + return NULL; + } + + cmdwin_spush(ie->type->getName()); + + return ie; +} + +class Character *select_party_member(void) +{ + enum StatusMode omode; + class Character *character; + + if (1 == player_party->getSize()) { + character = player_party->getMemberByOrder(0); + /* fixme: move to cmd_front_end? */ + cmdwin_spush("%s", character->getName()); + return character; + } + + foogodSetHintText(SCROLLER_HINT); + foogodSetMode(FOOGOD_HINT); + omode = statusGetMode(); + statusSetMode(SelectCharacter); + + struct KeyHandler kh; + struct ScrollerContext sc; + sc.selector = Character; + sc.selection = NULL; + kh.fx = scroller; + kh.data = ≻ + + eventPushKeyHandler(&kh); + cmdwin_push(""); + + statlist[0].sprite = mech->getSprite(); + snprintf(statlist[0].line1, sizeof(statlist[0].line1), "%s", + mech->getName()); + statlist[0].line2[0] = 0; + statlist[0].data = mech; + + statlist[1].sprite = container->getSprite(); + snprintf(statlist[1].line1, sizeof(statlist[1].line2), "%s", + container->getName()); + statlist[1].line2[0] = 0; + statlist[1].data = container; + + foogodSetHintText(SCROLLER_HINT); + foogodSetMode(FOOGOD_HINT); + omode = statusGetMode(); + statusSetGenericList("Choose Target", 2, statlist); + statusSetMode(GenericList); + + data.selection = NULL; + data.selector = Generic; + kh.fx = scroller; + kh.data = &data; + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + + statusSetMode(omode); + foogodSetMode(FOOGOD_DEFAULT); + + /* Disqualify the object NOT selected */ + if (data.selection == mech) + container = NULL; + else + mech = NULL; + + cmdwin_pop(); + } + + /* Open a mechanism */ + if (mech && mech->getObjectType()->canOpen()) { + cmdwin_push("%s!", mech->getName()); + mech->getObjectType()->open(mech, pc); + mapSetDirty(); + pc->runHook(OBJ_HOOK_OPEN_DONE, "p", mech); + pc->decActionPoints(kern_intvar_get("AP_COST:open_mechanism")); + return true; + } + + /* Nothing to open */ + if (NULL == container) { + cmdwin_push("abort!"); + log_msg("Open - nothing there!"); + return false; + } + + /* Open Container */ + + log_begin_group(); + + pc->runHook(OBJ_HOOK_OPEN_DONE, "p", container); + pc->decActionPoints(kern_intvar_get("AP_COST:open_container")); + cmdwin_push("%s!", container->getName()); + + // Describe the contents of the container. + log_msg("You find:"); + container->forEach(cmd_describe_inv_entry, NULL); + + // Open the container (automagically spills all the contents onto the + // map). + container->open(); + + // -------------------------------------------------------------------- + // Delete container automatically on the combat map because if + // containers are stacked (and they frequently are) then the top one + // always gets selected and the player can't get at the ones + // underneath. On the other hand, in towns I don't want to delete + // people's furniture. + // + // Addendum: everything stated above still holds, but now corpse loot + // can also get dropped on town maps outside, so I can no longer decide + // whether or not to delete a container based on context. Furthermore, + // I want all containers to behave the same way as much as + // possible. This is an open issue and it may take some time and user + // feedback to decide what best to do, so for now I'll simply always + // remove containers after opening them. + // -------------------------------------------------------------------- + + container->remove(); + + log_end_group(); + + mapSetDirty(); + return true; +} + +static bool cmd_nop_qh(struct QuitHandler *kh) +{ + return false; +} + + +bool cmdQuit(void) +{ + int yesno; + struct QuitHandler qh; + + /* Bugfix: if the player tries to close the window while we're in one + * of our getkey() calls, we'll enter this function recursively, + * messing up the prompts. So push a nop quit handler to prevent + * that. Kind of a hack: why should this function "know" it is called + * by the default quit handler? */ + qh.fx = cmd_nop_qh; + eventPushQuitHandler(&qh); + + cmdwin_clear(); + cmdwin_spush("Quit"); + cmdwin_spush(""); + getkey(&yesno, yesnokey); + cmdwin_pop(); + + /* Cancel quit? */ + if (yesno == 'n') { + cmdwin_spush("abort!"); + Quit = false; + goto pop_qh; + } + + cmdwin_spush("save"); + cmdwin_spush(""); + getkey(&yesno, yesnokey); + cmdwin_pop(); + + /* Don't save? */ + if (yesno == 'n') { + cmdwin_spush("not saving!"); + Quit = true; + goto pop_qh; + } + + if (cmdSave()) { + cmdwin_spush("saved!"); + log_msg("Goodbye!\n"); + Quit = true; + } else { + Quit = false; + } + + pop_qh: + eventPopQuitHandler(); + + return Quit; +} + +void cmdAttack(void) +{ + int dir; + struct move_info info; + struct combat_info cinfo; + + // Initialize data structures. + memset(&info, 0, sizeof(info)); + memset(&cinfo, 0, sizeof(cinfo)); + cinfo.move = &info; + cinfo.defend = false; + + // Get the direction + cmdwin_clear(); + cmdwin_spush("Attack"); + cmdwin_spush(""); + getkey(&dir, cardinaldirkey); + cmdwin_pop(); + if (dir == CANCEL) { + cmdwin_spush("none!"); + return; + } + cmdwin_spush("%s", directionToString(dir)); + + // Get the npc party being attacked + info.dx = directionToDx(dir); + info.dy = directionToDy(dir);; + info.place = player_party->getPlace(); + info.x = place_wrap_x(info.place, player_party->getX() + info.dx); + info.y = place_wrap_y(info.place, player_party->getY() + info.dy); + info.npc_party = place_get_Party(info.place, info.x, info.y); + + if (info.npc_party == NULL) { + cmdwin_spush("nobody there!"); + log_msg("Attack - nobody there!"); + return; + } + info.px = player_party->getX(); + info.py = player_party->getY(); + + cmdwin_spush("%s", info.npc_party->getName()); + + // If the npc is not hostile then get player confirmation. + if (! are_hostile(info.npc_party, player_party)) { + int yesno; + cmdwin_spush("attack non-hostile"); + cmdwin_spush(""); + getkey(&yesno, yesnokey); + cmdwin_pop(); + if (yesno == 'n') { + cmdwin_spush("no"); + return; + } + cmdwin_spush("yes"); + + make_hostile(info.npc_party, player_party); + } + + // Log the attack. + log_begin("You attack "); + info.npc_party->describe(); + log_end("."); + + // Enter combat + combat_enter(&cinfo); +} + +void cmdDeveloperEval(struct session *session) +{ + unsigned int len = 1024; + char *buf = (char*)calloc(len, sizeof(char)); + if (!buf) { + log_msg("Eval: not enough memory!"); + return; + } + + cmdwin_clear(); + cmdwin_push("Eval:"); + + if (!ui_getline_filtered(buf, len, NULL)) { + log_msg("Eval: abort"); + cmdwin_push("abort!"); + goto cleanup; + } + + log_msg("Eval: %s", buf); + session_eval(session, buf); + + cleanup: + free(buf); +} + +void cmdFire(void) +{ + int dir; + + cmdwin_clear(); + cmdwin_spush("Fire"); + + class Vehicle *vehicle = player_party->getVehicle(); + if ((!vehicle || + !vehicle->getOrdnance())) { + // SAM: + // In future, we may check for adjacent "cannon" + // mechanisms here (as in U5). + cmdwin_spush("No cannons available!"); + log_msg("Fire - no cannons!"); + return; + } + + cmdwin_spush("%s", vehicle->getOrdnance()->getName()); + cmdwin_spush(""); + getkey(&dir, dirkey); + cmdwin_pop(); + + if (dir == CANCEL) { + cmdwin_spush("none!"); + return; + } + + cmdwin_spush("%s", directionToString(dir)); + if (! vehicle->fire_weapon(directionToDx(dir), + directionToDy(dir), + player_party)) { + cmdwin_spush("Not a broadside!"); + log_msg("Fire - not a broadside!"); + return; + } +} + +bool cmdReady(class Character * member) +{ + bool committed = false; + struct inv_entry *ie; + struct KeyHandler kh; + struct ScrollerContext sc; + const char *msg = 0; + + cmdwin_clear(); + cmdwin_spush("Ready"); + + // Select user + if (member) { + cmdwin_spush("%s", member->getName()); + } else { + member = select_party_member(); + if (member == NULL) + return false; + + if (member->isCharmed()) { + cmdwin_push("Charmed!"); + log_msg("Ready - charmed!"); + return false; + } + + } + + log_begin_group(); + log_msg("%s readies arms:", member->getName()); + + statusSelectCharacter(member->getOrder()); + + player_party->sortReadiedItems(member); + foogodSetHintText(SCROLLER_HINT); + foogodSetMode(FOOGOD_HINT); + statusSetMode(Ready); + sc.selector = InventoryItem; + kh.fx = scroller; + kh.data = ≻ + eventPushKeyHandler(&kh); + + cmdwin_spush(""); + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + cmdwin_pop(); + + trade = (struct trade_info *) sc.selection; + + if (!trade) { + cmdwin_spush("none!"); + break; + } + + /* Print the sales pitch to the console, if one exists */ + if (trade->sales_pitch) { + log_msg("^c+%c%s:^c- %s", CONV_NPC_COLOR, merch->name, + trade->sales_pitch); + } + + cmdwin_spush("%s", trade->name); + + if (player_party->gold < trade->cost) { + int dummy; + cmdwin_spush("not enough gold! "); + getkey(&dummy, anykey); + continue; + } + // *** quantity *** + + cmdwin_push_mark(); + max_q = player_party->gold / trade->cost; + quantity = ui_get_quantity(max_q); + cmdwin_pop_to_mark(); + + if (quantity == 0) { + cmdwin_spush("none!"); + continue; + } + + quantity = min(quantity, max_q); + cmdwin_spush("%d", quantity); + + cost = quantity * trade->cost; + + // *** trade *** + + class ObjectType *type = (class ObjectType*)trade->data; + cmdwin_spush("ok"); + log_msg("You buy %d %s%s for %d gold\n", quantity, + trade->name, quantity > 1 ? "s" : "", cost); + + player_party->gold -= cost; + if (type->canBuy()) { + type->buy(player_party->get_leader(), quantity); + } else { + player_party->add(type, quantity); + } + trade->quantity = player_party->inventory->numAvail(type); + statusRepaint(); + foogodRepaint(); + bought++; + } + + statusSetMode(ShowParty); + return bought; +} + +static bool conv_filter_trade(struct inv_entry *ie, void *fdata) +{ + struct trade_info *trade = (struct trade_info*)fdata; + return (ie->type == trade->data && ie->count > ie->ref); +} + +static int fill_sell_list(struct merchant *merch, struct trade_info *trades) +{ + struct inv_entry *ie = NULL; + struct filter filter; + int i, j = 0; + + filter.fx = conv_filter_trade; + + for (i = 0; i < merch->n_trades; i++) { + + if (merch->trades[i].cost / MARKUP == 0) + continue; + + filter.fdata = &merch->trades[i]; + ie = player_party->inventory->first(&filter); + if (!ie) + continue; + + /* Why don't aren't we setting show_sprite here, too? */ + trades[j] = merch->trades[i]; + trades[j].cost /= MARKUP; + trades[j].quantity = ie->count - ie->ref; + trades[j].show_quantity = 1; + j++; + } + + return j; +} + +int ui_sell(struct merchant *merch) +{ + // A bit trickier than the "Buy" scenario. A merchant will only buy + // items that it is willing to turn around and sell at a profit. When + // it comes time to select an item to sell the user should only see the + // list of items in player inventory which the merchant is willing to + // buy. So here we need to build that list and feed it to the status + // viewer. + + int n_trades = 0; + struct trade_info *trades; + struct KeyHandler kh; + struct ScrollerContext sc; + struct trade_info *trade; + int sold = 0; + + // Allocate the trade list. + trades = new struct trade_info[merch->n_trades]; + if (!trades) { + log_msg("^c+%c%s:^c- I don't need anything.\n", + CONV_NPC_COLOR, merch->name); + return 0; + } + // Fill out the list + n_trades = fill_sell_list(merch, trades); + statusSetTradeInfo(n_trades, trades); + statusSetMode(Trade); + + sc.selector = TradeItem; + kh.fx = scroller; + kh.data = ≻ + + for (;;) { + + struct inv_entry *ie; + int quantity, max_q; + + sc.selection = NULL; + + cmdwin_clear(); + cmdwin_spush("Sell"); + cmdwin_spush(""); + eventHandle(); + cmdwin_pop(); + eventPopKeyHandler(); + + foogodSetMode(FOOGOD_DEFAULT); + return sc.selection; +} + + +/* Do common front-end processing. Migrate all commands to start using this. */ +static class Character *cmd_front_end(class Character *pc, const char *cmdstr) +{ + cmdwin_clear(); + cmdwin_spush(cmdstr); + + /* prompt user? */ + if (!pc) { + + /* only one choice? */ + if (player_party->get_num_living_members() == 1) { + pc = player_party->get_first_living_member(); + cmdwin_spush(pc->getName()); + } else { + pc = select_party_member(); + } + + } else { + cmdwin_spush(pc->getName()); + } + + /* user abort? */ + if (!pc) { + return 0; + } + + /* dead actor? */ + if (pc->isDead()) { + log_msg("%s - %s is too dead!", cmdstr, pc->getName()); + cmdwin_push("can't!"); + return 0; + } + + /* sleeping actor? */ + if (pc->isAsleep()) { + log_msg("%s - %s rolls over and snores!", cmdstr, + pc->getName()); + cmdwin_push("can't!"); + return 0; + } + + /* tell status who the actor is (sometimes it matters) */ + statusSelectCharacter(pc->getOrder()); + + return pc; +} + +static void cmd_add_skill_set(struct node *head, class Character *pc, + struct skill_set *skset) +{ + struct list *elem; + int pclvl = pc->getLevel(); + + /* for each skill in the skill set */ + list_for_each(&skset->skills, elem) { + + struct skill_set_entry *ssent; + struct node *node; + ssent = list_entry(elem, struct skill_set_entry, list); + + /* is it a passive skill? */ + if (ssent->skill->passive) { + continue; + } + + /* is the character is of sufficient level? */ + if (pclvl < ssent->level) { + continue; + } + + /* add it to the list */ + node = node_new(ssent); + node_add_tail(head, node); + } +} + +static void cmd_build_skill_list(struct node *head, class Character *pc) +{ + node_init(head); + + /* add species skills */ + if (pc->species + && pc->species->skills) { + cmd_add_skill_set(head, pc, pc->species->skills); + } + + /* add occupation skills */ + if (pc->occ + && pc->occ->skills) { + cmd_add_skill_set(head, pc, pc->occ->skills); + } + + /* add bonus skills? */ +} + +static int cmd_paint_skill(struct stat_super_generic_data *self, + struct node *node, + SDL_Rect *rect) +{ + struct skill_set_entry *ssent = (struct skill_set_entry *)node->ptr; + struct skill *skill = ssent->skill; + const char *requires = "Requires:"; + struct node *tnode; + struct list *elem; + SDL_Rect orect; + int complete = 0; + + /* remember original rect */ + orect = *rect; + + /* name */ + if (rect->h < ASCII_H) { + return -1; + } + screenPrint(rect, 0, "^c+m%s^c-", skill->name); + + /* level, ap, mp */ + screenPrint(rect, SP_RIGHTJUSTIFIED, + "^c+GLvl:^c+y%d^c- MP:^c+b%d^c- AP:^c+r%d^c-^c-", + ssent->level, + skill->mp, + skill->ap); + rect->y += ASCII_H; + rect->h -= ASCII_H; + + /* check for required items */ + if (! node_list_empty(&skill->tools) + || ! list_empty(&skill->materials)) { + + if (rect->h < ASCII_H) { + complete = -1; + } else { + + /* print "requires:" */ + screenPrint(rect, 0, " ^c+G%s^c-", requires); + + /* temporarily change x to print to right of "requires" */ + rect->x += (strlen(requires) + 1) * ASCII_W; + + /* list tools */ + node_for_each(&skill->tools, tnode) { + + if (rect->h < ASCII_H) { + complete = -1; + break; + } + + class ObjectType *tool = (class ObjectType*)tnode->ptr; + struct inv_entry *ie=player_party->inventory-> + search(tool); + char tool_clr=(ie&&ie->count)?'g':'r'; + screenPrint(rect, 0, "^c+%c%s^c-", tool_clr, + tool->getName()); + + rect->y += ASCII_H; + rect->h -= ASCII_H; + } + + /* list materials */ + list_for_each(&skill->materials, elem) { + + if (rect->h < ASCII_H) { + complete = -1; + break; + } + + struct skill_material *mat = + list_entry(elem, struct skill_material, list); + class ObjectType *objtype = + (class ObjectType*)mat->objtype; + struct inv_entry *ie=player_party->inventory-> + search(objtype); + char mat_clr=ie?'g':'r'; + char q_clr=(ie&&(ie->count>=mat->quantity))?'g':'r'; + screenPrint(rect, 0, "^c+%c%s^c+%c (%d/%d)^c-^c-", + mat_clr, + objtype->getName(), + q_clr, + mat->quantity, + ie?ie->count:0); + + rect->y += ASCII_H; + rect->h -= ASCII_H; + } + + /* restore rect x */ + rect->x = orect.x; + } + } + + /* figure out how much area we used */ + orect.h = rect->y - orect.y; + + /* if this is not the currently selected item then shade it */ + if (self->selected != node) { + screenShade(&orect, 128); + } + + return complete; +} + +static void cmd_skill_list_unref(struct stat_super_generic_data *self) +{ + struct node *node; + + /* Decrement the refcount. */ + assert(self->refcount > 0); + self->refcount--; + if (self->refcount > 0) { + return; + } + + /* Cleanup if no more refs. */ + node = node_next(&self->list); + while (node != &self->list) { + struct node *tmp = node; + node = node_next(node); + node_unref(tmp); + } +} + +static struct skill_set_entry *cmd_select_skill(class Character *pc) +{ + struct skill_set_entry *ssent; + struct node *selected; + struct stat_super_generic_data data; + + /* setup the status browser data */ + memset(&data, 0, sizeof(data)); + cmd_build_skill_list(&data.list, pc); + data.title = "Yuse"; + data.paint = cmd_paint_skill; + data.unref = cmd_skill_list_unref; + + /* put the status browser in selection mode */ + statusSetSuperGenericData(&data); + statusPushMode(SuperGeneric); + + /* wait for user selection */ + selected = (struct node*)cmd_select_generic(); + + /* extract result */ + if (selected) { + ssent = (struct skill_set_entry *)selected->ptr; + cmdwin_push(ssent->skill->name); + } else { + ssent = 0; + cmdwin_push("none"); + } + + /* restore browser status mode */ + statusPopMode(); + + assert(! data.refcount); + + return ssent; +} + +void cmdYuse(class Character *actor) +{ + struct skill_set_entry *ssent; + struct skill *skill; + int cant = 0, result = 0, yused = 0; + + /* select/verify the actor */ + if (!(actor = cmd_front_end(actor, "Yuse"))) { + return; + } + + /* select the skill to yuse */ + if (!(ssent = cmd_select_skill(actor))) { + return; + } + skill = ssent->skill; + log_begin("%s: %s - ", actor->getName(), skill->name); + + /* check wilderness */ + if (! skill->wilderness_ok + && place_is_wilderness(actor->getPlace())) { + cant = 1; + log_msg("Not in the wilderness!"); + } + + /* check level */ + if (actor->getLevel() < ssent->level) { + cant = 1; + log_msg("Must be level %d!", ssent->level); + } + + /* check mana */ + if (actor->getMana() < skill->mp) { + cant = 1; + log_msg("Not enough mana!"); + } + + /* check tools */ + if (!node_list_empty(&skill->tools)) { + struct node *tnode; + node_for_each(&skill->tools, tnode) { + class ObjectType *tool = (class ObjectType*)tnode->ptr; + struct inv_entry *ie=player_party->inventory-> + search(tool); + if (!ie || !ie->count) { + log_msg("Need %s!", tool->getName()); + cant = 1; + } + } + + } + + /* check material */ + if (! list_empty(&skill->materials)) { + struct list *elem; + struct skill_material *mat; + class ObjectType *objtype; + struct inv_entry *ie; + list_for_each(&skill->materials, elem) { + mat = list_entry(elem, struct skill_material, list); + objtype = (class ObjectType*)mat->objtype; + ie = player_party->inventory->search(objtype); + if (!ie || ie->count < mat->quantity) { + cant = 1; + log_msg("Need %d %s!", mat->quantity, + objtype->getName()); + } + } + } + + /* check special */ + if (skill->can_yuse + && ! closure_exec(skill->can_yuse, "p", actor)) { + cant = 1; + } + + /* cant? */ + if (cant) { + cmdwin_push("failed!"); + log_end("^c+rFailed!^c-"); + return; + } + + /* yuse the skill */ + result = closure_exec(skill->yuse, "p", actor); + yused = cmd_eval_and_log_result(result); + + /* change ap/mp/xp and consume materials */ + if (yused) { + actor->runHook(OBJ_HOOK_YUSE_DONE, 0); + actor->addMana(0 - skill->mp); + actor->decActionPoints(skill->ap); + actor->addExperience(ssent->level); + + if (! list_empty(&skill->materials)) { + struct list *elem; + struct skill_material *mat; + list_for_each(&skill->materials, elem) { + mat = list_entry(elem, struct skill_material, + list); + player_party->takeOut((class ObjectType*) + mat->objtype, + mat->quantity); + } + } + } + + log_end(0); +} +#endif /* USE_SKILLS */ + +bool cmdSetSoloMode(int party_member_index) +{ + class Character *solo_member = player_party->getMemberAtIndex(party_member_index); + if (solo_member + && ! solo_member->isIncapacitated() + && solo_member->isOnMap() + && solo_member->isPlayerControlled() + ) { + + if (solo_member->engagedInTask()) { + log_msg("%s is engaged in %s, abort?", solo_member->getName(), solo_member->getTaskName()); + if (! ui_get_yes_no(solo_member->getName())) { + return false; + } + } + + player_party->enableSoloMode(solo_member); + return true; + } + return false; +} + +bool cmdToggleFollowMode(void) +{ + log_begin("Follow mode "); + if (player_party->getPartyControlMode() == PARTY_CONTROL_FOLLOW) { + log_end("OFF"); + player_party->enableRoundRobinMode(); + return false; + } else { + log_end("ON"); + player_party->enableFollowMode(); + return true; + } +} + diff --git a/src/cmd.h b/src/cmd.h new file mode 100644 index 0000000..e3ce7cc --- /dev/null +++ b/src/cmd.h @@ -0,0 +1,211 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef cmd_h +#define cmd_h + +#include "macros.h" +#include "event.h" /* for v_funcpointer_ii */ + +#define MIN_XAMINE_LIGHT_LEVEL 32 + +class Character; +class Object; +class Party; + +BEGIN_DECL; + +// I really shouldn't pollute this interface with these, but they don't really +// fit anywhere else right now, either. +#include "status.h" +struct ScrollerContext { + enum StatusSelection selector; + const void *selection; + bool abort; + bool done; + bool mixing; // for mix reagents +}; + +/** + * Request format for select_target_generic(). + */ +typedef struct ui_select_target_req +{ + struct place *place; /* place this is happening in */ + int x1, y1; /* center of target zone */ + int x2, y2; /* initial/final cursor position */ + struct templ *tiles; /* template of tiles in target zone */ + struct list suggest; /* quick-target tiles */ + void *data; /* caller context */ + + /* called when the cursor moves over a new tile */ + void (*move)(struct place *, int, int, void *); + + /* Called when user hits 'enter' or otherwise selects a tile. Returns + * non-zero to end the targeting session, zero otherwise. */ + int (*select)(struct place *, int, int, void *); + +} ui_select_target_req_t; + +#define SCROLLER_HINT "\005\006=scroll ENT=select ESC=exit" +#define PAGER_HINT "\005\006=scroll ESC=exit" + +extern int dirkey(struct KeyHandler *kh, int key, int keymod); +extern int cardinaldirkey(struct KeyHandler *kh, int key, int keymod); +extern int yesnokey(struct KeyHandler *kh, int key, int keymod); +extern int anykey(struct KeyHandler *kh, int key, int keymod); +extern int scroller(struct KeyHandler *kh, int key, int keymod); +extern int movecursor(struct KeyHandler *kh, int key, int keymod); +extern int getnum(struct KeyHandler *kh, int key, int keymod); +extern void getkey(void *data, int(*handler) (struct KeyHandler * kh, + int key, int keymod)); +#define CMD_SELECT_MEMBER (1 << 0) +#define CMD_PRINT_MEMBER (1 << 1) + +extern void cmdAttack(void); +extern int cmd_camp_in_town(class Character *camper); +extern int cmd_camp_in_wilderness(class Party *camper); +extern void cmdFire(void); +extern void cmdHelp(void); +extern void cmdLoiter(class Being *subject); +extern bool cmdMixReagents(class Character *mixer); +extern void cmdNewOrder(void); +extern bool cmdSave(void); +extern void cmdReload(void); +extern bool cmdSearch(class Character *pc); +extern void cmdTalk(Object *member); +extern void cmdZoomIn(void); +extern bool cmdUse(class Character * pc, int flags); +extern bool cmdHandle(class Character * pc); +extern bool cmdReady(class Character * pc); +extern bool cmdZtats(class Character * pc); +extern bool cmdXamine (class Object *examiner); +extern bool cmdAT(class Character * pc); +extern bool cmdGet(class Object *actor); +extern bool cmdOpen(class Character * pc); +extern bool cmdCastSpell(class Character * pc); +extern bool cmdQuit(void); +extern bool cmdLook(int x, int y); +extern bool cmd_terraform(struct place *place, int x, int y); +extern bool cmd_save_current_place (struct place * place); +extern bool cmdSaveTerrainMap(class Character * pc); +extern bool cmdSetSoloMode(int party_member_index); +extern bool cmdToggleFollowMode(void); +extern void cmdSettings(void); +extern void cmdDrop(class Character *pc); +extern void cmdYuse(class Character *pc); +extern void cmdDeveloperEval(struct session *); + +extern class Character *select_party_member(void); + +struct location_list { + struct list list; + int x; + int y; +}; + +extern int select_target(int ox, int oy, int *x, int *y, int range, + struct list *suggest); + +extern const char * name_of_context (void); + +extern int ui_get_quantity(int max); + +// the new ui api +extern int ui_get_direction(void); +extern int ui_get_yes_no(const char *asked_persons_name); +extern int ui_getline(char *buf, int len); +extern int ui_getline_plain(char *buf, int len); +extern void ui_name_vehicle(class Vehicle *vehicle); + +/** + * The merchant information for a trading session. + */ +struct merchant { + const char *name; /* The merchant's name */ + int n_trades; /* Num entries in the array of items */ + struct trade_info *trades; /* The array of trade items */ +}; + +/** + * These three functions all engage in the trading UI with a merchant. ui_trade + * will allow the player to choose between buying and selling, and will call + * the other two functions. + * + * @param merch is the merchant info + * @returns the quantity of items traded + */ +extern int ui_trade(struct merchant *merch); +extern int ui_buy(struct merchant *merch); +extern int ui_sell(struct merchant *merch); + +/** + * Prompt the player to enter a line. By default (no filter provided) this will + * accept all printable characters as valid input from the player. Especially + * the ESC, '\n' and '\b' characters are taken to mean control characters and + * aren't considered printable. + * + * @param buf The string buffer to fill with the response. On success this + * contains a null-terminated string. The NULL will be there, and the buffer + * length will not be exceeded. The user reply will be truncated if necessary. + * + * @param len The length of buf. + * + * @param filter An optional filter function. This function should return + * non-zero to reject a key. Note that all non-printable characters are already + * filtered automatically; this param let's you filter even more. The filter is + * applied after checking for ESC, '\n' and '\b', which are processed as + * control characters and never appear in the result anyway. + * + * @returns The actual number of characters stored. Note that if the player + * hits ESC this will be zero as if no keys were pressed. + */ +extern int ui_getline_filtered(char *buf, int len, int (*filter)(int key)); + +/** + * More general version of select_target(). Prompts the player to select a tile + * within a range or template of tiles. + * + * @parm req tells the function how to carry out its business. + * + * @returns zero iff the (x2, y2) fields of the req hold the player-selected + * target location. The only time it won't is if the player aborts the prompt. + */ +extern int ui_select_target_generic(ui_select_target_req_t *req); + +/** + * Initialize a target request to safe defaults. Note that this is for a new + * request, if you try to re-init without doing some manual cleanup first + * you'll get a memory leak. + * + * @parm req will be initialized. + */ +extern void ui_select_target_req_init(ui_select_target_req_t *req); + +/** + * Prompt the player to select something from inventory. This assumes that the + * status mode has already been set by the caller. + */ +extern struct inv_entry *ui_select_item(void); + +END_DECL; + +#endif diff --git a/src/cmdwin.c b/src/cmdwin.c new file mode 100644 index 0000000..118549f --- /dev/null +++ b/src/cmdwin.c @@ -0,0 +1,300 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "cmdwin.h" + +#include "cfg.h" +#include "common.h" +#include "console.h" +#include "dimensions.h" +#include "images.h" +#include "log.h" +#include "screen.h" +#include "sprite.h" + +#include +#include +#include + +#define CMDWIN_FRAG_MAX_LEN 64 +#define CMDWIN_BUF_SZ 256 + +/* Fragment flags */ +#define CMDWIN_FRAG_SEP (1<<0) +#define CMDWIN_FRAG_MARK (1<<1) + +struct cmdwin_frag { + struct list list; + int flags; + char buf[CMDWIN_FRAG_MAX_LEN]; +}; + +static struct { + SDL_Rect srect; /* screen rectangle (pixels) */ + char *buf; /* string buffer */ + char *ptr; /* next empty spot in buffer */ + int blen; /* buffer length, this should be bigger than slen and + * is the max expected total size of any prompt (the + * longest prompts may be too big for the window) */ + int room; /* empty space in buffer */ + int slen; /* printable string length (blen >= slen), this is + * limited by the cmdwin UI size */ + struct sprite *cursor_sprite; + struct list frags; +} cmdwin; + +#ifdef DEBUG +static FILE *log = NULL; +#endif + +static inline void cmdwin_clear_no_repaint() +{ + memset(cmdwin.buf, 0, cmdwin.blen); + cmdwin.ptr = cmdwin.buf; + cmdwin.room = cmdwin.blen; +} + +static void cmdwin_cursor_sprite_init() +{ + char *fname = cfg_get("cursor-image-filename"); + struct images *ss_cursor = 0; + + assert(fname); + ss_cursor = images_new(0, 8, 16, 1, 4, 0, 0, fname); + assert(ss_cursor); + cmdwin.cursor_sprite = sprite_new(0, 4, 0, 0, 0, ss_cursor); + assert(cmdwin.cursor_sprite); +} + +static void cmdwin_clear_frag_stack(void) +{ + struct list *entry; + + entry = cmdwin.frags.next; + while (entry != &cmdwin.frags) { + struct cmdwin_frag *frag = (struct cmdwin_frag*)entry; + entry = entry->next; + list_remove(&frag->list); + free(frag); + } +} + +static struct cmdwin_frag *cmdwin_top() +{ + if (list_empty(&cmdwin.frags)) + return 0; + return (struct cmdwin_frag*)cmdwin.frags.prev; +} + +static void cmdwin_reprint_buffer(void) +{ + struct list *entry; + + /* Erase the buffer */ + cmdwin_clear_no_repaint(); + + /* Loop over the fragments until out of room or out of fragments */ + list_for_each(&cmdwin.frags, entry) { + struct cmdwin_frag *frag = (struct cmdwin_frag*)entry; + int n = 0; + + /* Append the fragment to the buffer. */ + if ((frag->flags & CMDWIN_FRAG_SEP) + && (entry->next != &cmdwin.frags)) { + /* Print a '-' after this fragment. */ + n = snprintf(cmdwin.ptr, cmdwin.room, "%s-", frag->buf); + } else { + /* No '-' afterwards. */ + n = snprintf(cmdwin.ptr, cmdwin.room, "%s", frag->buf); + } + n = min(n, cmdwin.room); + cmdwin.room -= n; + cmdwin.ptr += n; + + /* If out of room then stop, and backup the ptr to the last + * entry in the buffer */ + if (!cmdwin.room) { + cmdwin.ptr--; + break; + } + + } +} + +int cmdwin_init(void) +{ + cmdwin_cursor_sprite_init(); + + list_init(&cmdwin.frags); + + cmdwin.srect.x = CMD_X; + cmdwin.srect.y = CMD_Y; + cmdwin.srect.w = CMD_W; + cmdwin.srect.h = CMD_H; + cmdwin.slen = (CMD_W / ASCII_W) - 1; /* leave one space for the + * cursor */ + cmdwin.blen = CMDWIN_BUF_SZ; + assert(cmdwin.blen >= cmdwin.slen); + + cmdwin.buf = (char *) malloc(cmdwin.blen); + if (!cmdwin.buf) + return -1; + +#ifdef DEBUG + log = fopen(".cmdwin", "w+"); + if (!log) { + err(strerror(errno)); + return -1; + } +#endif + + cmdwin_clear_no_repaint(); + return 0; +} + +static void cmdwin_vpush(int flags, const char *fmt, va_list args) +{ + /* Allocate a new fragment */ + struct cmdwin_frag *frag = (struct cmdwin_frag*)malloc(sizeof(*frag)); + if (!frag) { + warn("allocation failed"); + return; + } + + frag->flags = flags; + + /* default to empty string */ + frag->buf[0] = 0; + + /* Store the string in the fragment */ + if (fmt != NULL) { + vsnprintf(frag->buf, sizeof(frag->buf), fmt, args); + } + + /* Push the fragment onto the stack */ + list_add_tail(&cmdwin.frags, &frag->list); + + /* Reprint the buffer with the new fragment */ + cmdwin_reprint_buffer(); + + /* Update the display */ + cmdwin_repaint(); +} + +void cmdwin_spush(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + cmdwin_vpush(CMDWIN_FRAG_SEP, fmt, args); + va_end(args); + +} + +void cmdwin_push(const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + cmdwin_vpush(0, fmt, args); + va_end(args); +} + +void cmdwin_push_mark() +{ + cmdwin_vpush(CMDWIN_FRAG_MARK, 0, 0); +} + +void cmdwin_pop(void) +{ + struct cmdwin_frag *frag; + + /* Fragment stack should not be empty. */ + assert(! list_empty(&cmdwin.frags)); + + /* Remove the last fragment and free it. */ + frag = (struct cmdwin_frag*)cmdwin.frags.prev; + list_remove(&frag->list); + free(frag); + + /* Reprint the buffer without the fragment */ + cmdwin_reprint_buffer(); + + /* Update the display */ + cmdwin_repaint(); +} + +void cmdwin_pop_to_mark() +{ + struct cmdwin_frag *frag = cmdwin_top(); + while (frag && frag->flags != CMDWIN_FRAG_MARK) { + cmdwin_pop(); + frag = cmdwin_top(); + } + + /* DON'T pop the mark itself */ +} + +void cmdwin_clear(void) +{ + cmdwin_clear_frag_stack(); + cmdwin_clear_no_repaint(); + cmdwin_repaint(); +} + +void cmdwin_repaint_cursor(void) +{ + SDL_Rect rect; + + rect.x = cmdwin.srect.x; + rect.y = cmdwin.srect.y; + rect.w = ASCII_W; + rect.h = ASCII_H; + + /* If the string is too big, show the last part of it (in other words, + * right-justify it) */ + char *start = max(cmdwin.buf, cmdwin.ptr - cmdwin.slen); + rect.x += (cmdwin.ptr - start) * ASCII_W; + + sprite_paint(cmdwin.cursor_sprite, 0, rect.x, rect.y); + screenUpdate(&rect); +} + +void cmdwin_repaint(void) +{ + /* If the string is too big, show the last part of it (in other words, + * right-justify it) */ + char *start = max(cmdwin.buf, cmdwin.ptr - cmdwin.slen); + screenErase(&cmdwin.srect); + screenPrint(&cmdwin.srect, 0, start); + screenUpdate(&cmdwin.srect); + cmdwin_repaint_cursor(); +} + +void cmdwin_flush(void) +{ + if (!strlen(cmdwin.buf)) + return; + + log_msg("%s\n", cmdwin.buf); + cmdwin_clear(); +} diff --git a/src/cmdwin.h b/src/cmdwin.h new file mode 100644 index 0000000..27dec74 --- /dev/null +++ b/src/cmdwin.h @@ -0,0 +1,67 @@ +/* + * nazghul - an old-school RPG engine + * Copyright (C) 2002, 2003 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * Gordon McNutt + * gmcnutt@users.sourceforge.net + */ + +#ifndef cmdwin_h +#define cmdwin_h + +/* The command window is the little window below the map that displays all the + * command prompts. It's very interactive. The gist of the API is that + * multi-step commands that want to prompt the user will "push" a prompt, pop + * it and push the reply, push the next prompt, etc. */ + +/* cmdwin_init -- startup init */ +extern int cmdwin_init(void); + +/* cmdwin_clear -- erase the contents */ +extern void cmdwin_clear(void); + +/* cmdwin_repaint_cursor -- repaint just the cursor prompt (used to animate the + * cursor sprite) */ +extern void cmdwin_repaint_cursor(void); + +/* cmdwin_repaint -- repaint the cmdwin window (cmdwin_push and _spush do this + * automatically, so this is rarely necessary) */ +extern void cmdwin_repaint(void); + +/* cmdwin_flush -- write the contents of the cmdwin to the console */ +extern void cmdwin_flush(void); + +/* cmdwin_push -- append a string to the cmdwin prompt (this can be undone with + * cmdwin_pop). Works just like printf for string formatting. */ +extern void cmdwin_push(const char *fmt, ...); + +/* cmdwin_spush -- same as push, but print a '-' after it if anything else is + * pushed (the 's' is for 'segment', you're pushing a prompt segment) */ +extern void cmdwin_spush(const char *fmt, ...); + +/* cmdwin_pop -- remove a string appended by one of the push commands */ +extern void cmdwin_pop(void); + +/* cmdwin_push_mark -- a mark is invisible, but when pop_to_mark is called any + * string appended after the last mark is popped. */ +extern void cmdwin_push_mark(); + +/* cmdwin_pop_to_mark -- pop all strings appended since the last mark. This + * does not pop the mark itself (use cmdwin_pop for that). */ +extern void cmdwin_pop_to_mark(); + +#endif diff --git a/src/combat.c b/src/combat.c new file mode 100644 index 0000000..d2ee791 --- /dev/null +++ b/src/combat.c @@ -0,0 +1,1814 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "combat.h" +#include "dice.h" +#include "node.h" +#include "Party.h" +#include "place.h" +#include "player.h" +#include "object.h" +#include "common.h" +#include "map.h" +#include "hash.h" +#include "wq.h" +#include "sound.h" +#include "status.h" +#include "cursor.h" +#include "Container.h" +#include "terrain.h" +#include "Field.h" +#include "event.h" +#include "play.h" +#include "foogod.h" +#include "wind.h" +#include "dup_constants.h" +#include "cmdwin.h" +#include "terrain_map.h" +#include "vehicle.h" +#include "formation.h" +#include "pinfo.h" +#include "cmd.h" +#include "formation.h" +#include "session.h" +#include "log.h" +#include "vmask.h" +#include "factions.h" +#include "blender.h" + +#include +#include +#include +#include +#include + +#define FORMATION_H (formation[array_sz(formation) - 1].y) +#define N_MAX_NPCS 256 /* arbitrary limit */ +#define MAX_DEPTH 64 +#define MAX_PLACEMENT_RECTANGLE_W 32 +#define MAX_PLACEMENT_RECTANGLE_H 16 +#define SEARCH_QUEUE_SZ 100 + +/* Formation pattern -- party facing north (dx=0,dy=-1), origin at the leader's + * position */ + +enum combat_faction_status { + COMBAT_FACTION_EXISTS, + COMBAT_FACTION_GONE, + COMBAT_FACTION_CHARMED, + COMBAT_FACTION_CAMPING +}; + +static struct { + struct place *place; + void *session_handle; + enum combat_state state; + char vmap[7 * 7]; // visited map (used to search for positions) + class Vehicle *enemy_vehicle; + sound_t *sound_enter; + sound_t *sound_defeat; + sound_t *sound_victory; + int round; +} Combat; + +struct v2 { + struct place *place; + int dx, dy; +}; + +// Search alg data +static char rmap[MAX_PLACEMENT_RECTANGLE_W * MAX_PLACEMENT_RECTANGLE_H]; +static int x_q[SEARCH_QUEUE_SZ]; +static int y_q[SEARCH_QUEUE_SZ]; +static int q_head; +static int q_tail; + +enum combat_state combat_get_state(void) +{ + return Combat.state; +} + +void combat_set_state(enum combat_state new_state) +{ + // -------------------------------------------------------------------- + // Interesting state transitions: + // + // ==================================================================== + // old state | new state | result + // ==================================================================== + // COMBAT_STATE_DONE | COMBAT_STATE_FIGHTING | entry to combat + // COMBAT_STATE_DONE | COMBAT_STATE_LOOTING | non-hostile + // COMBAT_STATE_DONE | COMBAT_STATE_CAMPING | entry to camping + // COMBAT_STATE_FIGHTING | COMBAT_STATE_DONE | defeat + // COMBAT_STATE_FIGHTING | COMBAT_STATE_LOOTING | victory + // COMBAT_STATE_LOOTING | COMBAT_STATE_FIGHTING | hostiles entered + // COMBAT_STATE_LOOTING | COMBAT_STATE_DONE | exit normally + // COMBAT_STATE_CAMPING | COMBAT_STATE_FIGHTING | ambush + // COMBAT_STATE_CAMPING | COMBAT_STATE_DONE | exit camping + // ==================================================================== + // + // -------------------------------------------------------------------- + + if (Combat.state == new_state) + return; + + + switch (Combat.state) { + + case COMBAT_STATE_DONE: + switch (new_state) { + case COMBAT_STATE_FIGHTING: + log_banner("^c+mCOMBAT^c-"); + sound_play(Combat.sound_enter, SOUND_MAX_VOLUME); + break; + case COMBAT_STATE_LOOTING: + break; + case COMBAT_STATE_CAMPING: + log_banner("CAMPING"); + break; + default: + assert(false); + break; + } + break; + + case COMBAT_STATE_FIGHTING: + switch (new_state) { + case COMBAT_STATE_LOOTING: + log_banner("^c+gVICTORY^c-"); + sound_play(Combat.sound_victory, SOUND_MAX_VOLUME); + player_party->addExperience(COMBAT_VICTORY_XP); + break; + case COMBAT_STATE_DONE: + log_banner("^c+rDEFEAT^c-"); + sound_play(Combat.sound_defeat, SOUND_MAX_VOLUME); + break; + default: + assert(false); + break; + } + break; + + case COMBAT_STATE_LOOTING: + switch (new_state) { + case COMBAT_STATE_FIGHTING: + log_banner("^c+mCOMBAT^c-"); + sound_play(Combat.sound_enter, SOUND_MAX_VOLUME); + break; + case COMBAT_STATE_DONE: + break; + default: + assert(false); + break; + } + break; + + case COMBAT_STATE_CAMPING: + switch (new_state) { + case COMBAT_STATE_FIGHTING: + log_banner("^c+mCOMBAT^c-"); + sound_play(Combat.sound_enter, SOUND_MAX_VOLUME); + break; + case COMBAT_STATE_LOOTING: + case COMBAT_STATE_DONE: + break; + default: + assert(false); + break; + } + break; + + default: + assert(false); + break; + } + + Combat.state = new_state; + session_run_hook(Session, combat_change_hook, "p", Session->player); +} + +// returns 0 for ok position, -1 for no position, or a PFLAG type for fallback positions with problems +// input includes current best case problemness +static int location_is_safe(struct position_info *info, int current) +{ + struct astar_node *path; + struct astar_search_info as_info; + struct terrain *terrain; + int returntype=0; + + // Is it passable? + if (!place_is_passable(info->place, info->px, info->py, + info->subject, 0)) { + dbg("impassable\n"); + return -1; + } + // Is it occupied? + if (place_is_occupied(info->place, info->px, info->py)) { + dbg("occupied\n"); + returntype= PFLAG_IGNOREBEINGS; + if (current & (PFLAG_IGNOREHAZARDS || PFLAG_IGNOREBEINGS || PFLAG_IGNOREFIELDS)) + return -1; + } + + // I added the next two checks because a character was getting + // positioned over the firepit while camping, and I thought it was + // damaging him. Turns out firepits weren't setup to cause fire damage + // (oddly), and the character was just starving. I'll leave this here + // for now anyway. + + // Is it dangerous? Hack: check for a field and dangerous terrain + if (place_get_object(info->place, info->px, info->py, field_layer)) { + dbg("possibly dangerous field\n"); + returntype= PFLAG_IGNOREFIELDS; + if (current & (PFLAG_IGNOREHAZARDS || PFLAG_IGNOREFIELDS)) + return -1; + } + terrain = place_get_terrain(info->place, info->px, info->py); + if (terrain->effect) { + dbg("possibly dangerous terrain\n"); + returntype= PFLAG_IGNOREHAZARDS; + if (current & (PFLAG_IGNOREHAZARDS )) + return -1; + } + + memset(&as_info, 0, sizeof (as_info)); + if (info->find_party) { + // Each member should be able to find a path back to the + // party's originating location on the map. + dbg("searching for path to party [%d %d]...", + info->x, info->y); + + as_info.x0 = info->px; + as_info.y0 = info->py; + as_info.x1 = info->x; + as_info.y1 = info->y; + as_info.flags = PFLAG_IGNOREBEINGS; + as_info.limit_depth = true; + as_info.max_depth = 5; + + path = place_find_path(info->place, &as_info, info->subject); + + if (!path) + dbg("no path back to party\n"); + } + else { + // skip the pathfinding check + return returntype; + } + + if (path) { + astar_path_destroy(path); + return returntype; + } + + return -1; +} + +// returns 0 for ok position, -1 for no position, or a PFLAG type for fallback positions with problems +// input includes current best case problemness +static int combat_search_for_safe_position(struct position_info *info, int currentsafety) +{ + unsigned int i; + int index; + static int x_offsets[] = { -1, 1, 0, 0 }; + static int y_offsets[] = { 0, 0, -1, 1 }; + int locationsafety=-1; + + dbg("checking [%d %d]...", info->px, info->py); + + // translate the map coords into an rmap index + index = info->py - info->ry; + index *= info->rw; + index += (info->px - info->rx); + + // If the current location is off-map, outside of the placement + // rectangle or already visited then discontinue the search. + if (rmap[index]) { + dbg("already visited [%d]\n", index); + return -1; // already visited + } + if (info->px < info->rx || info->px >= info->rx + info->rw || + info->py < info->ry || info->py >= info->ry + info->rh) { + dbg("outside the placement area\n"); + return -1; // outside the placement rect + } + if (place_off_map(info->place, info->px, info->py)) { + dbg("off-map\n"); + // return -1; // off map + goto enqueue_neighbors; + } + // Mark this location as visited. + rmap[index] = 1; + + // If the current location is safe then the search succeeded. + locationsafety = location_is_safe(info,currentsafety); + if (locationsafety == 0) { + dbg("OK!\n"); + return 0; + } + + enqueue_neighbors: + // Enqueue the adjacent neighbors onto the search queue. + for (i = 0; i < array_sz(x_offsets) && q_tail < SEARCH_QUEUE_SZ; i++) { + assert(q_tail < SEARCH_QUEUE_SZ); + x_q[q_tail] = info->px + x_offsets[i]; + y_q[q_tail] = info->py + y_offsets[i]; + q_tail++; + } + + // Return still not found. + return locationsafety; +} + +// returns 0 for ok position, -1 for no position, or a PFLAG type for fallback positions with problems +static int combat_find_safe_position(struct position_info *info) +{ + // Here's my new definition of a safe place: a safe place is a tile + // within the placement rectangle which is passable to the character in + // question and from which the character in question can pathfind to + // the edge from which the party entered. + + // store data on a fallback not-so-safe position + int currentsafety = 0; + int cur_x = 0, cur_y = 0; + int newsafety = -1; + + // Clear the search queue. + q_head = q_tail = 0; + + // Push the preferred position onto the search queue. + x_q[q_tail] = info->px; + y_q[q_tail] = info->py; + q_tail++; + + // Run through the search queue until it is exhausted or a safe + // position has been found. + while (q_head != q_tail) { + + // Dequeue the next location to check. + info->px = x_q[q_head]; + info->py = y_q[q_head]; + q_head++; + + // If it is ok then we're done. + newsafety = combat_search_for_safe_position(info, currentsafety); + if (newsafety == 0) + return 0; + else if (newsafety != -1) + { + currentsafety = newsafety; + cur_x = info->px; + cur_y = info->py; + } + } + + if (currentsafety != 0) + { + info->px = cur_x; + info->py = cur_y; + return currentsafety; + } + + return -1; +} + +static bool myPutNpc(class Character * pm, void *data) +{ + int tmp; + struct position_info *info; + + + info = (struct position_info *) data; + + if (pm->isDead()) + return false; + + // In the case where there is more than one NPC party entering combat + // this might be called more than once for an NPC. I want to ignore all + // but the first call, so check if the NPC is already on the map. + if (pm->isOnMap()) + return false; + + // Make sure we don't index beyond the end of the formation array. + if (pm->getOrder() >= info->formation->n) + return false; + + pm->setCombat(true); + + pm->setX(info->formation->entry[pm->getOrder()].x); + pm->setY(info->formation->entry[pm->getOrder()].y); + + /* Counterclockwise rotations: x = x * cos - y * sin y = x * sin + y * + * cos */ + if (info->dx < 0) { + /* Rotate +90 degrees */ + tmp = pm->getX(); + pm->setX(pm->getY()); + pm->setY(tmp); + } + else if (info->dx > 0) { + /* Rotate -90 degrees */ + tmp = pm->getX(); + pm->setX(-pm->getY()); + pm->setY(tmp); + } + else if (info->dy > 0) { + /* Rotate 180 degrees */ + pm->setX(-pm->getX()); + pm->setY(-pm->getY()); + } + + /* If dy > 1 then the formation is ok as-is. */ + pm->changeX(info->x); + pm->changeY(info->y); + + // Check if that location will really work. If not then do a DFS + // starting from the desired location and see if we can find someplace + // that WILL work. + + // initialize the position info for a new search + info->subject = pm; + memset(rmap, 0, sizeof (rmap)); + + // set the preferred location + info->px = pm->getX(); + info->py = pm->getY(); + + dbg("Placing %s\n", pm->getName()); + + if (combat_find_safe_position(info) == -1) { + // If I can't place a member then I can't place it. + dbg("*** Can't place %s ***\n", pm->getName()); + return false; + } + + pm->setX(info->px); + pm->setY(info->py); + dbg("Put '%s' at [%d %d]\n", pm->getName(), info->px, info->py); + pm->setPlace(Place); + place_add_object(Place, pm); + pm->setOnMap(true); + info->placed++; + + /* Check if we need to go back to fighting */ + if (combat_get_state() != COMBAT_STATE_FIGHTING && + are_hostile(pm, player_party)) { + combat_set_state(COMBAT_STATE_FIGHTING); + } + + return false; +} + +static void set_party_initial_position(struct position_info *pinfo, int x, int y) +{ + pinfo->x = x; + pinfo->y = y; + + // Set the bounds of the placement rectangle. For now I don't care if + // it overlaps the edge of the map because the search algorithm will + // check for off-map locations. + pinfo->rw = MAX_PLACEMENT_RECTANGLE_W; + pinfo->rh = MAX_PLACEMENT_RECTANGLE_H; + pinfo->rx = pinfo->x - pinfo->rw / 2; + pinfo->ry = pinfo->y - pinfo->rh / 2; + + dbg("Moved party start position to [%d %d]\n", pinfo->x, pinfo->y);; + +} + +void combat_fill_position_info(struct position_info *info, struct place *place, int x, int y, int dx, int dy, bool defend) +{ + // + // This function will: + // * determine the party's coordinates upon entry to combat + // * turn the defending party to face the attacker + // * specify the placement rectangle for the party members + // * set the flags for the placement algorithm + // + + info->place = place; + info->dx = dx; + info->dy = dy; + + if (info->place != Combat.place) { + // Occupy the same location and face the same way + info->x = x; + info->y = y; + + } + else { + + if (defend) { + // Reverse facing + info->dx = -dx; + info->dy = -dy; + dx = -dx; + dy = -dy; + } + // Occupy an edge facing the opponent + if (dx < 0) { + // facing west, occupy east half + info->x = place_w(info->place) - place_w(info->place) / 4; + } + else if (dx > 0) { + // facing east, occupy west half + info->x = place_w(info->place) / 4; + } + else { + // facing north or south, center on east-west + info->x = place_w(info->place) / 2; + } + + if (dy < 0) { + // facing north, occupy south + info->y = place_h(info->place) - place_h(info->place) / 4; + } + else if (dy > 0) { + // facing south, occupy north + info->y = place_h(info->place) / 4; + } + else { + // facing east or west, center on north-south + info->y = place_h(info->place) / 2; + } + } + + set_party_initial_position(info, info->x, info->y); + + // clear the pmask and search map before first use + info->subject = NULL; + memset(rmap, 0, sizeof (rmap)); + + info->placed = 0; +} + +bool combat_place_character(class Character * pm, void *data) +{ + // Put a party member on the combat map + + int tmp; + struct position_info *info; + + info = (struct position_info *) data; + + if (pm->isDead()) + return false; + + if (pm->getOrder() >= info->formation->n) + return false; + + pm->setX(info->formation->entry[pm->getOrder()].x); + pm->setY(info->formation->entry[pm->getOrder()].y); + + /* Counterclockwise rotations: x = x * cos - y * sin y = x * sin + y * + * cos */ + if (info->dx < 0) { + /* Rotate +90 degrees */ + tmp = pm->getX(); + pm->setX(pm->getY()); + pm->setY(tmp); + } + else if (info->dx > 0) { + /* Rotate -90 degrees */ + tmp = pm->getX(); + pm->setX(-pm->getY()); + pm->setY(tmp); + } + else if (info->dy > 0) { + /* Rotate 180 degrees */ + pm->setX(-pm->getX()); + pm->setY(-pm->getY()); + } + + /* If dy > 1 then the formation is ok as-is. */ + pm->changeX(info->x); + pm->changeY(info->y); + + // Check if that location will really work. If not then do a DFS + // starting from the desired location and see if we can find someplace + // that WILL work. + + // init the position info for a new search + info->subject = pm; + memset(rmap, 0, sizeof (rmap)); + info->px = pm->getX(); + info->py = pm->getY(); + dbg("Placing %s\n", pm->getName()); + + if (combat_find_safe_position(info) != 0) { + + // Ok, so that didn't work. This can happen when the party + // leader is right on the map border facing towards the map + // center. In this case the find-safe-place alg won't handle + // followers that are too deep off the map. If this IS the + // party leader, or if upon retry we STILL can't find a safe + // place, then screw it - we'll place this character on the + // start location (even if we have to end up stacking the whole + // party there!). + + // Corner case: a portal leads from one lake to another. A + // hostile npc party is sitting right on the destination. The + // party enters the portal on foot, upon arrival the npc party + // attacks. Party members which are on foot get stacked on the + // entry point and cannot move or flee. This is an unfriendly + // situation, but something of a corner case. Map hackers can + // skirt the issue and player's can expect that entering + // portals involves an element of danger :). The engine won't + // crash and the player can usually get out of the fix by + // defeating the npc's. + + class Character *leader = player_party->get_leader(); + + if (!leader) { + dbg("Putting %s on start location [%d %d]\n", + pm->getName(), info->x, info->y); + info->px = info->x; + info->py = info->y; + } + else { + // init the position info to search again + memset(rmap, 0, sizeof (rmap)); + info->px = leader->getX(); + info->py = leader->getY(); + dbg("Retrying %s\n", pm->getName()); + + if (combat_find_safe_position(info) != 0) { + dbg("Putting %s on start location " + "[%d %d]\n", + pm->getName(), info->x, info->y); + info->px = info->x; + info->py = info->y; + } + } + } + + pm->relocate(info->place, info->px, info->py); + + return false; +} + +static bool mySetInitialCameraPosition(class Character * pm, void *data) +{ + if (pm->isOnMap()) { + mapCenterCamera(pm->getX(), pm->getY()); + return true; + } + return false; +} + +static void combat_overlay_vehicle(Vehicle *vehicle, int dx, int dy, + struct position_info *pinfo) +{ + + assert(pinfo->dx || pinfo->dy); + assert(!pinfo->dx || !pinfo->dy); + + int dst_x = 0, dst_y = 0; + + if (dx < 0) { + // facing west, fill east half + dst_x = COMBAT_MAP_W / 2; + set_party_initial_position(pinfo, (COMBAT_MAP_W*3)/4,COMBAT_MAP_H/2); + } + else if (dx > 0) { + // facing east, fill west half + dst_x = COMBAT_MAP_W / 2 - COMBAT_MAP_W; + set_party_initial_position(pinfo, COMBAT_MAP_W/4,COMBAT_MAP_H/2); + } + else if (dy < 0) { + // facing north, fill south half + dst_y = COMBAT_MAP_H / 2; + set_party_initial_position(pinfo, COMBAT_MAP_W/2,(COMBAT_MAP_H*3)/4); + } + else if (dy > 0) { + // facing south, fill north half + dst_y = COMBAT_MAP_H / 2 - COMBAT_MAP_H; + set_party_initial_position(pinfo, COMBAT_MAP_W/2,COMBAT_MAP_H/4); + } + else + { + set_party_initial_position(pinfo, COMBAT_MAP_W/2,COMBAT_MAP_H/2); + } + + closure_exec(vehicle->getObjectType()->renderCombat, "ppdd", + Place, vehicle, dst_x, dst_y); + +} + + +static void combat_overlay_map(struct terrain_map *map, + struct position_info *pinfo, int broadside) +{ + int x = 0, y = 0; + + assert(pinfo->dx || pinfo->dy); + assert(!pinfo->dx || !pinfo->dy); + + // Clone the map so we can make a rotated copy. + map = terrain_map_clone(map, "combat_overlay_map"); + if (!map) { + err("Failed to allocate temporary terrain map"); + return; + } + // Rotate the map so that north faces the opponent. + if (broadside) { + terrain_map_rotate(map, vector_to_rotation(pinfo->dy, pinfo->dx)); + + // Position the map against the boundary dividing the map. + if (pinfo->dx < 0) { + // facing west, shift map west toward edge + x = (place_w(Place)) / 2; + y = (place_h(Place) - map->h) / 2; + } + else if (pinfo->dx > 0) { + // facing east, shift map east toward edge + x = (place_w(Place)) / 2 - map->w; + y = (place_h(Place) - map->h) / 2; + } + else if (pinfo->dy < 0) { + // facing north, shift map north toward edge + x = (place_w(Place) - map->w) / 2; + y = (place_h(Place)) / 2; + } + else if (pinfo->dy > 0) { + // facing south, shift map south toward edge + x = (place_w(Place) - map->w) / 2; + y = (place_h(Place)) / 2 - map->h; + } + } + else { + terrain_map_rotate(map, vector_to_rotation(pinfo->dx, + pinfo->dy)); + // center the overlayed map + x = (place_w(Place) - map->w) / 2; + y = (place_h(Place) - map->h) / 2; + } + + assert(x >= 0); + assert(y >= 0); + + // Adjust the party's starting position to be centered on the overlap + // map. + set_party_initial_position(pinfo, + x + (map->w /*+ 1*/) / 2, + y + (map->h /*+ 1*/) / 2); + + // Blit the rotated map centered on the given coordinates. + terrain_map_blit(Place->terrain_map, x, y, map, 0, 0, map->w, map->h); + // terrain_map_print(stdout, INITIAL_INDENTATION, Place->terrain_map); + + // Cleanup. + terrain_map_unref(map); +} + +static void myPutEnemy(class Party * foe, struct position_info *pinfo) +{ + foe->forEachMember(myPutNpc, pinfo); +} + +/* + * combat_position_enemy - put an NPC party on the combat map + */ +static int combat_position_enemy(class Party * foe, int dx, int dy, + int defend, + struct place *place) +{ + int positioned = 0; + + assert(foe->getSize()); + + combat_fill_position_info(&foe->pinfo, place, foe->getX(), foe->getY(), + dx, dy, defend); + foe->pinfo.formation = foe->get_formation(); + if (!foe->pinfo.formation) + foe->pinfo.formation = formation_get_default(); + + Combat.enemy_vehicle = foe->getVehicle(); + + /* Bugfix SF1412060 "NPC attacks while on (but not aboard) ship" */ + /* Addendum: the foe may not have a place if it is being introduced + * into combat "from scratch" (ie, it did not exist on the wilderness + * as a party before being imported into combat). */ + if (! Combat.enemy_vehicle && foe->getPlace()) { + Combat.enemy_vehicle = place_get_vehicle(foe->getPlace(), + foe->getX(), + foe->getY()); + } + /* Check for a map overlay. */ + if (Combat.enemy_vehicle + && Combat.enemy_vehicle->getObjectType()->renderCombat + && Place == Combat.place) { + combat_overlay_vehicle(Combat.enemy_vehicle, + defend ? -dx : dx, + defend ? -dy : dy, + &foe->pinfo); + } + + foe->disembark(); + obj_inc_ref(foe); + foe->remove(); + myPutEnemy(foe, &foe->pinfo); + positioned = foe->pinfo.placed; + + obj_dec_ref(foe); + + return positioned; +} + + +/***************************************************************************** + * combat_npc_status_visitor - determine the status of the npc faction(s) + * + * This is a "visitor" function applied to each object in a list of nodes. It's + * meant to be applied to every object in a place. It checks for any npc + * party members and whether or not they're charmed, and sets the combat status + * of the npc faction. + * + * This routine does not distinguish between different NPC factions, it just + * looks for anybody hostile to the player. + * + *****************************************************************************/ +static void combat_hostile_status_visitor(struct node *node, void *data) +{ + enum combat_faction_status *status; + class Object *obj; + + /* Extract the typed variables from the generic parms */ + status = (enum combat_faction_status *)data; + obj = (class Object*)node->ptr; + + /* If we already know a hostile faction exists then skip the rest */ + if (*status == COMBAT_FACTION_EXISTS) + return; + + /* Skip non-beings */ + if (! obj_is_being(obj)) + return; + + /* Skip player party members */ + if (obj->isPlayerPartyMember()) + return; + + /* A hostile npc means a hostile faction still exists */ + if (are_hostile((Being*)obj, player_party)) { + *status = COMBAT_FACTION_EXISTS; + return; + } + + /* Check for a charmed hostile */ + if (are_natively_hostile((Being*)obj, player_party)) { + *status = COMBAT_FACTION_CHARMED; + } +} + +/***************************************************************************** + * combat_get_hostile_faction_status - check hostile combat status + * + * This is literally a dupe of combat_get_player_faction_status() below. + * + *****************************************************************************/ +static enum combat_faction_status combat_get_hostile_faction_status(void) +{ + enum combat_faction_status stat; + + /* Assume until proven otherwise that the player faction is gone. */ + stat = COMBAT_FACTION_GONE; + + /* Check each object in the current place to determine the status of + * the player faction. */ + node_foldr(place_get_all_objects(Place), + combat_hostile_status_visitor, + &stat); + + /* Return the discovered status. */ + return stat; +} + +/***************************************************************************** + * combat_player_status_visitor - determine the status of the player faction + * + * This is a "visitor" function applied to each object in a list of nodes. It's + * meant to be applied to every object in a place. It checks for any player + * party members and whether or not they're charmed, and sets the combat status + * of the player party based on the cumulative results. + * + *****************************************************************************/ +static void combat_player_status_visitor(struct node *node, void *data) +{ + enum combat_faction_status *status; + class Object *obj; + + /* Extract the typed variables from the generic parms */ + status = (enum combat_faction_status *)data; + obj = (class Object*)node->ptr; + + /* If we already know the player is still fighting then skip the rest + * of this. */ + if (*status == COMBAT_FACTION_EXISTS) + return; + + /* Skip non-beings */ + if (! obj_is_being(obj)) + return; + + /* Skip non-party-members */ + if (! obj->isPlayerPartyMember()) + return; + + /* A non-hostile party member means the player is still fighting. */ + if (! are_hostile((Being*)obj, player_party)) { + *status = COMBAT_FACTION_EXISTS; + return; + } + + /* Check if a player party members has been charmed */ + if (are_natively_hostile((Being*)obj, player_party)) { + *status = COMBAT_FACTION_CHARMED; + } +} + +/***************************************************************************** + * combat_get_player_faction_status - check player combat status + * + * Loops over all objects to check if any player party members are still around + * and whether or not they're charmed. + * + * FIXME: why not just check the player party directly? Or at least merge this + * with the combat_get_hostile_faction_status() function above? + * + *****************************************************************************/ +static enum combat_faction_status combat_get_player_faction_status(void) +{ + enum combat_faction_status stat; + + /* Assume until proven otherwise that the player faction is gone. */ + stat = COMBAT_FACTION_GONE; + + /* Check each object in the current place to determine the status of + * the player faction. */ + node_foldr(place_get_all_objects(Place), + combat_player_status_visitor, + &stat); + + /* Return the discovered status. */ + return stat; +} + +void combat_analyze_results_of_last_turn() +{ + + enum combat_faction_status hostile_faction_status; + enum combat_faction_status player_faction_status; + + // --------------------------------------------------------------------- + // Now check for changes in the combat state as a result of the last + // turn. Check the status of the hostile party or parties and the + // player party. The following table shows the outcome with all + // possible combinations of status: + // + // ===================================================== + // hostiles | player party | result + // ===================================================== + // exist | exist | continue combat + // exist | gone | exit combat + // exist | charmed | uncharm, continue combat + // gone | exist | looting + // gone | gone | exit combat + // gone | charmed | uncharm, looting + // charmed | exist | continue combat + // charmed | gone | exit combat + // charmed | charmed | uncharm, continue combat + // ===================================================== + // + // --------------------------------------------------------------------- + + hostile_faction_status = combat_get_hostile_faction_status(); + player_faction_status = combat_get_player_faction_status(); + + switch (player_faction_status) { + + case COMBAT_FACTION_EXISTS: + + switch (hostile_faction_status) { + + case COMBAT_FACTION_EXISTS: + // ----------------------------------------------------- + // Both factions exist. Continue or restart fighting. + // ----------------------------------------------------- + combat_set_state(COMBAT_STATE_FIGHTING); + break; + + case COMBAT_FACTION_CHARMED: + // ----------------------------------------------------- + // The hostile faction are all charmed. Tough luck for + // them. Make sure we are fighting. Addendum: can't + // attack them without degrading diplomacy with own + // faction, so declare combat over. When charm wears + // off we'll go back to fighting. + // ----------------------------------------------------- + //combat_set_state(COMBAT_STATE_FIGHTING); + combat_set_state(COMBAT_STATE_LOOTING); + break; + + case COMBAT_FACTION_GONE: + // ----------------------------------------------------- + // No hostiles around. Loot at will. + // ----------------------------------------------------- + if (Combat.state != COMBAT_STATE_DONE) + { + combat_set_state(COMBAT_STATE_LOOTING); + } + break; + + default: + assert(false); + break; + } + + break; + + case COMBAT_FACTION_CHARMED: + + // ------------------------------------------------------------- + // In all of these cases I uncharm the party members. If I + // don't, then I'm risking a deadlock situation where the + // hostiles can't or won't finish off the charmed members, in + // which case the game gets stuck running all the npc's forever + // while the player helplessly watches. + // ------------------------------------------------------------- + + player_party->unCharmMembers(); + + switch (hostile_faction_status) { + + case COMBAT_FACTION_EXISTS: + combat_set_state(COMBAT_STATE_FIGHTING); + break; + + case COMBAT_FACTION_GONE: + // ---------------------------------------------------- + // No hostiles around. Loot at will. Uncharm or we'll + // definitely deadlock. + // ---------------------------------------------------- + combat_set_state(COMBAT_STATE_LOOTING); + break; + + default: + assert(false); + break; + } + + break; + + case COMBAT_FACTION_GONE: + + // ------------------------------------------------------------ + // In all of these cases combat is over. Simple. If combat is + // ocurring in the special combat place then we need to clean + // it up by calling combat_exit(). + // ------------------------------------------------------------ + + combat_set_state(COMBAT_STATE_DONE); + +// if (Place == Combat.place) + combat_exit(); + + break; + + case COMBAT_FACTION_CAMPING: + + switch (hostile_faction_status) { + + case COMBAT_FACTION_EXISTS: + // ---------------------------------------------------- + // Ambush! + // ---------------------------------------------------- + combat_set_state(COMBAT_STATE_FIGHTING); + break; + + case COMBAT_FACTION_GONE: + // ---------------------------------------------------- + // No hostiles around. Change nothing. + // ---------------------------------------------------- + break; + + default: + assert(false); + break; + } + + break; + + } + + +} + +/* + * combat_find_and_position_enemy - if this object is a hostile NPC party then + * place it on the combat map + */ +static void combat_find_and_position_enemy(class Object * obj, void *data) +{ + struct v2 *info; + + if (!obj->isType(PARTY_ID)) + return; + + info = (struct v2 *) data; + assert(obj_is_being(obj)); + if (are_hostile((Being*)obj, player_party)) + combat_set_state(COMBAT_STATE_FIGHTING); + combat_position_enemy((class Party *) obj, info->dx, info->dy, false, + info->place); +} + +int combatInit(void) +{ + // This is called once at the beginning of the game + memset(&Combat, 0, sizeof (Combat)); + + /* Initialize the place to safe defaults */ + Combat.state = COMBAT_STATE_DONE; + + return 0; +} + +void combat_reset_state(void) +{ + /* Initialize the place to safe defaults */ + fprintf(stderr,"combatreset\n"); + Combat.state = COMBAT_STATE_DONE; +} + +static void fill_map_half(struct terrain_map *map, int dx, int dy, + struct terrain *terrain) +{ + assert(dx || dy); + + if (dx < 0) { + // facing west, fill east half + terrain_map_fill(map, map->w / 2, 0, (map->w+1) / 2, map->h, + terrain); + } + else if (dx > 0) { + // facing east, fill west half + terrain_map_fill(map, 0, 0, map->w / 2, map->h, terrain); + } + else if (dy < 0) { + // facing north, fill south half + terrain_map_fill(map, 0, map->h / 2, map->w, (map->h+1) / 2, + terrain); + } + else if (dy > 0) { + // facing south, fill north half + terrain_map_fill(map, 0, 0, map->w, map->h / 2, terrain); + } +} + + +static void fill_temporary_terrain_map(struct terrain_map *map, + struct place *place, int x, int y, + int dx, int dy) +{ + struct terrain_map *tile_map; + struct terrain *terrain; + int dst_x = 0, dst_y = 0, src_x = 0, src_y = 0, src_w = 0, src_h = 0; + + assert(dx || dy); + assert(!(dx && dy)); + + if (dx < 0) { + + // facing west, fill east half + dst_x = map->w / 2; + dst_y = 0; + src_x = 0; + src_y = 0; + src_w = (map->w + 1) / 2; + src_h = map->h; + + } + else if (dx > 0) { + + // facing east, fill west half + dst_x = 0; + dst_y = 0; + src_x = map->w / 2; + src_y = 0; + src_w = (map->w) / 2; + src_h = map->h; + + } + else if (dy < 0) { + + // facing north, fill south half + dst_x = 0; + dst_y = map->h / 2; + src_x = 0; + src_y = 0; + src_w = map->w; + src_h = (map->h + 1) / 2; + + } + else if (dy > 0) { + + // facing south, fill north half + dst_x = 0; + dst_y = 0; + src_x = 0; + src_y = map->h / 2; + src_w = map->w; + src_h = (map->h)/ 2; + } + + tile_map = place_get_combat_terrain_map(place, x, y); + + if (tile_map) { + + // fixme -- instead of crashing at runtime, check for properly + // sized combat maps at load time (this will require the combat + // map dimensions to be also specified at load time or at least + // well-documented for map developers) + assert(tile_map->w >= (src_x + src_w)); + assert(tile_map->h >= (src_y + src_h)); + + // Use the combat map associated with the terrain type. + terrain_map_blit(map, dst_x, dst_y, tile_map, src_x, src_y, + src_w, src_h); + } + else { + // Fill with the terrain type. + terrain = place_get_terrain(place, x, y); + terrain_map_fill(map, dst_x, dst_y, src_w, src_h, terrain); + } +} + + +static void setup_combat_place_part(struct place *place, + struct terrain* our_terrain, struct terrain* other_terrain, + int dx, int dy, int mapx, int mapy) +{ + int dst_x = 0, dst_y = 0; + + if (our_terrain->renderCombat) + { + fprintf(stderr,"rc\n"); + if (dx < 0) { + // facing west, fill east half + dst_x = COMBAT_MAP_W / 2; + } + else if (dx > 0) { + // facing east, fill west half + dst_x = COMBAT_MAP_W / 2 - COMBAT_MAP_W; + } + else if (dy < 0) { + // facing north, fill south half + dst_y = COMBAT_MAP_H / 2; + } + else if (dy > 0) { + // facing south, fill north half + dst_y = COMBAT_MAP_H / 2 - COMBAT_MAP_H; + } + + closure_exec(our_terrain->renderCombat, "pppdddd", + place, our_terrain, other_terrain, + dst_x, dst_y, mapx, mapy); + } + else if (dx || dy) + { + fill_map_half(place->terrain_map, dx, dy, our_terrain); + } + else + { + terrain_map_fill(place->terrain_map, 0, 0, COMBAT_MAP_W, COMBAT_MAP_H, our_terrain); + } +} + + +static void setup_combat_place(struct place *place, struct combat_info + *info) +{ + struct terrain *player_terrain; + struct terrain *npc_terrain; + + // Determine orientation for both parties + // Also get true locations (after parties have moved to go from diagonal to adjacent) + if (!info->move->npc_party) + { + info->pc_dx = 0; + info->pc_dy = 0; + info->pc_x = player_party->getX(); + info->pc_y = player_party->getY(); + } + else if (info->defend) + { + info->pc_dx = -info->move->dx; + info->pc_dy = -info->move->dy; + info->pc_x = player_party->getX(); + info->pc_y = player_party->getY(); + info->npc_x = info->pc_x - info->move->dx; + info->npc_y = info->pc_y - info->move->dy; + } + else + { + info->pc_dx = info->move->dx; + info->pc_dy = info->move->dy; + info->npc_x = info->move->npc_party->getX(); + info->npc_y = info->move->npc_party->getY(); + info->pc_x = info->npc_x - info->move->dx; + info->pc_y = info->npc_y - info->move->dy; + } + + // get terrains for each + player_terrain=place_get_terrain(player_party->getPlace(), info->pc_x, info->pc_y); + + if (info->move->npc_party) + { + npc_terrain=place_get_terrain(info->move->npc_party->getPlace(), info->npc_x, info->npc_y); + } + else + { + npc_terrain=player_terrain; // some sensible definition makes like easier... + } + + setup_combat_place_part(place, player_terrain, npc_terrain, info->pc_dx, info->pc_dy, info->pc_x, info->pc_y); + if (info->move->npc_party) + { + setup_combat_place_part(place, npc_terrain, player_terrain, -info->pc_dx, -info->pc_dy, info->npc_x, info->npc_y); + } + +} + + +static struct terrain_map *create_temporary_terrain_map(struct combat_info + *info) +{ + struct terrain_map *map; + int player_dx, player_dy, npc_dx, npc_dy,pcmap_x,pcmap_y,npcmap_x,npcmap_y; + struct list *elem; + + // Create a map derived partially from the enemy's tile and + // partially from the player's tile. + + map = terrain_map_new("tmp_combat_map", COMBAT_MAP_W, COMBAT_MAP_H, + player_party->getPlace()->terrain_map->palette); + assert(map); + + terrain_map_fill(map, 0, 0, COMBAT_MAP_W, COMBAT_MAP_H, + place_get_terrain(player_party->getPlace(),player_party->getX(),player_party->getY())); + return map; + + // Determine orientation for both parties. + + + if (info->defend) { + player_dx = -info->move->dx; + player_dy = -info->move->dy; + npc_dx = info->move->dx; + npc_dy = info->move->dy; + pcmap_x = player_party->getX(); + pcmap_y = player_party->getY(); + npcmap_x = pcmap_x - info->move->dx; + npcmap_y = pcmap_y - info->move->dy; + } + else { + player_dx = info->move->dx; + player_dy = info->move->dy; + npc_dx = -info->move->dx; + npc_dy = -info->move->dy; + npcmap_x = info->move->npc_party->getX(); + npcmap_y = info->move->npc_party->getY(); + pcmap_x = npcmap_x - info->move->dx; + pcmap_y = npcmap_y - info->move->dy; + } + + // Fill the player's half of the combat map + fill_temporary_terrain_map(map, + player_party->getPlace(), + pcmap_x, pcmap_y, + player_dx, player_dy); + + // Fill the npc party's half of the combat map + fill_temporary_terrain_map(map, + info->move->npc_party->getPlace(), + npcmap_x, npcmap_y, + npc_dx, npc_dy); + + struct terrain_map *party_map = + place_get_combat_terrain_map(player_party->getPlace(), + player_party->getX(), + player_party->getY()); + struct terrain_map *npc_party_map = + place_get_combat_terrain_map(info->move->npc_party->getPlace(), + info->move->npc_party->getX(), + info->move->npc_party->getY()); + + // SAM: It seems that, until we can think of something + // more clever, (palette merging code? yech...) + // that all combat maps will have to have a palette + // in common. It may be more restrictive than I have + // stated, but I would need to research the question... + // + // SAM: + // Hmmm...ship-to-shore blits a map with a different palette + // onto a map with 'pal_standard', and this code has no way of seeing that. + // Possibly the map blitting should merge the palettes after all... + if (party_map && npc_party_map) { + dbg("maps '%s' '%s', palettes '%s' '%s'\n", + party_map->tag, npc_party_map->tag, + party_map->palette->tag, npc_party_map->palette->tag); + int palette_tags_match = !strcmp(party_map->palette->tag, + npc_party_map->palette->tag); + if (!palette_tags_match) { + dbg("create_temporary_terrain_map() warning: \n" + " Two combat maps (tags '%s' and '%s') \n" + " merging with dissimilar palettes (tags '%s' and '%s').\n" + " (This should work OK now, but be aware...)\n", + party_map->tag, npc_party_map->tag, + party_map->palette->tag, + npc_party_map->palette->tag); + // SAM: New code in palette_print() should enable us to carry on. + // assert(0); + } + } + struct terrain_map *the_map; + if (party_map) + the_map = party_map; + else if (npc_party_map) + the_map = npc_party_map; + else { + // No combat map for either location? + // Use the parent map (wilderness, or whatever) to get a palette. + // Since the terrain fill for each half is based on + // some terrain in the parent map, that palette should be appropriate. + assert(player_party->getPlace()->terrain_map); + the_map = player_party->getPlace()->terrain_map; + } + map->palette = the_map->palette; + //terrain_map_print(stdout, INITIAL_INDENTATION, map); + + + /* run all registered terrain blenders on the new map */ + list_for_each(&Session->blenders, elem) { + blender_t *blender=outcast(elem, blender_t, list); + terrain_map_blend(map, blender->inf, blender->n_nonsup, + blender->nonsup, blender->range); + } + + return map; +} + +static bool position_player_party(struct combat_info *cinfo) +{ + class Vehicle *vehicle; + + combat_fill_position_info(&player_party->pinfo, Place, + cinfo->move->x, cinfo->move->y, + cinfo->move->dx, cinfo->move->dy, + cinfo->defend); + + player_party->pinfo.formation = player_party->get_formation(); + if (!player_party->pinfo.formation) + player_party->pinfo.formation = formation_get_default(); + + // Check for map overlays. First check if the player is in a vehicle + // with a map. + vehicle = player_party->getVehicle(); + if (vehicle && + vehicle->getObjectType()->renderCombat && + Place == Combat.place) { + combat_overlay_vehicle(vehicle, cinfo->pc_dx, cinfo->pc_dy, + &player_party->pinfo); + } + + // Next check if the player is OVER (on the map) but not in a vehicle + // on the map. Note: this only applies to non-dungeon combat, and in a + // series of dungeon combats the player party may not have a place + // (because we remove it just below and the calling code does not + // relocate the player party until it returns to a town or wilderness. + else if (player_party->getPlace() && + (vehicle = place_get_vehicle(player_party->getPlace(), + player_party->getX(), + player_party->getY())) && + vehicle->getObjectType()->renderCombat) { + // dbg("party overlay, party over vehicle\n"); + combat_overlay_vehicle(vehicle, cinfo->pc_dx, cinfo->pc_dy, + &player_party->pinfo); + } + // Finally, since there is no vehicle map check for a camping map. + else if (cinfo->camping && player_party->campsite_map) { + // dbg("party overlay, party is camping\n"); + combat_overlay_map(player_party->campsite_map, + &player_party->pinfo, 0); + } + + if (player_party->isLoitering()) + { + player_party->forceAbortLoitering(); + } + player_party->remove(); + player_party->forEachReverseMember(combat_place_character, + &player_party->pinfo); + + return true; +} + +bool combat_enter(struct combat_info * info) +{ + struct location loc; + + if (player_party->allDead()) { + /* Yes, this can happen in some rare circumstances... */ + return false; + } + + /* Our map-building code assumes 4-neighbor adjacency. If attacking on + * a diagonal, randomly choose a cardinal direction. */ + if (info->move->dx && info->move->dy) + { + if (rand() % 2) { + info->move->dx = 0; + } else { + info->move->dy = 0; + } + } + + // -------------------------------------------------------------------- + // Default to the entry point as the combat exit location for the + // player party. + // -------------------------------------------------------------------- + + loc.place = info->move->place; + loc.x = info->move->x; + loc.y = info->move->y; + + + // *** Initialize Combat Globals *** + + Combat.enemy_vehicle = NULL; + Combat.round = 0; + Session->crosshair->remove(); + + if (! info->move->place->wilderness) { + + // ------------------------------------------------------------ + // When not in the wilderness use the current place for combat. + // ------------------------------------------------------------ + Place = info->move->place; + } + else { + + // ------------------------------------------------------------ + // Create a temporary place for combat in the wilderness. It's + // parent will be the wilderness. We have to set a special flag + // to indicate that it's wilderness combat (used for things + // like exit policy). + // ------------------------------------------------------------ + + Combat.place = place_new("p_wilderness_combat", + "Wilderness Combat", + 0, // sprite + create_temporary_terrain_map(info), + 0, // ! wrapping + info->move->place->underground, + 0, // ! wilderness + 1 // wilderness combat + ); + + Combat.place->is_wilderness_combat = 1; + Combat.place->location.place = info->move->place; + Combat.place->location.x = info->move->px; + Combat.place->location.y = info->move->py; + + setup_combat_place(Combat.place,info); + + place_add_subplace(info->move->place, Combat.place, + info->move->px, info->move->py); + + Place = Combat.place; + } + + mapSetPlace(Place); + + // *** Position the Player Companions *** + + // This is where the map overlays on the player side of the map get + // placed, if any. + if (!position_player_party(info)) + return false; + + // *** Position the Enemy Party Members *** + + if (info->move->npc_party) { + + + /* combat_position_enemy() will decrement most of the refcounts + * ont he party, keep it alive until we're done */ + obj_inc_ref(info->move->npc_party); + + if (!combat_position_enemy(info->move->npc_party, + info->move->dx, info->move->dy, + !info->defend, Place)) { + log_begin("*** FORFEIT ***"); + log_msg("Your opponent slips away!"); + log_end(NULL); + combat_set_state(COMBAT_STATE_LOOTING); + } + else + { + combat_set_state(COMBAT_STATE_FIGHTING); + } + + /* done with it now */ + obj_dec_ref(info->move->npc_party); + info->move->npc_party = NULL; + + } + else if (info->camping) { + + combat_set_state(COMBAT_STATE_CAMPING); + log_msg("Zzzz..."); + } + else { + struct v2 v2; + v2.dx = info->move->dx; + v2.dy = info->move->dy; + v2.place = Place; + combat_set_state(COMBAT_STATE_DONE); + place_for_each_object(Place, combat_find_and_position_enemy, + &v2); + } + + player_party->forEachMember(mySetInitialCameraPosition, 0); + + if (combat_get_state() == COMBAT_STATE_FIGHTING) { + player_party->enableRoundRobinMode(); + sound_play(Combat.sound_enter, SOUND_MAX_VOLUME); + } + else if (combat_get_state() != COMBAT_STATE_CAMPING) { + player_party->enableFollowMode(); + } + + // --------------------------------------------------------------------- + // Force a map update. If an npc initiates combat then the event + // handler will not run and do a repaint until the next event. + // --------------------------------------------------------------------- + + mapUpdate(0); + foogodRepaint(); + + // --------------------------------------------------------------------- + // Return to the main loop. Combat will continue from there. + // --------------------------------------------------------------------- + return true; +} + +char combatGetState(void) +{ + switch (Combat.state) { + case COMBAT_STATE_FIGHTING: + return 'Y'; + break; + case COMBAT_STATE_DONE: + return 'N'; + break; + case COMBAT_STATE_LOOTING: + return 'V'; + break; + case COMBAT_STATE_CAMPING: + return 'K'; + break; + } + + return 'N'; +} + +int combat_add_party(class Party * party, int dx, int dy, int located, + struct place *place, int x, int y) +{ + int added = 0; + + obj_inc_ref(party); + + if (!located) { + // Caller has not specified a location so use the normal + // procedure. + added = combat_position_enemy(party, dx, dy, false, place); + obj_dec_ref(party); + return added; + } + + // Special case: caller wants to put the party at (x, y). Duplicate the + // code in combat_position_enemy except fill out the position info + // based on caller's request. + party->disembark(); + party->remove(); + + memset(&party->pinfo, 0, sizeof (party->pinfo)); + party->pinfo.place = place; + party->pinfo.x = x; + party->pinfo.y = y; + party->pinfo.dx = dx; + party->pinfo.dy = dy; + party->pinfo.formation = party->get_formation(); + party->pinfo.find_party = true; + if (!party->pinfo.formation) + party->pinfo.formation = formation_get_default(); + set_party_initial_position(&party->pinfo, x, y); + myPutEnemy(party, &party->pinfo); + + added = party->pinfo.placed; + + obj_dec_ref(party); + + return added; + +} + +void combat_exit(void) +{ + struct place *parent = 0; + int x, y; + + // Clean up the temporary combat place, if we used one. If we started + // off in combat when we loaded this session then we need to remove + // the temp place and temp map from the session's list of objects + // to save. We can tell that we need to remove them if they have + // non-null handles (those handles are only set by the loader, if + // we create the tmp place during normal game play we don't set them). + // + // Before destroying the place I have to memorize it's location for the + // next step. + if (Place->is_wilderness_combat) { + + //assert(! Place->handle); // should not be top-level + assert(place_get_parent(Place)); + + if (Place->terrain_map->handle) + session_rm(Session, Place->terrain_map->handle); + + place_remove_and_destroy_all_objects(Place); + parent = place_get_parent(Place); + x = place_get_x(Place); + y = place_get_y(Place); + place_remove_subplace(parent, Place); + + // Bugfix: Invalidate the entire map from the vmask cache. If + // you don't do this, then the next time the player enters + // combat and we start looking up vmasks we will find old, + // stale ones from this place, resulting in LOS bugs. That's + // because the keys used by the vmask are built from the name + // of the place, and for the combat map it is always the same + // name. + vmask_invalidate(Place, 0, 0, place_w(Place), place_h(Place)); + + // If this place has a handle it's in the session list and + // needs to be removed before we destroy it, otherwise on + // session reload it will be deleted again. + if (Place->handle) + session_rm(Session, Place->handle); + + place_del(Place); // map deleted in here + Combat.place = 0; + + // ------------------------------------------------------------ + // Relocate the player party back to the wilderness. This will + // handle the place switch implicitly by setting the global + // 'Place' pointer to the wilderness. + // ------------------------------------------------------------ + + player_party->relocate(parent, x, y); + + } + + assert(NULL != player_party->getPlace()); + + // -------------------------------------------------------------------- + // Force a map update. Although the map has been marked dirty by now, + // we will not see a repaint until the next event if we do not act + // now. This routine is called from the context of the main play loop, + // not the event loop. + // -------------------------------------------------------------------- + + //mapUpdate(0); + +} diff --git a/src/combat.h b/src/combat.h new file mode 100644 index 0000000..5623be3 --- /dev/null +++ b/src/combat.h @@ -0,0 +1,73 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef combat_h +#define combat_h + +#define COMBAT_MAP_W 19 +#define COMBAT_MAP_H 19 + +class Character; + +extern int combatInit(void); +extern int combatLoad(class Loader *loader); +extern char combatGetState(void); + +/* This is needed for walking around while zoomed out. Currently only the + special ^Z command (which is intended for map editing) uses it. */ +extern void combatGetCameraCenter(int *x, int *y); + + +#include "player.h" // for struct move_info +struct combat_info { + int hours; // for moving into camping + class Character *guard; // for moving into camping + bool defend; // for moving into combat- true if PC is defending + bool camping; // for moving into combat + struct move_info *move; + int pc_x; // cache for final location of player party + int pc_y; + int npc_x; // cache for final location of npc party + int npc_y; + int pc_dx; // cache for final delta + int pc_dy; +}; + +enum combat_state { + COMBAT_STATE_FIGHTING, + COMBAT_STATE_LOOTING, + COMBAT_STATE_CAMPING, + COMBAT_STATE_DONE +}; + +extern enum combat_state combat_get_state(void); +extern void combat_set_state(enum combat_state); +extern void combat_reset_state(void); +extern bool combat_enter(struct combat_info *info); +extern bool combat_rendezvous_party(int max_path_len); +extern void combat_exit(void); +extern void combat_analyze_results_of_last_turn(void); +extern void combat_fill_position_info(struct position_info *info, struct place *place, int x, int y, int dx, int dy, bool defend); +extern bool combat_place_character(class Character * pm, void *data); +extern int combat_add_party(class Party *party, int dx, int dy, int located, + struct place *place, int x, int y); + +#endif diff --git a/src/common.c b/src/common.c new file mode 100644 index 0000000..de6db29 --- /dev/null +++ b/src/common.c @@ -0,0 +1,242 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "common.h" +#include "sky.h" +#include "screen.h" +#include "player.h" +#include "foogod.h" +#include "place.h" +#include "event.h" +#include "console.h" + +#include +#include + +int Turn; +int Tick; +int AnimationTicks; +int TickMilliseconds; +// int WindDirection; +int ShowAllTerrain = 0; + +struct los *LosEngine; + + +int commonInit(void) +{ + Turn = 0; + Tick = 0; + srand(0); + return 0; +} + +// fixme -- obsolete, use the next one +static const char *dir_str[] = { + "Northwest", "North", "Northeast", + "West", "Here", "East", + "Southwest", "South", "Southeast", + "Up", "Down" +}; + +static unsigned char dir_facing[] = { + WEST, NORTH, EAST, + WEST, NORTH, EAST, + WEST, SOUTH, EAST, +}; + +static unsigned char dir_8facing[] = { + NORTHWEST, NORTH, NORTHEAST, + WEST, NORTH, EAST, + SOUTHWEST, SOUTH, SOUTHEAST, +}; + +static int direction_to_rotation_tbl[] = { + 315, 0, 45, + 270, 0, 90, + 225, 180, 135, +}; + +static int directionToDxTable[] = { + -1, 0, +1, + -1, 0, +1, + -1, 0, +1, + 0, 0, +}; + +static int directionToDyTable[] = { + -1, -1, -1, + 0, 0, 0, + +1, +1, +1, + 0, 0, +}; + +static int keyToDirectionTable[] = { + SOUTHWEST, SOUTH, SOUTHEAST, + WEST, HERE, EAST, + NORTHWEST, NORTH, NORTHEAST +}; + +const char *directionToString(int dir) +{ + if (dir < 0 || dir >= array_sz(dir_str)) + return "*** invalid direction ***"; + return dir_str[dir]; +} + +int stringToDirection(char *str) +{ + unsigned int i; + for (i = 0; i < array_sz(dir_str); i++) { + if (!strncasecmp(dir_str[i], str, strlen(dir_str[i]))) + return i; + } + return -1; +} + +int directionToOpposite(int dir) +{ + static int tbl[] = { + SOUTHEAST, + SOUTH, + SOUTHWEST, + EAST, + HERE, + WEST, + NORTHEAST, + NORTH, + NORTHWEST, + DOWN, + UP + }; + + if (dir < 0 || dir >= array_sz(tbl)) + return DIRECTION_NONE; + + return tbl[dir]; +} + +int keyToDirection(int key) +{ + return keyToDirectionTable[key - KEY_SOUTHWEST]; +} + +int directionToDx(int dir) +{ + return directionToDxTable[dir]; +} + +int directionToDy(int dir) +{ + return directionToDyTable[dir]; +} + +const char *get_dir_str(int dx, int dy) +{ + clamp(dx, -1, 1); + clamp(dy, -1, 1); + return dir_str[(dy + 1) * 3 + dx + 1]; +} + +int vector_to_facing(int dx, int dy) +{ + clamp(dx, -1, 1); + clamp(dy, -1, 1); + return dir_facing[(dy + 1) * 3 + dx + 1]; +} + +int vector_to_8facing(int dx, int dy) +{ + if (abs(dx) > 2* (abs(dy))) + { + dy = 0; + } + else if (abs(dy) > 2* (abs(dx))) + { + dx = 0; + } + clamp(dx, -1, 1); + clamp(dy, -1, 1); + return dir_8facing[(dy + 1) * 3 + dx + 1]; +} + +int vector_to_rotation(int dx, int dy) +{ + clamp(dx, -1, 1); + clamp(dy, -1, 1); + return direction_to_rotation_tbl[(dy + 1) * 3 + dx + 1]; +} + +int vector_to_dir(int dx, int dy) +{ + int adx = abs(dx); + int ady = abs(dy); + + // Note: north is in the negative x direction, south in the positive + + if (ady > adx) { + if (dy > 0) + return SOUTH; + else + return NORTH; + } else { + if (dx > 0) + return EAST; + else + return WEST; + } +} + +bool isvowel(char c) +{ + return (c == 'a' || c == 'A' || + c == 'e' || c == 'E' || + c == 'i' || c == 'I' || + c == 'o' || c == 'O' || + c == 'u' || c == 'U' || c == 'y' || c == 'Y'); +} + +bool point_in_rect(int x, int y, SDL_Rect *rect) +{ + return (x >= rect->x && + y >= rect->y && + x < (rect->x + rect->w) && + y < (rect->y + rect->h)); +} + +int logBase2(int val) +{ + int ret = 0; + + if (val<=0) + return 0; /* incorrect but safe */ + + val -= 1; + + while (val) { + val>>=1; + ret++; + } + + return ret; +} + + diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..c93ee43 --- /dev/null +++ b/src/common.h @@ -0,0 +1,337 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef common_h +#define common_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include "list.h" +#include "debug.h" +#include "los.h" +#include "dup_constants.h" + +#include +#include +#include + +/* Constants *****************************************************************/ + +/* Directions */ +#define DIRECTION_NONE -1 +#define NORTHWEST 0 +#define NORTH 1 +#define NORTHEAST 2 +#define WEST 3 +#define HERE 4 +#define EAST 5 +#define SOUTHWEST 6 +#define SOUTH 7 +#define SOUTHEAST 8 +#define UP 9 +#define DOWN 10 +#define NUM_DIRECTIONS 11 +#define NUM_PLANAR_DIRECTIONS 9 +#define NUM_WIND_DIRECTIONS 9 +#define IS_LEGAL_DIRECTION(dir) ((dir)>=0 && (dir) (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define clamp(v,a,b) ((v) = (v) < (a) ? (a) : ((v) > (b) ? (b) : (v))) +#define array_sz(a) (int)(sizeof((a))/sizeof((a)[0])) +#define outcast(ptr,type,field) \ + ((type*)((char*)(ptr)-(unsigned long)(&((type *)0)->field))) +#define CREATE(ptr,type,err) \ + (ptr) = (type*)malloc(sizeof(type)); \ + if (!(ptr)) \ + return (err); \ + memset((ptr), 0, sizeof(type)); +#define distance(dx,dy) (((dx)>(dy)) ? ((dx)+((dy)>>1)) : ((dy)+ (dx)>>1))) + + +// SAM: The below are used by palette_print(), terrain_map_print(), etc. +#define INITIAL_INDENTATION 0 +#define INDENTATION_FACTOR 2 +#define INDENT fprintf(fp, "%*s", indent, "") + +/* Enums *********************************************************************/ + +typedef enum { + UI_SIZE_NORMAL = 0, + UI_SIZE_SMALL = 1 +} ui_size_t; + +/* Structures ****************************************************************/ + +/* Global Functions **********************************************************/ + +char * version_as_string(void); // From nazghul.c + +extern int commonInit(void); +extern const char *get_dir_str(int dx, int dy); +extern void turnAdvance(int turns); +extern int vector_to_dir(int dx, int dy); +extern int vector_to_facing(int dx, int dy); +extern int vector_to_rotation(int dx, int dy); +extern int vector_to_8facing(int dx, int dy); + +extern int stringToDirection(char *str); +extern int keyToDirection(int key); +extern int directionToDx(int dir); +extern int directionToDy(int dir); +extern const char *directionToString(int dir); +extern bool isvowel(char c); +extern bool point_in_rect(int x, int y, SDL_Rect *rect); +extern int directionToOpposite(int dir); + +#define keyIsDirection(key) ((key) >= KEY_SOUTHWEST && (key) <= KEY_NORTHEAST) + +/* Global Variables **********************************************************/ + +extern int Turn; +extern int AnimationTicks; +extern int Tick; +extern int TickMilliseconds; +extern bool Quit; +extern struct los *LosEngine; +extern int ShowAllTerrain; +extern int logBase2(int val); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/console.c b/src/console.c new file mode 100644 index 0000000..49c2fd7 --- /dev/null +++ b/src/console.c @@ -0,0 +1,460 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "console.h" +#include "screen.h" +#include "common.h" +#include "sprite.h" +#include "play.h" +#include "event.h" +#include "cmd.h" // for getkey() +#include "foogod.h" // for foogod_get_y() + +#include +#include +#include +#include +#include + +#define MAX_MSG_SZ 512 +#define CONS_BUF_SIZE (CONS_LINES * (CONSOLE_MAX_MSG_SZ + 1)) + +static struct console { + SDL_Rect screenRect; + char *buf; /* text buffer */ + char **lines; /* pointers into buf, one per line */ + int line; /* current line index */ + char *cursor; /* next byte on current line */ + int room; /* bytes left on current line */ + int numLines; /* num lines filled + current line */ + + int firstLine; // index into 'lines' array of the first filled + // line (the lines array is a circular buffer, * + // so once all the lines are filled this value * + // advances every time the 'line' value * + // advances) + + int repeat; // counts number of times last line repeats + +#ifdef DEBUG + FILE *log; +#endif +} Console; + +static char console_scratch_buf[MAX_MSG_SZ + 1]; +static char console_last_msg[MAX_MSG_SZ + 1]; + +static void consoleNewline(void); + +static int consolePage(void) +{ + int yesno = 1; + + consolePrint("---More-Y/N?"); + consoleRepaint(); + getkey(&yesno, yesnokey); + consoleBackspace(12); + return yesno == 'y'; +} + +int consoleInit(void) +{ + int i; + + Console.screenRect.x = CONS_X; + Console.screenRect.w = CONS_W; + + //console_set_y(foogod_get_y() + FOOGOD_H + BORDER_H); + + Console.buf = (char *)malloc(CONS_BUF_SIZE); + if (! Console.buf) + return -1; + memset(Console.buf, 0, CONSOLE_MAX_MSG_SZ + 1); + + Console.cursor = Console.buf; + Console.room = CONSOLE_MAX_MSG_SZ; + Console.line = 0; + Console.firstLine = 0; + Console.repeat = 0; + + /* Unintuitively, numLines must begin with 1. I only advance it for + * newlines, and if someone prints text on the very first line without + * issuing a newline then it needs to be rendered in the repaint + * routine. In other words, I always pretend that the current line has + * something on it. */ + Console.numLines = 1; + Console.lines = (char**)malloc(CONS_LINES * sizeof(char*)); + if (!Console.lines) + return -1; + for (i = 0; i < CONS_LINES; i++) + Console.lines[i] = &Console.buf[i * (CONSOLE_MAX_MSG_SZ + 1)]; + +#ifdef DEBUG + /* Open the console log file. */ + Console.log = fopen(".console", "w"); + if (Console.log == NULL) { + perror(".console"); + } +#endif + + return 0; +} + +static int console_handle_repeated_msg(void) +{ + + // Is this a repeat? + if (strchr(console_scratch_buf, '\n') == 0 || + (strcmp(console_scratch_buf, console_last_msg) != 0) || + (strcmp(console_scratch_buf, "\n") == 0)) { + + // No. Was the previous message a repeat? + if (Console.repeat != 0) { + // Yes, So we need to advance past the 'repeat' msg + // which occupies its own line + consoleNewline(); + } + // Setup for new msg. + Console.repeat = 0; + strcpy(console_last_msg, console_scratch_buf); + return 0; + } + + // Yes, this is a repeat. + Console.repeat++; + + // Is this the first repeat for the msg? + if (Console.repeat == 1) { + // Yes. Are we at the beginning of a new line? + if (Console.room != CONSOLE_MAX_MSG_SZ) { + // No. So advance to a new line. + consoleNewline(); + } + // Print the repeat notice for the first time. + snprintf(Console.lines[Console.line], CONSOLE_MAX_MSG_SZ, + "[again]"); + Console.room -= strlen(Console.lines[Console.line]); + Console.cursor += strlen(Console.lines[Console.line]); + + } else { + // No. This is not the first time we've repeated this + // msg. Erase the previous 'repeat' notice and print a new one + // with the updated repeat count. + memset(Console.lines[Console.line], 0, CONSOLE_MAX_MSG_SZ + 1); + snprintf(Console.lines[Console.line], CONSOLE_MAX_MSG_SZ, + "[%d times]", Console.repeat); + } + + consoleRepaint(); + + return 1; +} + +void consolePrint(const char *fmt, ...) +{ + int printed; + va_list args; + char *ptr, *eow; + int n_lines = 0, wlen; + int words = 0; + int wrapped; + + /* Print message to the scratch buffer */ + va_start(args, fmt); + printed = vsnprintf(console_scratch_buf, MAX_MSG_SZ, fmt, args); + va_end(args); + +#ifdef DEBUG + if (Console.log != NULL) + vfprintf(Console.log, fmt, args); +#endif + + /* Check if message was truncated to fit. Note that I discard anything + * that will not fit. */ + if (printed == -1) + printed = MAX_MSG_SZ; + + // Is this a repeat of the last msg? + if (console_handle_repeated_msg()) + // Yes. Already handled. + return; + + /* + * Now transfer the contents of the scratch buffer to the line + * buffers. I use the following rules: + * + * 1. A word is a run of non-ws chars. + * + * 2. When starting a new line after wrapping discard FIRST initial ws. + * + * 3. When starting a new line print the first word. If the first will + * not fit on the line then print as much as possible and start a new + * line with the remainder. + * + * 4. After printing a word print all whitespace up to the next word or + * the end of the current line. + * + * 5. After printing ws probe the next word to find it's length. If the + * word will not fit then start a new line and apply rule 3. Otherwise + * print the word and apply rule 4. + * + * 6. After starting a new line check if the message window is full. If + * so then prompt the user before continuing. This gives the user a + * chance to read everything printed thus far. + * + * 7. All but the first newline are indented by a space to help make + * visual blocks of text. + * + */ + ptr = console_scratch_buf; + + wrapped = 0; + + /* copy from the super buffer to the line buffer(s) */ + while (printed) { + + /* Check if this is the start of a new line and if so then + * apply rules 2 and 3. */ + if (Console.room == CONSOLE_MAX_MSG_SZ) { + + /* Rule 2 */ + while (isspace(*ptr) && printed) { + + if (!wrapped) { + if (*ptr == '\n') { + ptr++; + printed--; + goto newline; + } + + /* copy the char */ + *Console.cursor = *ptr; + Console.room--; + Console.cursor++; + } + wrapped = 0; + ptr++; + printed--; + } + + /* Rule 3 */ + while (!isspace(*ptr) && printed && Console.room) { + + /* copy the char */ + *Console.cursor = *ptr; + + /* advance source and destination */ + printed--; + ptr++; + Console.room--; + Console.cursor++; + } + + words++; + + /* Check for end-of-line */ + if (!Console.room) { + wrapped = 1; + goto newline; + } + + } + + /* Ok. We have already printed at least one word on this line + * and now need to apply Rule 4: print all ws up to end-of-line + * or start-of-word. */ + + wrapped = 0; + + while (isspace(*ptr) && Console.room && printed) { + + if (*ptr == '\n') { + ptr++; + printed--; + goto newline; + } + + /* copy the char */ + *Console.cursor = *ptr; + + /* advance source and destination */ + printed--; + ptr++; + Console.room--; + Console.cursor++; + } + + if (!Console.room) { + wrapped = 1; + goto newline; + } + + if (!printed) + break; + + /* All right. At this point I know I have space left and + * another word to print. Rule 5. */ + eow = strpbrk(ptr, " \t\n\r"); + if (eow) + wlen = eow - ptr; + else + wlen = printed; + + if (wlen > Console.room) { + wrapped = 1; + goto newline; + } + + while (wlen) { + /* copy the char */ + *Console.cursor = *ptr; + + /* advance source and destination */ + printed--; + ptr++; + Console.room--; + Console.cursor++; + wlen--; + } + + words++; + + continue; + + newline: + + /* advance to the next line */ + consoleNewline(); + n_lines++; + + /* Rule 6 */ + if (n_lines == (CONS_LINES - 1)) { + if (!consolePage()) + return; + n_lines = 0; + } + + /* Start of new line so go back to top-of-loop so I can run the + * start-of-line code. */ + continue; + } + + consoleRepaint(); +} + +void consoleBackspace(int n) +{ + int len; + + /* Don't allow backspace beyond end of prompt */ + len = CONSOLE_MAX_MSG_SZ - Console.room; + if (len > n) + len = n; + + /* Backup */ + Console.cursor -= len; + Console.room += len; + + /* Erase everything beyond the Console.cursor */ + memset(Console.cursor, 0, Console.room); + // *Console.cursor = 0; + +#ifdef DEBUG + if (Console.log != NULL) + fprintf(Console.log, "\b"); +#endif +} + +static void consoleNewline(void) +{ + Console.line = (Console.line + 1) % CONS_LINES; + + if (Console.numLines < (CONS_LINES)) + Console.numLines++; + else + Console.firstLine = (Console.firstLine + 1) % CONS_LINES; + + Console.cursor = Console.lines[Console.line]; + + memset(Console.cursor, 0, CONSOLE_MAX_MSG_SZ + 1); + Console.room = CONSOLE_MAX_MSG_SZ; + +#ifdef DEBUG + if (Console.log != NULL) + fprintf(Console.log, "\n"); +#endif + + //consoleRepaint(); +} + +void consoleRepaint(void) +{ + SDL_Rect rect; + int n_lines; + int max_lines; + int line; + + //screenErase(&Console.screenRect); + + rect.x = Console.screenRect.x; + rect.w = Console.screenRect.w; + rect.y = console_get_y(); + rect.h = console_get_h(); + + screenErase(&rect); + + max_lines = rect.h / ASCII_H; + n_lines = min(Console.numLines, max_lines); + + /* Find the first visible line in the line buffer by backing up from + * the current line. If I need to back up past the beginning then wrap + * around to the end. */ + if (n_lines > (Console.line + 1)) { + line = CONS_LINES - (n_lines - (Console.line + 1)); + } else { + line = (Console.line + 1) - n_lines; + } + + while (n_lines--) { + screenPrint(&rect, 0, Console.lines[line]); + line = (line + 1) % CONS_LINES; + rect.y += ASCII_H; + } + + screenUpdate(&Console.screenRect); +} + +int console_get_y(void) +{ + return (foogod_get_y() + foogod_get_h()); +} + +int console_get_h(void) +{ + return (SCREEN_H - BORDER_H - console_get_y()); +} + +int console_max_lines (void) { + int max_lines; + + max_lines = Console.screenRect.h / ASCII_H; + return min(Console.numLines, max_lines); +} diff --git a/src/console.h b/src/console.h new file mode 100644 index 0000000..d3b7995 --- /dev/null +++ b/src/console.h @@ -0,0 +1,41 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef console_h +#define console_h + +#ifdef __cplusplus +extern "C" { +#endif + + extern int consoleInit(void); + extern void consolePrint(const char *fmt, ...); + extern void consoleBackspace(int n); + //extern void consoleNewline(void); + extern void consoleRepaint(void); + //extern void console_set_y(int y); + extern int console_get_y(void); + extern int console_get_h(void); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/constants.h b/src/constants.h new file mode 100644 index 0000000..47b703a --- /dev/null +++ b/src/constants.h @@ -0,0 +1,42 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef constants_h +#define constants_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * User-defined event types + */ + +/* + * Defaults for configurable parameters. + */ +#define DEFAULT_SCREEN_WIDTH 640 +#define DEFAULT_SCREEN_HEIGHT 480 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/conv.c b/src/conv.c new file mode 100644 index 0000000..bce92b1 --- /dev/null +++ b/src/conv.c @@ -0,0 +1,1015 @@ +#ifndef TEST_PORTRAITS + + +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +#include "character.h" +// + +#include "bitset.h" +#include "conv.h" +#include "cfg.h" +#include "event.h" +#include "cmdwin.h" +#include "common.h" +#include "object.h" +#include +#include "closure.h" +#include "log.h" +#include "scheme-private.h" /* for keyword processing */ +#include "session.h" + +#include +#include +#include +#include + +#define MAX_KEYWORD_SZ 16 + +/** + * Conversation structure. + */ +struct conv { + struct closure *proc; /* Closure which responds to keywords. */ + int ref; /* Reference count. */ + int n_keywords; /* Size of the keywords array. */ + char **keywords; /* Keyword array. */ + bitset_t *marked; /* Used keywords */ +}; + +static int conv_room, conv_len; +static char conv_query[64], *conv_ptr; +static int conv_done; +static int conv_keyword_highlighting = 1; + +/** + * Keyhandler callback for processing player keystrokes while collecting the + * query string. This stores typed characters into the conv_query buffer. + * + * @param kh is the keyhandler pushed for input handling. + * @param key is the key the player just typed. + * @returns 1 if the player is done entering the query, else 0. + */ +static int conv_get_player_query(struct KeyHandler *kh, int key, int keymod) +{ + if (key == CANCEL) { + while (conv_ptr > conv_query) { + conv_ptr--; + *conv_ptr = 0; + cmdwin_pop(); + conv_room++; + } + return 1; + } + + if (key == '\n') { + return 1; + } + + if (key == '\b') { + if (conv_ptr != conv_query) { + conv_ptr--; + *conv_ptr = 0; + conv_room++; + cmdwin_pop(); + } + return 0; + } + + if (isprintable(key) + && conv_room) { + cmdwin_push("%c", key); + *conv_ptr++ = key; + conv_room--; + } + + return 0; +} + + +/** + * Force the player query to a value. This is mainly done to start the + + * conversation off with the "HAIL" keyword. + * + * @param str is the query value to set. + */ +static void conv_set_query(const char *str) +{ + snprintf(conv_query, sizeof(conv_query) - 1, "%s", str); + conv_query[MAX_KEYWORD_SZ] = 0; + conv_len = strlen(conv_query); +} + +/** + * Internal destructor for a conversation struct. + * + * @param conv is the conversation to delete. + */ +static void conv_del(struct conv *conv) +{ + if (conv->proc) { + closure_unref(conv->proc); + } + + if (conv->keywords) { + + int i; + + for (i = 0; i < conv->n_keywords; i++) { + if (conv->keywords[i]) { + free(conv->keywords[i]); + } + } + + free(conv->keywords); + } + + if (conv->marked) { + bitset_free(conv->marked); + } + + free(conv); +} + +/** + * Callback used by the sort function to compare two values. + * + * @param p1 is one value. + * @param p2 is the other value. + * @returns 1 if p1>p2, 0 if p1==p2, -1 if p1 cptr. + */ +static int conv_prefix_cmp(char *wptr, char *cptr) +{ + int len = 0; + + while (*wptr && *cptr) { + char wc = tolower(*wptr++); + char cc = tolower(*cptr++); + len++; + int d = wc - cc; + if (d != 0) { + return d; + } + } + + if (*cptr && ! *wptr) { + /* candidate is longer than word */ + return -1; + } + + if (*wptr && !isspace(*wptr) && !ispunct(*wptr) && len < 4) { + /* candidate is short but word is not */ + return 1; + } + + return 0; +} + +/** + * Check if a word is a keyword. + * + * @conv is the conversation to check. + * @word is the word to look for in the keywords. + * @returns the index of the matching keyword, else -1 if not found. + */ +static int conv_lookup_keyword(struct conv *conv, char *word) +{ + int min = 0, max = conv->n_keywords, pivot; + + while (max > min) { + + /** + * apricot + * + * aardvark + * abacus + * + * zoo + * zebra + */ + + pivot = ((max-min)/2) + min; + + int d = conv_prefix_cmp(word, conv->keywords[pivot]); + + if (d > 0) { + /* word > pivot => search higher */ + min = pivot + 1; + } else if (d < 0) { + /* word < pivot => search lower */ + max = pivot; + } else { + return pivot; + } + } + + return -1; +} + +/** + * Check if a word is a keyword and, if so, to mark it (marking is used to show + * the player which keywords have already been used in a conversation). + * + * @conv is the conversation to check. + * @word is the word to look for in the keywords. + */ +static void conv_mark_if_keyword(struct conv *conv, char *word) +{ + int index = conv_lookup_keyword(conv, word); + if (index != -1) { + bitset_set(conv->marked, index); + } +} + +static int conv_add_keyword(struct conv *conv, char *keyword, int key_index) +{ + assert(key_index < conv->n_keywords); + if (!(conv->keywords[key_index] = strdup(keyword))) { + warn("%s: strdup failed on %s", __FUNCTION__, keyword); + return -1; + } + return 0; +} + +static void conv_sort_keywords(struct conv *conv) +{ + qsort(conv->keywords, conv->n_keywords, sizeof(char*), conv_sort_cmp); +} + +static void conv_highlight_keywords(struct conv *conv) +{ + int key_index = 0; + scheme *sc = conv->proc->sc; + pointer sym = conv->proc->code; + + assert(sc); + assert(sym); + + if (sym == sc->NIL) { + warn("%s: conv proc not a symbol", __FUNCTION__); + return; + } + + pointer ifc = sc->vptr->find_slot_in_env(sc, sc->envir, sym, 1); + if (! scm_is_pair(sc, ifc)) { + warn("%s: conv '%s' has no value", __FUNCTION__, scm_sym_val(sc, sym)); + return; + } + + pointer clos = scm_cdr(sc, ifc); + if (! scm_is_closure(sc, clos)) { + warn("%s: conv '%s' not a closure", __FUNCTION__, scm_sym_val(sc, sym)); + return; + } + + pointer env = scm_cdr(sc, clos); + pointer vtable = scm_cdr(sc, scm_car(sc, scm_car(sc, env))); + + conv->n_keywords = scm_len(sc, vtable); + + if (!(conv->keywords = (char**)calloc(conv->n_keywords, sizeof(char*)))) { + warn("%s: failed to allocate keyword array size %d", __FUNCTION__, conv->n_keywords); + return; + } + + if (!(conv->marked = bitset_alloc(conv->n_keywords))) { + warn("%s: failed to allocate bitset array size %d", __FUNCTION__, conv->n_keywords); + return; + } + + while (scm_is_pair(sc, vtable)) { + pointer binding = scm_car(sc, vtable); + vtable = scm_cdr(sc, vtable); + pointer var = scm_car(sc, binding); + if (conv_add_keyword(conv, scm_sym_val(sc, var), key_index)) { + return; + } + key_index++; + } + + conv_sort_keywords(conv); +} + +struct conv *conv_new(struct closure *proc) +{ + struct conv *conv; + + if (!(conv = (struct conv*)calloc(1, sizeof(*conv)))) { + return NULL; + } + + conv->ref = 1; + conv->proc = proc; + closure_ref(proc); + + return conv; +} + +void conv_save(struct conv *conv, struct save *save) +{ + closure_save(conv->proc, save); +} + +void conv_unref(struct conv *conv) +{ + assert(conv->ref>0); + conv->ref--; + if (!conv->ref) { + conv_del(conv); + } +} + +void conv_ref(struct conv *conv) +{ + conv->ref++; +} + +void conv_end() +{ + conv_done = 1; +} + +void conv_enter(Object *npc, Object *pc, struct conv *conv) +{ + struct KeyHandler kh; + + assert(conv); + + if (! conv->keywords && conv_keyword_highlighting) { + conv_highlight_keywords(conv); + } + + /* If NPC initiates conversation, make sure we have a valid session + * subject, else describe() will crash when determining if unknown NPC + * is hostile or not. */ + if (! Session->subject) { + Session->subject = (class Being*)pc; + } + + log_banner("^c+yCONVERSATION^c-"); + + session_run_hook(Session, conv_start_hook, "pp", pc, npc); + + conv_done = 0; + kh.fx = conv_get_player_query; + conv_set_query("hail"); + + for (;;) { + + /* Truncate the query to 4 characters */ + conv_query[4] = 0; + + conv_mark_if_keyword(conv, conv_query); + + /* If query was NAME, assume the NPC is now known */ + if (!strcasecmp(conv_query, "NAME")) { + ((class Character*)npc)->setKnown(true); + } + + /* Query the NPC */ + closure_exec(conv->proc, "ypp", conv_query, npc, pc); + + if (conv_done) + break; + + /*** Setup for next query ***/ + + memset(conv_query, 0, sizeof(conv_query)); + conv_room = sizeof(conv_query) - 1; + conv_ptr = conv_query; + + cmdwin_clear(); + cmdwin_push("Say: "); + + /*** Get next query ***/ + + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + + conv_query[MAX_KEYWORD_SZ] = 0; + conv_len = strlen(conv_query); + if (! conv_len) + sprintf(conv_query, "bye"); + log_msg("^c+%c%s:^c- %s", CONV_PC_COLOR, + pc->getName(), conv_query); + + /*** Check if player ended conversation ***/ + + if (Quit) + break; + + if (strlen(conv_query) == 0) + conv_set_query("BYE"); + + if (!strcasecmp(conv_query, "BYE")) { + conv_end(); + } + + } + + cmdwin_clear(); + cmdwin_repaint(); + + session_run_hook(Session, conv_end_hook, "pp", pc, npc); + +} + +int isprintable(int c) +{ + /* Looks like ctype's isprint() doesn't always behave the same way. On + * some systems it was letting c<32 go through, causing an assert in + * ascii.c. */ + return ((c >= 32) + && (c < 127) + && (c != '%') /* printf special char */ + && (c != '^') /* ascii.c special char */ + ); +} + +int conv_get_word(char *instr, char **beg, char **end) +{ + char *inp = instr; + + while (*inp && !isalpha(*inp)) { + inp++; + } + + if (!*inp) { + return 0; + } + + *beg = inp; + + while (*inp && isalpha(*inp)) { + inp++; + } + + *end = inp; + + return 1; +} + +int conv_is_keyword(struct conv *conv, char *word) +{ + int index; + + if (! conv_keyword_highlighting) { + return 0; + } + + index = conv_lookup_keyword(conv, word); + if (index == -1) { + return 0; + } + return CONV_IS_KEYWORD | (bitset_tst(conv->marked, index) ? CONV_IS_MARKED : 0); +} + +int conv_init(void) +{ + char *val = cfg_get("keyword-highlighting"); + if (!val || strcasecmp(val, "yes")) { + conv_keyword_highlighting = 0; + } + return 0; +} + +void conv_enable_keyword_highlighting(int enable) +{ + conv_keyword_highlighting = !!enable; +} + +#else /* TEST_PORTRAITS */ + +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "applet.h" +#include "bitset.h" +#include "conv.h" +#include "event.h" +#include "cmdwin.h" +#include "common.h" +#include "object.h" +#include "closure.h" +#include "log.h" +#include "session.h" +#include "sprite.h" + +#include +#include +#include + +#define MAX_KEYWORD_SZ 16 + +#define PORTRAIT_H 192 +#define PORTRAIT_W 184 + +/** + * Conversation structure. + */ +struct conv { + struct closure *proc; /* Closure which responds to keywords. */ + int ref; /* Reference count. */ + int n_keywords; /* Size of the keywords array. */ + int key_index; /* Index of next empty keyword slot. */ + char **keywords; /* Keyword array. */ + bitset_t *marked; /* Used keywords */ +}; + +struct conv_applet { + struct applet base; + struct sprite *portrait; + Object *npc, *pc; + struct conv *conv; + int conv_room, conv_len; + char conv_query[16], *conv_ptr; +}; + +static int conv_done; + +static void conv_op_run(struct applet *applet, SDL_Rect *dims, struct session *session); +static void conv_op_paint(struct applet *applet); +static int conv_op_get_height(struct applet *applet); + +static struct applet_ops conv_applet_ops = { + conv_op_run, + conv_op_paint, + conv_op_get_height +}; + + +/** + * Keyhandler callback for processing player keystrokes while collecting the + * query string. This stores typed characters into the ca->conv_query buffer. + * + * @param kh is the keyhandler pushed for input handling. + * @param key is the key the player just typed. + * @returns 1 if the player is done entering the query, else 0. + */ +static int conv_get_player_query(struct KeyHandler *kh, int key, int keymod) +{ + DECL_CAST(struct conv_applet, ca, kh->data); + + if (key == CANCEL) { + while (ca->conv_ptr > ca->conv_query) { + ca->conv_ptr--; + *ca->conv_ptr = 0; + cmdwin_pop(); + ca->conv_room++; + } + return 1; + } + + if (key == '\n') { + return 1; + } + + if (key == '\b') { + if (ca->conv_ptr != ca->conv_query) { + ca->conv_ptr--; + *ca->conv_ptr = 0; + ca->conv_room++; + cmdwin_pop(); + } + return 0; + } + + if (isprintable(key) + && ca->conv_room) { + cmdwin_push("%c", key); + *ca->conv_ptr++ = key; + ca->conv_room--; + } + + return 0; +} + +/** + * Force the player query to a value. This is mainly done to start the + * conversation off with the "HAIL" keyword. + * + * @param ca is the conv_applet context to modify. + * @param str is the query value to set. + */ +static void conv_set_query(struct conv_applet *ca, char *str) +{ + snprintf(ca->conv_query, sizeof(ca->conv_query) - 1, "%s", str); + ca->conv_query[MAX_KEYWORD_SZ] = 0; + ca->conv_len = strlen(ca->conv_query); +} + +/** + * Internal destructor for a conversation struct. + * + * @param conv is the conversation to delete. + */ +static void conv_del(struct conv *conv) +{ + if (conv->proc) { + closure_unref(conv->proc); + } + + if (conv->keywords) { + + int i; + + for (i = 0; i < conv->key_index; i++) { + if (conv->keywords[i]) { + free(conv->keywords[i]); + } + } + + free(conv->keywords); + } + + if (conv->marked) { + bitset_free(conv->marked); + } + + free(conv); +} + +/** + * Callback used by the sort function to compare two values. + * + * @param p1 is one value. + * @param p2 is the other value. + * @returns 1 if p1>p2, 0 if p1==p2, -1 if p1 cptr. + */ +static int conv_prefix_cmp(char *wptr, char *cptr) +{ + int len = 0; + + while (*wptr && *cptr) { + char wc = tolower(*wptr++); + char cc = tolower(*cptr++); + len++; + int d = wc - cc; + if (d != 0) { + return d; + } + } + + if (*cptr && ! *wptr) { + /* candidate is longer than word */ + return 1; + } + + if (*wptr && len < 4) { + /* candidate is short but word is not */ + return -1; + } + + return 0; +} + +/** + * Check if a word is a keyword. + * + * @conv is the conversation to check. + * @word is the word to look for in the keywords. + * @returns the index of the matching keyword, else -1 if not found. + */ +static int conv_lookup_keyword(struct conv *conv, char *word) +{ + int min = 0, max = conv->key_index, pivot; + + while (max > min) { + + /** + * apricot + * + * aardvark + * abacus + * + * zoo + * zebra + */ + + pivot = ((max-min)/2) + min; + + int d = conv_prefix_cmp(word, conv->keywords[pivot]); + + if (d > 0) { + /* word > pivot => search higher */ + min = pivot + 1; + } else if (d < 0) { + /* word < pivot => search lower */ + max = pivot; + } else { + return pivot; + } + } + + return -1; +} + +/** + * Check if a word is a keyword and, if so, to mark it (marking is used to show + * the player which keywords have already been used in a conversation). + * + * @conv is the conversation to check. + * @word is the word to look for in the keywords. + */ +static void conv_mark_if_keyword(struct conv *conv, char *word) +{ + int index = conv_lookup_keyword(conv, word); + if (index != -1) { + bitset_set(conv->marked, index); + } +} + +/** + * + */ +static int conv_op_get_height(struct applet *applet) +{ + DECL_CAST(struct conv_applet, ca, applet); + if (ca->portrait) { + return PORTRAIT_H; + } + return ASCII_H; +} + +struct conv *conv_new(struct closure *proc, int n_keywords) +{ + struct conv *conv; + + if (!(conv = (struct conv*)calloc(1, sizeof(*conv)))) { + return NULL; + } + + if (!(conv->keywords = (char**)calloc(n_keywords, sizeof(char*)))) { + conv_del(conv); + return NULL; + } + + if (!(conv->marked = bitset_alloc(n_keywords))) { + conv_del(conv); + return NULL; + } + + conv->n_keywords = n_keywords; + conv->ref = 1; + conv->proc = proc; + closure_ref(proc); + + return conv; +} + +void conv_save(struct conv *conv, struct save *save) +{ + closure_save(conv->proc, save); +} + +int conv_add_keyword(struct conv *conv, char *keyword) +{ + assert(conv->key_index < conv->n_keywords); + if (!(conv->keywords[conv->key_index] = strdup(keyword))) { + return -1; + } + conv->key_index++; + return 0; +} + +void conv_sort_keywords(struct conv *conv) +{ + qsort(conv->keywords, conv->key_index, sizeof(char*), conv_sort_cmp); +} + +void conv_unref(struct conv *conv) +{ + assert(conv->ref>0); + conv->ref--; + if (!conv->ref) { + conv_del(conv); + } +} + +void conv_ref(struct conv *conv) +{ + conv->ref++; +} + +char *conv_highlight_keywords(struct conv *conv, char *orig) +{ + return NULL; +} + + +void conv_end() +{ + conv_done = 1; +} + +void conv_enter(Object *npc, Object *pc, struct conv *conv) +{ + struct conv_applet conv_applet; + + memset(&conv_applet, 0, sizeof(&conv_applet)); + conv_applet.base.ops = &conv_applet_ops; + conv_applet.npc = npc; + conv_applet.pc = pc; + conv_applet.conv = conv; + conv_applet.portrait = npc->getPortrait(); + + session_run_hook(Session, conv_start_hook, "pp", pc, npc); + + statusRunApplet(&conv_applet.base); + statusSetMode(ShowParty); /* restore default status mode */ + + session_run_hook(Session, conv_end_hook, "pp", pc, npc); + +} + +int isprintable(int c) +{ + /* Looks like ctype's isprint() doesn't always behave the same way. On + * some systems it was letting c<32 go through, causing an assert in + * ascii.c. */ + return ((c >= 32) + && (c < 127) + && (c != '%') /* printf special char */ + && (c != '^') /* ascii.c special char */ + ); +} + +int conv_get_word(char *instr, char **beg, char **end) +{ + char *inp = instr; + + while (*inp && !isalpha(*inp)) { + inp++; + } + + if (!*inp) { + return 0; + } + + *beg = inp; + + while (*inp && isalpha(*inp)) { + inp++; + } + + *end = inp; + + return 1; +} + +int conv_is_keyword(struct conv *conv, char *word) +{ + int index = conv_lookup_keyword(conv, word); + if (index == -1) { + return 0; + } + return CONV_IS_KEYWORD | (bitset_tst(conv->marked, index) ? CONV_IS_MARKED : 0); +} + +static void conv_op_paint(struct applet *applet) +{ + DECL_CAST(struct conv_applet, ca, applet); + + screenErase(&applet->dims); + if (ca->portrait) { + int x = (applet->dims.w - PORTRAIT_W)/2 + applet->dims.x; + sprite_paint(ca->portrait, 0, x, applet->dims.y); + } else { + screenPrint(&applet->dims, SP_CENTERED, "No portrait"); + } + screenUpdate(&applet->dims); + + status_repaint_title(); +} + +static void conv_op_run(struct applet *applet, SDL_Rect *dims, struct session *session) +{ + DECL_CAST(struct conv_applet, ca, applet); + + applet->dims = *dims; + applet->session = session; + + status_set_title(ca->npc->getName()); + conv_op_paint(applet); + + conv_set_query(ca, "hail"); + conv_done = 0; + + for (;;) { + + /* Truncate the query to 4 characters */ + ca->conv_query[4] = 0; + + conv_mark_if_keyword(ca->conv, ca->conv_query); + + /* Query the NPC */ + closure_exec(ca->conv->proc, "ypp", ca->conv_query, ca->npc, ca->pc); + + if (conv_done) { + break; + } + + /*** Setup for next query ***/ + + memset(ca->conv_query, 0, sizeof(ca->conv_query)); + ca->conv_room = sizeof(ca->conv_query) - 1; + ca->conv_ptr = ca->conv_query; + + cmdwin_clear(); + cmdwin_push("Say: "); + + /*** Get next query ***/ + + eventRunKeyHandler(conv_get_player_query, ca); + + ca->conv_query[MAX_KEYWORD_SZ] = 0; + ca->conv_len = strlen(ca->conv_query); + if (! ca->conv_len) + sprintf(ca->conv_query, "bye"); + log_msg("^c+%c%s:^c- %s", CONV_PC_COLOR, + ca->pc->getName(), ca->conv_query); + + /*** Check if player ended conversation ***/ + + if (Quit) + break; + + if (strlen(ca->conv_query) == 0) + conv_set_query(ca, "BYE"); + + if (!strcasecmp(ca->conv_query, "BYE")) { + conv_end(); + } + + } + + cmdwin_clear(); + cmdwin_repaint(); + +} + + +#endif /* TEST_PORTRAITS */ diff --git a/src/conv.h b/src/conv.h new file mode 100644 index 0000000..4a88942 --- /dev/null +++ b/src/conv.h @@ -0,0 +1,134 @@ +/* + * nazghul - an old-school RPG engine + * Copyright (C) 2002, 2003, 2008 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * Gordon McNutt + * gmcnutt@users.sourceforge.net + */ +#ifndef conv_h +#define conv_h + +#define CONV_PC_COLOR 'g' +#define CONV_NPC_COLOR 'b' + +/** + * Flags for the return value of conv_is_keyword(). + */ +#define CONV_IS_KEYWORD (1<<0) /* word is a keyword */ +#define CONV_IS_MARKED (1<<1) /* keyword has been used */ + +struct conv; + +/** + * Allocate a conversation struct and a fixed number of keywords slots. + * + * @param proc becomes the proc field with an added refcount. + * @returns a new converstation struct on success, else NULL if allocaition + * failed. + */ +struct conv *conv_new(struct closure *proc); + +/** + * Save a conversation to the session file. + * + * @param conv is the conversation to save. Only the closure is saved. + * @param save is the save object. + */ +void conv_save(struct conv *conv, struct save *save); + +/** + * Release a reference to a conversation. This may delete it. + * + * @param is the conversation. + */ +void conv_unref(struct conv *conv); + +/** + * Add a reference to a conversation. This prevents it from being destroyed. + * + * @param is the conversation. + */ +void conv_ref(struct conv *conv); + +/** + * Start a conversation. This will start the conversation session in the + * console, and return when and only when the conversation is over. + * + * @param npc is the NPC being spoken to. + * @param pc is the player party member doing the talking. + * @param conv is the conversation. + */ +void conv_enter(class Object *npc, class Object *pc, struct conv *conv); + +/** + * End a conversation. This is provided so that NPC scripts can end the + * conversation prematurely (before the player says 'bye'). + */ +void conv_end(void); + +/** + * Substitute for ctype.h's isprint(), which does not work properly on all + * systems. + * + * @param c is the character to test. + * @returns non-zero if c is a printable character, else zero. + */ +int isprintable(int c); + +/** + * Given an input string get pointers to the beginning and end of the next + * word. The beginning of a word is any alphabetical character which either + * starts the string or follows whitespace or punctuation. + * + * @param instr is the input string. + * + * @param beg will point to the beginning of the next work on exit, iff one was + * found. If not its value is undefined. + * @param end likewise will point to the end of the next work in the string. + * @returns non-zero iff a word was found in the string. + */ +int conv_get_word(char *instr, char **beg, char **end); + +/** + * Check if a word is a keyword in a conversation (and, if so, if it has + * already been used in a conversation since the last session reload). This + * works by testing if any of the keywords are a prefix of the word. + * + * @param conv is the conversation with the keywords to check. + * @param word if the word to test for. + * @returns zero if the word is not a keyword, else a non-zero union of the + * flags CONV_IS_KEYWORD and CONV_IS_MARKED. + * + */ +int conv_is_keyword(struct conv *conv, char *word); + +/** + * Initialize module before using. + * + * @returns non-zero on error. + */ +int conv_init(void); + +/** + * Turn keyword highlighting on or off. + * + * @param enable is non-zero to turn it on. + */ +void conv_enable_keyword_highlighting(int enable); + + +#endif diff --git a/src/ctrl.c b/src/ctrl.c new file mode 100644 index 0000000..e0ef26d --- /dev/null +++ b/src/ctrl.c @@ -0,0 +1,1707 @@ +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "../config.h" /* for USE_SKILLS */ +#include "ctrl.h" +#include "dice.h" +#include "event.h" +#include "foogod.h" +#include "cmd.h" +#include "cmdwin.h" +#include "map.h" +#include "place.h" +#include "player.h" +#include "Party.h" +#include "character.h" +#include "combat.h" +#include "terrain.h" +#include "sched.h" +#include "session.h" +#include "log.h" +#include "factions.h" +#include "kern_intvar.h" +#include "nazghul.h" // for DeveloperMode + +#ifndef CONFIG_DIAGONAL_MOVEMENT +#define CONFIG_DIAGONAL_MOVEMENT 1 +#endif + +int G_latency_start = 0; +int G_turnaround_start = 0; +int G_turnaround = 0; + +static int ctrl_party_key_handler(struct KeyHandler *kh, int key, int keymod) +{ + int dir; + + class PlayerParty *party = (class PlayerParty*)kh->data; + + Session->subject = player_party; + + G_latency_start = SDL_GetTicks(); + + /* Commands which are only enabled in developer mode */ + if (DeveloperMode) { + switch (key) { + + case KEY_CTRL_T: + cmd_terraform(party->getPlace(), party->getX(), party->getY()); + break; + + case KEY_CTRL_O: + cmd_save_current_place(party->getPlace()); + break; + + case KEY_CTRL_Z: + mapTogglePeering(); + break; + } + } + + switch (key) { + +#if CONFIG_DIAGONAL_MOVEMENT + case KEY_NORTHWEST: + case KEY_NORTHEAST: + case KEY_SOUTHWEST: + case KEY_SOUTHEAST: +#endif /* CONFIG_DIAGONAL_MOVEMENT */ + case KEY_NORTH: + case KEY_WEST: + case KEY_EAST: + case KEY_SOUTH: + { + dir = keyToDirection(key); + party->move(directionToDx(dir), directionToDy(dir)); + mapSetDirty(); + dir = keyToDirection(key); + } + break; + +#if CONFIG_DIAGONAL_MOVEMENT + case KEY_SHIFT_NORTHWEST: + case KEY_SHIFT_NORTHEAST: + case KEY_SHIFT_SOUTHWEST: + case KEY_SHIFT_SOUTHEAST: +#endif /* CONFIG_DIAGONAL_MOVEMENT */ + case KEY_SHIFT_NORTH: + case KEY_SHIFT_EAST: + case KEY_SHIFT_SOUTH: + case KEY_SHIFT_WEST: + + // ---------------------------------------------------- + // Pan the camera. + // ---------------------------------------------------- + + key &= ~KEY_SHIFT; /* clear shift bit */ + dir = keyToDirection(key); + mapMoveCamera(directionToDx(dir), directionToDy(dir)); + mapSetDirty(); + break; + + case 'a': + cmdAttack(); + break; + case 'b': + party->board_vehicle(); + break; + case 'c': + cmdCastSpell(NULL); + break; + case 'f': + cmdFire(); + break; + case 'g': + cmdGet(party); + break; + case 'h': + // SAM: Adding (H)andle command... + cmdHandle(NULL); + break; + case 'k': + cmd_camp_in_wilderness(party); + break; + case 'l': + cmdLoiter(party); + break; + case 'm': + cmdMixReagents(NULL); + break; + case 'n': + cmdNewOrder(); + break; + case 'o': + cmdOpen(NULL); + break; + case 'q': + cmdQuit(); + break; + case 'r': + cmdReady(NULL); + break; + case 's': + cmdSearch(0); + break; + case 't': + cmdTalk(NULL); + break; + case 'u': + cmdUse(NULL, CMD_SELECT_MEMBER|CMD_PRINT_MEMBER); + break; +#ifdef USE_SKILLS + case 'y': + cmdYuse(NULL); + break; +#endif + case 'x': + cmdXamine(party); + break; + case 'z': + cmdZtats(party->getMemberAtIndex(0)); + break; + case '@': + // SAM: 'AT' command for party-centric information + cmdAT(NULL); + break; + case ' ': + party->endTurn(); + log_msg("Pass"); + break; + case '>': + // This key was chosen to be a cognate for '>' in + // NetHack and other roguelike games. + cmdZoomIn(); + party->endTurn(); + break; + case '?': + cmdHelp(); + break; + + case KEY_CTRL_S: + cmdSave(); + break; + + case KEY_CTRL_R: + cmdReload(); + Session->subject = NULL; + return true; + + case SDLK_F10: + cmdSettings(); + break; + + default: + break; + } // switch(key) + + /* Prep cmdwin for next prompt */ + cmdwin_clear(); + + Session->subject = NULL; + + party->absorbMemberAPDebt(); + + /* Return true when done processing commands. */ + if(!party->isTurnEnded()) + cmdwin_push("Party [%d ap]:",party->getActionPoints()); + + return party->isTurnEnded(); + +} + +void ctrl_wander(class Object *object) +{ + // *** left off here *** + + int dx = 0, dy = 0; + + if (object->isStationary()) + return; + + /* Roll for direction */ + dx = rand() % 3 - 1; + if (!dx) + dy = rand() % 3 - 1; + + if (dx || dy) { + + int newx, newy; + newx = object->getX() + dx; + newy = object->getY() + dy; + + if (! object->canWanderTo(newx, newy)) + return; + + // ------------------------------------------------------------ + // Do a quick check here if this would take the character off + // the map. If so, then don't do it. Can't have NPC's wandering + // off out of town... + // ------------------------------------------------------------ + + if (place_off_map(object->getPlace(), object->getX() + dx, + object->getY() + dy) || + place_is_hazardous(object->getPlace(), object->getX() + dx, + object->getY() + dy)) + return; + + object->move(dx, dy); + } +} + +void ctrl_party_ai(class Party *party) +{ + int d; + + /* Check if this party is friendly to the player or if the player is + * not around */ + if (! are_hostile(party, player_party) || + Place != party->getPlace()) { + // This party is friendly to the player, so just wander for now + // (later I'll add schedules). + ctrl_wander(party); + return; + } + + /* Check if the player is _on this spot_. Yes, this can happen under + * current game rules. If a player enters a portal and an npc is on the + * destination then... */ + if (party->getX() == player_party->getX() && + party->getY() == player_party->getY()) { + + struct move_info info; + struct combat_info cinfo; + + memset(&info, 0, sizeof(info)); + info.place = party->getPlace(); + info.x = party->getX(); + info.y = party->getY(); + info.dx = party->getDx(); + info.dy = party->getDy(); + info.px = player_party->getX(); + info.py = player_party->getY(); + info.npc_party = party; + + if (!info.dx && !info.dy) + info.dx = 1; + else if (info.dx && info.dy) + info.dy = 0; + + memset(&cinfo, 0, sizeof(cinfo)); + cinfo.defend = true; + cinfo.move = &info; + + combat_enter(&cinfo); + party->endTurn(); + return; + } + + /* get distance to player */ + d = place_walking_distance(party->getPlace(), party->getX(), + party->getY(), + player_party->getX(), player_party->getY()); + + /* if adjacent attack */ + if (1==d) { + int dx=0, dy=0; + place_get_direction_vector(party->getPlace(), + party->getX(), party->getY(), + player_party->getX(), player_party->getY(), + &dx, &dy); + if (party->attackPlayer(dx, dy)) { + return; + } + } + + if (d > party->getVisionRadius()) { + ctrl_wander(party); + return; + } + + if (d > 1 && party->attack_with_ordnance(d)) { + return; + } + + if (!party->gotoSpot(player_party->getX(), player_party->getY())) { + ctrl_wander(party); + return; + } +} + +static int ctrl_calc_to_hit(class Character *character, + class ArmsType *weapon, + int penalty) +{ + int base = dice_roll("1d20"); + int weaponBonus = dice_roll(weapon->getToHitDice()); + int attackBonus = character->getAttackBonus(weapon); + int val = base + weaponBonus + attackBonus + penalty; + + log_continue("to-hit: %d=%d+%d+%d", val, base, weaponBonus, + attackBonus); + if (penalty >= 0) { + log_continue("+"); + } + log_continue("%d\n", penalty); + + return val; +} + +static int ctrl_calc_to_defend(class Character *target) +{ + int base = target->getDefend(); + int bonus = target->getAvoidBonus(); + int val = base + bonus; + + log_continue("to-def: %d=%d+%d\n", val, base, bonus); + + return val; +} + +static int ctrl_calc_damage(class Character *character, + class ArmsType *weapon, + char critical) +{ + int weaponDamage = dice_roll(weapon->getDamageDice()); + int characterBonus = character->getDamageBonus(weapon); + int memberBonus = 0; + int criticalBonus = 0; + + if (character->isPlayerControlled()) { + memberBonus = dice_roll("1d4"); + } + + if (critical) { + criticalBonus = character->getDamageBonus(weapon); + } + + int val = weaponDamage + characterBonus + criticalBonus + memberBonus; + + log_continue("damage: %d=%d+%d", val, weaponDamage, characterBonus); + if (memberBonus) { + log_continue("+%d", memberBonus); + } + if (criticalBonus) { + log_continue("+%d", criticalBonus); + } + log_continue("\n"); + + return val; +} + +static int ctrl_calc_armor(class Character *target, int critical) +{ + int armor = 0; + + if (! critical) { + armor = target->getArmor(); + } + + log_continue(" armor: %d\n", armor); + + return armor; +} + +static void ctrl_attack_done(class Character *character, class ArmsType *weapon, + class Character *target) +{ + character->runHook(OBJ_HOOK_ATTACK_DONE, "pp", weapon, target); + character->useAmmo(weapon); +} + +void ctrl_do_attack(class Character *character, class ArmsType *weapon, + class Character *target, int to_hit_penalty) +{ + int hit; + int def; + int damage; + int armor; + int critical = 0; + int misx; + int misy; + bool miss; + + /* Reduce the diplomacy rating between the attacker's and target's + * factions */ + harm_relations(character, target); + + log_begin("^c%c%s^cw attacks ^c%c%s^cw with %s: " + , (are_hostile(character, player_party)?'r':'g') + , character->getName() + , (are_hostile(target, player_party)?'r':'g') + , target->getName() + , weapon->getName() + ); + + if (weapon->canOnAttack()) + { + weapon->onAttack(NULL,character); + } + + miss = ! weapon->fire(target, character->getX(), character->getY(), &misx, &misy); + ctrl_attack_done(character, weapon, target); + + if (miss) + { + log_end("obstructed!"); + weapon->fireHitLoc(character, NULL, character->getPlace(),misx,misy,-1); + return; + } + + /* Roll to hit. */ + log_continue("\n"); + hit = ctrl_calc_to_hit(character, weapon, to_hit_penalty); + def = ctrl_calc_to_defend(target); + if (hit < def) + { + log_end("evaded!"); + weapon->fireHitLoc(character, NULL, character->getPlace(),misx,misy,-1); + return; + } + + /* roll for critical hit */ + if (20 <= (dice_roll("1d20") + + logBase2(character->getBaseAttackBonus(weapon)))) { + critical = 1; + log_continue("^c+yCritical hit!^c-\n"); + } + + /* roll for damage */ + damage = ctrl_calc_damage(character, weapon, critical); + armor = ctrl_calc_armor(target, critical); + damage -= armor; + damage = max(damage, 0); + + if (damage <= 0) + { + log_end("blocked!"); + weapon->fireHitLoc(character, target, character->getPlace(),misx,misy,0); + return; + } + + // the damage() method may destroy the target, so bump the refcount + // since we still need the target through the end of this function + obj_inc_ref(target); + target->damage(damage); + + weapon->fireHitLoc(character, target, character->getPlace(),misx,misy,damage); + + log_end("%s!", target->getWoundDescription()); + + /* If the target was killed then add xp to the attacker */ + if (target->isDead()) { + character->addExperience(target->getExperienceValue()); + } + + obj_dec_ref(target); +} + + +static class Character * +ctrl_get_interfering_hostile(class Character *character) +{ + static int dx_to_neighbor[] = { 0, -1, 0, 1 }; + static int dy_to_neighbor[] = { -1, 0, 1, 0 }; + class Character *near; + int i; + + for (i = 0; i < 4; i++) { + near = (class Character*)place_get_object( + character->getPlace(), + character->getX() + dx_to_neighbor[i], + character->getY() + dy_to_neighbor[i], + being_layer); + + if (near && + are_hostile(near, character) && + !near->isIncapacitated()) { + return near; + } + } + + return NULL; +} + +struct nearest_hostile_info { + class Character *origin; + class Character *nearest; + int min_distance; + int range; + struct list suggest; /* for ctrl_attack_ui */ +}; + +static void ctrl_suggest_visitor(class Object *obj, void *data) +{ + struct nearest_hostile_info *info = (struct nearest_hostile_info*)data; + class Character *npc = 0; + int dist = 0; + struct location_list *entry = 0; + + if (being_layer!=obj->getLayer()) + return; + + npc = (class Character*)obj; + + if (! are_hostile(npc, info->origin)) + return; + + if (! npc->isVisible() && ! Reveal) + return; + + if (! place_in_los(info->origin->getPlace(), + info->origin->getX(), + info->origin->getY(), + info->origin->getPlace(), + obj->getX(), + obj->getY())) + return; + + if (info->range < (dist = place_flying_distance(info->origin->getPlace(), + info->origin->getX(), + info->origin->getY(), + obj->getX(), + obj->getY()))) + return; + + /* Add it to the list */ + entry = (struct location_list*)malloc(sizeof(*entry)); + assert(entry); + entry->x = obj->getX(); + entry->y = obj->getY(); + list_add_tail(&info->suggest, &entry->list); + + /* Keep track of the nearest as we go. */ + if (! info->nearest + || (dist < info->min_distance)) { + info->min_distance = dist; + info->nearest = npc; + } + + printf("Added %s at [%d %d]\n", obj->getName(), obj->getX(), obj->getY()); +} + +static void ctrl_del_suggest_list(struct list *head) +{ + struct list *entry = head->next; + while (entry != head) { + struct location_list *tmp = + (struct location_list*)entry; + entry = entry->next; + list_remove(&tmp->list); + free(tmp); + } +} + + +static void ctrl_attack_ui(class Character *character) +{ + int x; + int y; + class ArmsType *weapon; + class Character *target; + struct terrain *terrain; + class Object *mech; + + // If in follow mode, when the leader attacks automatically switch to + // turn-based mode. + if (player_party->getPartyControlMode() == PARTY_CONTROL_FOLLOW && + player_party->getSize() > 1) { + log_msg("Switching from Follow to Round Robin Mode.\n"); + player_party->enableRoundRobinMode(); + } + + // Loop over all readied weapons + int armsIndex=0; + int this_is_nth_attack = 1; + int this_wpn_AP; + for (weapon = character->enumerateWeapons(&armsIndex); weapon != NULL; + weapon = character->getNextWeapon(&armsIndex)) { + struct nearest_hostile_info info; + + // prompt the user + cmdwin_clear(); + cmdwin_spush("Attack"); + + // Determine AP for this (potential) attack, + // as a discount may be applied for dual weapon attacks and such, + // and we need the discounted figure to display in the UI: + this_wpn_AP = weapon->getRequiredActionPoints(); + if (this_is_nth_attack == 1) { + // 1st weapon attack (usual case), no AP cost adjustments + } + else if (this_is_nth_attack == 2) { + // 2nd weapon attack (dual weapon, 2nd weapon) + int mult = kern_intvar_get("AP_MULT12:second_wpn_attack"); + this_wpn_AP = (int) (this_wpn_AP * mult) / 12; + } + else if (this_is_nth_attack >= 3) { + // 3rd+ weapon attack (unusual case for multi-limbed beings...) + int mult = kern_intvar_get("AP_MULT12:third_plus_wpn_attack"); + this_wpn_AP = (int) (this_wpn_AP * mult) / 12; + } + + //log_msg("DEBUG: wpn = %s (AP=%d-->%d), remaining AP=%d\n", + // weapon->getName(), weapon->getRequiredActionPoints(), this_wpn_AP, + // character->getActionPoints() ); + + if (weapon->isMissileWeapon()) { + // SAM: It would be nice to get ammo name, too... + cmdwin_spush("%s (%d AP, range %d, %d ammo)", + weapon->getName(), + this_wpn_AP, + weapon->getRange(), + character->hasAmmo(weapon)); + } + else if (weapon->isThrownWeapon()) { + // SAM: It would be nice to get ammo name, too... + cmdwin_spush("%s (%d AP, range %d, %d left)", + weapon->getName(), + this_wpn_AP, + weapon->getRange(), + character->hasAmmo(weapon)); + } + else { + cmdwin_spush("%s (%d AP, reach %d)", + weapon->getName(), + this_wpn_AP, + weapon->getRange() ); + } + + + // Check ammo + if (!character->hasAmmo(weapon)) { + cmdwin_spush("no ammo!"); + log_msg("%s: %s - no ammo!\n", + character->getName(), + weapon->getName()); + continue; + } + + /* Check the four adjacent tiles for hostiles who will + * interfere with a missile weapon */ + if (weapon->isMissileWeapon()) { + class Character *near; + near = ctrl_get_interfering_hostile(character); + if (near) { + cmdwin_spush("blocked!"); + log_msg("%s: %s - blocked by %s!\n", + character->getName(), + weapon->getName(), + near->getName()); + continue; + } + } + + /* Build the list of suggested targets. */ + memset(&info, 0, sizeof(info)); + info.origin = character; + info.range = weapon->getRange(); + list_init(&info.suggest); + place_for_each_object(character->getPlace(), + ctrl_suggest_visitor, + &info); + + /* Get the default target. It's important to do this every time + * the loop because the last iteration may have killed the + * previous target, or it may be out of range of the + * weapon. The getAttackTarget routine will reevaluate the + * current target. */ + target = character->getAttackTarget(weapon); + + /* If the target is the character that means there is no + * default target now. Select the nearest one is the new + * default. */ + if (target==character) { + if (! list_empty(&info.suggest)) { + assert(info.nearest); + target = info.nearest; + } + } + + assert(target); + + // select the target location + x = target->getX(); + y = target->getY(); + + // SAM: + // select_target() might be a more elegant place to put + // logic to prevent (or require confirm of) attacking self, + // party members, etc. + if (-1 == select_target(character->getX(), + character->getY(), + &x, &y, + weapon->getRange(), + &info.suggest)) { + cmdwin_spush("abort!"); + continue; + } + + /* Cleanup the suggestion list */ + ctrl_del_suggest_list(&info.suggest); + + // Find the new target under the cursor + target = (class Character *) + place_get_object(character->getPlace(), x, y, + being_layer); + character->setAttackTarget(target); + if (target == NULL) { + + /* Attack the terrain */ + terrain = place_get_terrain(character->getPlace(), + x, y); + + cmdwin_spush(" %s", terrain->name); + + log_begin("%s: %s - ", character->getName() + , weapon->getName() + ); + + int misx = x; + int misy = y; + + this_is_nth_attack++; + + if (weapon->canOnAttack()) + { + weapon->onAttack(NULL,character); + } + + bool miss = ! weapon->fire(character->getPlace(), + character->getX(), + character->getY(), + &misx, + &misy); + + if (miss) + { + log_end("obstructed!"); + } + + weapon->fireHitLoc(character, NULL, character->getPlace(),misx,misy,-1); + + ctrl_attack_done(character, weapon, NULL); + + if (!miss) + { + /* Check for a mech */ + mech = place_get_object(character->getPlace(), x, y, + mech_layer); + if (mech && mech->getName()) { + log_end("%s hit!", mech->getName()); + mech->attack(character); + } else { + log_end("%s hit!", terrain->name); + } + } + + } + else if (target == character) { + /* Targeting the self is taken to mean "switch to my + * next weapon". This allows players to quickly jump to + * the next weapon if no target is in range and they + * aren't interested in attacking the ground. */ + cmdwin_spush("skip weapon!"); + // no attack made, so don't increment this_is_nth_attack + continue; + } else { + // confirmed_attack_ally: + + // in combat all npc parties and the player party + // should be removed, so only characters reside at the + // being layer + assert(target->isType(CHARACTER_ID)); + + cmdwin_spush("%s", target->getName()); + + + // If the npc is not hostile then get player confirmation. + if (! are_hostile(character, target)) { + int yesno; + cmdwin_spush("attack non-hostile"); + cmdwin_spush(""); + getkey(&yesno, yesnokey); + cmdwin_pop(); + if (yesno == 'n') { + cmdwin_spush("no"); + continue; + } + cmdwin_spush("yes"); + } + + // Strike the target + this_is_nth_attack++; + ctrl_do_attack(character, weapon, target, character->getToHitPenalty()); + + // If we hit a party member then show their new hit + // points in the status window + if (target->isPlayerControlled()) + statusRepaint(); + } + + /* Warn the user if out of ammo. Originally this code used + * character->getCurrentWeapon() instead of weapon, that may + * still be okay now that getToHitPenalty() is outside of this + * loop, but not sure why it' would be preferred. */ + if (! character->hasAmmo(weapon)) + log_msg("%s : %s now out of ammo\n", + character->getName(), weapon->getName()); + + character->decActionPoints(this_wpn_AP); + //log_msg("DEBUG: after attack, used %d, remaining AP=%d\n", + // this_wpn_AP, character->getActionPoints() ); + } + +} + +static void ctrl_move_character(class Character *character, int dir) +{ + enum MoveResult move_result; + const char *result = NULL; + const char *dirstr = directionToString(dir); + int dx; + int dy; + + dx = directionToDx(dir); + dy = directionToDy(dir); + + /* try to move */ + move_result = character->move(dx, dy); + + /* recenter (harmless if move failed) */ + mapCenterView(character->getView(), character->getX(), + character->getY()); + + /* if moved ok then no message to print */ + if (MovedOk == move_result) { + return; + } + + /* otherwise we'll print something */ + log_begin(""); + + switch (move_result) { + case OffMap: + result = "no place to go!"; + break; + case ExitedMap: + result = "exit!"; + character->endTurn(); + break; + case EngagedEnemy: + cmdwin_spush("enter combat!"); + break; + case WasOccupied: + result = "occupied!"; + break; + case WasImpassable: + { + /* If the move failed because something impassable is there + * then check for a mech and try to handle it. This is good + * enough to automatically open unlocked doors. + */ + + class Object *mech; + int newx, newy; + + newx = character->getX() + dx; + newy = character->getY() + dy; + + mech = place_get_object(character->getPlace(), newx, newy, + mech_layer); + + if (mech && mech->getObjectType()->canHandle()) + { + mech->getObjectType()->handle(mech, character); + character->decActionPoints(kern_intvar_get("AP_COST:handle_mechanism")); + mapSetDirty(); + result = "handled!"; + } + else if (mech && mech->getObjectType()->canBump()) + { + result = ""; + mech->getObjectType()->bump(mech, character); + mapSetDirty(); + } + else + { + result = "impassable!"; + } + } + break; + case SlowProgress: + result = "slow progress!"; + break; + case SwitchedOccupants: + result = "switch!"; + break; + case NotFollowMode: + result = "must be in follow mode!"; + break; + case CantRendezvous: + result = "party can't rendezvous!"; + break; + case CouldNotSwitchOccupants: + result = "can't switch places!"; + break; + default: + break; + } + + log_continue("%s: %s - %s", character->getName(), dirstr, result); + log_end(""); +} + +static int ctrl_character_key_handler(struct KeyHandler *kh, int key, + int keymod) +{ + extern int G_latency_start; + int dir; + + class Character *character = (class Character *) kh->data; + class Object *portal; + + G_latency_start = SDL_GetTicks(); + + Session->subject = character; + + /* First process commands which should not be affected by the keystroke + * hooks. */ + + /* Commands which are only enabled in developer mode */ + if (DeveloperMode) { + switch (key) { + + case KEY_CTRL_T: + cmd_terraform(character->getPlace(), character->getX(), + character->getY()); + break; + + case KEY_CTRL_O: + cmd_save_current_place(character->getPlace() ); + break; + + case KEY_CTRL_Z: + mapTogglePeering(); + break; + + case KEY_CTRL_E: + cmdDeveloperEval(Session); + break; + } + } + + switch (key) { + + case KEY_CTRL_S: + cmdSave(); + break; + + case KEY_CTRL_R: + cmdReload(); + Session->subject = NULL; + return true; + + case SDLK_F10: + cmdSettings(); + break; + + case 'f': + if (cmdToggleFollowMode()) { + if (! character->isLeader()) { + character->endTurn(); + } + } else { + foogod_set_title("Round Robin: %s", character->getName()); + foogodRepaint(); + } + break; + + case SDLK_1: + case SDLK_2: + case SDLK_3: + case SDLK_4: + case SDLK_5: + case SDLK_6: + case SDLK_7: + case SDLK_8: + case SDLK_9: + if (cmdSetSoloMode(key - SDLK_1)) { + character->endTurn(); + } + break; + + case SDLK_0: + // ---------------------------------------------------- + // Exit solo mode. + // ---------------------------------------------------- + player_party->enableRoundRobinMode(); + //in general, switching to roundrobin mode means + //you need all the turns you gan get, so dont waste this one + //character->endTurn(); + break; + + default: + break; + } + + // Don't run the keystroke hook until we get here. Keystroke + // effects should not affect the special ctrl charactes + // (otherwise something like being stuck in a web can prevent a + // user from reloading a game). + character->runHook(OBJ_HOOK_KEYSTROKE, 0); + if (character->isTurnEnded()) { + Session->subject = NULL; + return true; + } + + + switch (key) { + +#if CONFIG_DIAGONAL_MOVEMENT + case KEY_NORTHWEST: + case KEY_NORTHEAST: + case KEY_SOUTHWEST: + case KEY_SOUTHEAST: +#endif /* CONFIG_DIAGONAL_MOVEMENT */ + case KEY_NORTH: + case KEY_WEST: + case KEY_EAST: + case KEY_SOUTH: + dir = keyToDirection(key); + ctrl_move_character(character, dir); + break; + + +#if CONFIG_DIAGONAL_MOVEMENT + case KEY_SHIFT_NORTHWEST: + case KEY_SHIFT_NORTHEAST: + case KEY_SHIFT_SOUTHWEST: + case KEY_SHIFT_SOUTHEAST: +#endif /* CONFIG_DIAGONAL_MOVEMENT */ + case KEY_SHIFT_NORTH: + case KEY_SHIFT_EAST: + case KEY_SHIFT_SOUTH: + case KEY_SHIFT_WEST: + + // ---------------------------------------------------- + // Pan the camera. + // ---------------------------------------------------- + + key &= ~KEY_SHIFT; /* clear shift bit */ + dir = keyToDirection(key); + mapMoveCamera(directionToDx(dir), directionToDy(dir)); + mapSetDirty(); + break; + + + case 'a': + ctrl_attack_ui(character); + break; + + case 'c': + cmdCastSpell(character); + break; + + case 'd': + cmdDrop(character); + break; + case 'e': + + // ---------------------------------------------------- + // Enter a portal. For this to work a portal must exist + // here, the party must be in follow mode, and all the + // party members must be able to rendezvous at this + // character's position. + // ---------------------------------------------------- + + portal = place_get_object(character->getPlace(), + character->getX(), + character->getY(), + mech_layer); + if (!portal || !portal->canEnter()) { + break; + } + + log_begin_group(); + portal->enter(character); + log_end_group(); + + break; + + + case 'g': + cmdGet(character); + break; + case 'h': + cmdHandle(character); + break; + case 'k': + cmd_camp_in_town(character); + break; + case 'l': + cmdLoiter(character); + break; + case 'm': + cmdMixReagents(character); + break; + case 'n': + cmdNewOrder(); + break; + case 'o': + cmdOpen(character); + break; + case 'q': + cmdQuit(); + break; + case 'r': + if (player_party->getPartyControlMode()==PARTY_CONTROL_FOLLOW) + cmdReady(NULL); + else + cmdReady(character); + break; + case 's': + cmdSearch(character); + break; + case 't': + cmdTalk(character); + break; + case 'u': + cmdUse(character, 0); + break; + case 'x': + cmdXamine(character); + break; +#ifdef USE_SKILLS + case 'y': + cmdYuse(character); + break; +#endif + case 'z': + cmdZtats(character); + break; + case '@': + cmdAT(character); + break; + case ' ': + log_msg("Pass"); + character->endTurn(); + break; + case '?': + cmdHelp(); + break; + + case SDLK_ESCAPE: + // SAM: Removed the ESC-to-exit-combat keybinding. + // Using ESC for both exit-from-UI-things and exit-combat-map + // meant it was easy to exit, and miss your loot. + // + if (!place_is_wilderness_combat(character->getPlace())) + { + // log_msg(""); + break; + } + + if (place_contains_hostiles(character->getPlace(), character)) + { + // log_msg(""); + break; + } + log_msg("To exit this combat map, use '<', \nor walk off the edge of the map."); + break; + + case '<': + // case SDLK_ESCAPE // SAM: Removed the ESC-to-exit-combat keybinding, see above. + // ---------------------------------------------------- + // Quick exit from wilderness combat. The current place + // must be the special wildernss combat place and it + // must be empty of hostile characters or this fails. + // ---------------------------------------------------- + + if (!place_is_wilderness_combat(character->getPlace())) + { + log_msg("Must use an exit!"); + break; + } + + if (place_contains_hostiles(character->getPlace(), + character)) + { + log_msg("Not while foes remain!"); + break; + } + + // ---------------------------------------------------- + // This next call is to make sure the "Victory" and + // "Defeated" messages are printed properly. I don't + // *think* it has any other interesting side-effects in + // this case. + // ---------------------------------------------------- + + combat_analyze_results_of_last_turn(); + + // ---------------------------------------------------- + // Remove all party members. + // ---------------------------------------------------- + + player_party->removeMembers(); + + character->endTurn(); + + break; + + default: + break; + } + + cmdwin_clear(); + + if (!character->isTurnEnded()) { + cmdwin_push("%s:", character->getName()); + } + + Session->subject = NULL; + + return character->isTurnEnded(); +} + +static int ctrl_too_close_to_target(class Character *character, + class Character *target) +{ + int distance; + + distance = place_flying_distance(character->getPlace(), + character->getX(), character->getY(), + target->getX(), target->getY()); + + if (distance > 1) + return 0; + + int armsIndex=0; + for (class ArmsType * weapon = character->enumerateWeapons(&armsIndex); + weapon != NULL; weapon = character->getNextWeapon(&armsIndex)) { + + /* if npc has at least one melee weapon then not too close */ + if (character->hasAmmo(weapon) && + ! weapon->isMissileWeapon()) { + return 0; + } + } + + return 1; +} + +#if 0 +static void ctrl_unready_all_weapons(class Character *character) +{ + int armsIndex = 0; + for (class ArmsType * weapon = character->enumerateWeapons(&armsIndex); + weapon != NULL; weapon = character->getNextWeapon(&armsIndex)) { + character->unready(weapon); + } +} + +static void ctrl_ready_melee_weapons(class Character *character) +{ + class Container *container = character->getContainer(); + struct inv_entry *ie; +} + +static int ctrl_switch_to_melee_weapon(class Character *character) +{ + /* unready all weapons */ + ctrl_unready_all_weapons(character); + + /* ready any melee weapons */ + ctrl_ready_melee_weapons(character); + + /* ready any shields if hands are left open */ + + /* ready any missile weapons if hands are left open */ + +} +#endif + +static int ctrl_try_move_toward(class Character *character, int dx, int dy) +{ + int x = character->getX() + dx; + int y = character->getY() + dy; + + if (place_is_passable(character->getPlace(), x, y, character, 0)) { + switch (character->move(dx, dy)) { + case MovedOk: + case ExitedMap: + case SwitchedOccupants: + return 1; + default: + return 0; + } + } + + return 0; +} + +static int ctrl_move_away_from_target(class Character *character, + class Character *target) +{ + /* first try moving directly away from the target */ + int dx = character->getX() - target->getX(); + int dy = character->getY() - target->getY(); + + if (character->isStationary()) + return 0; + + /* normalize vector */ + dx = dx > 0 ? 1 : (dx < 0 ? -1 : 0); + dy = dy > 0 ? 1 : (dy < 0 ? -1 : 0); + + /* disallow diagonal moves */ + if (dx == 0 || dy == 0) { + if (ctrl_try_move_toward(character, dx, dy)) + return 1; + } + + /* try another vector */ + if (dx != 0) { + if (ctrl_try_move_toward(character, 0, 1)) + return 1; + if (ctrl_try_move_toward(character, 0, -1)) + return 1; + } + + if (dy != 0) { + if (ctrl_try_move_toward(character, 1, 0)) + return 1; + if (ctrl_try_move_toward(character, -1, 0)) + return 1; + } + + return 0; +} + +static bool ctrl_attack_target(class Character *character, + class Character *target) +{ + int distance; + bool attacked = false; + + distance = place_flying_distance(character->getPlace(), + character->getX(), character->getY(), + target->getX(), target->getY()); + + int armsIndex = 0; + int this_is_nth_attack = 0; + int slowest_attack_AP = 0; + int total_AP = 0; + int this_wpn_AP; + for (class ArmsType * weapon = character->enumerateWeapons(&armsIndex); + weapon != NULL; weapon = character->getNextWeapon(&armsIndex)) { + + // log_msg("DEBUG: wpn = %s (AP=%d), remaining AP=%d\n", + // weapon->getName(), weapon->getRequiredActionPoints(), character->getActionPoints() ); + if (distance > weapon->getRange()) { + continue; + } + + if (!character->hasAmmo(weapon)) { + continue; + } + + if (distance <= 1 && weapon->isMissileWeapon()) { + // Handle missile weapon interference + continue; + } + + this_is_nth_attack++; + ctrl_do_attack(character, weapon, target, character->getToHitPenalty()); + + // sum up AP requirement + this_wpn_AP = weapon->getRequiredActionPoints(); + if (this_wpn_AP > slowest_attack_AP) + { + slowest_attack_AP = this_wpn_AP; + } + total_AP += this_wpn_AP; + attacked = true; + + if (this_is_nth_attack == 1) { + // 1st weapon attack (usual case) + } + else if (this_is_nth_attack == 2) { + // 2st weapon attack (dual weapon, 2nd weapon) + int mult = kern_intvar_get("AP_MULT12:second_wpn_attack"); + this_wpn_AP = (int) (this_wpn_AP * mult) / 12; + } + else if (this_is_nth_attack >= 3) { + // 3rd+ weapon attack (unusual case for multi-limbed beings...) + int mult = kern_intvar_get("AP_MULT12:third_plus_wpn_attack"); + this_wpn_AP = (int) (this_wpn_AP * mult) / 12; + } + character->decActionPoints(this_wpn_AP); + //log_msg("DEBUG: after attack, used %d, remaining AP=%d\n", + // this_wpn_AP, character->getActionPoints() ); + statusRepaint(); + + if (target->isDead()) + break; + + // If the AP use is not over the multi-weapon extra allowance, continue: + int threshold = kern_intvar_get("AP_THRESHOLD:multi_attack_overage"); + if (character->getActionPoints() + threshold < 0) { + //log_msg("DEBUG: AP = %d, threshold = %d -- breaking multi-attack\n", + // character->getActionPoints(), threshold ); + break; + } + } + + if (character->needToRearm()) + character->armThyself(); + + return attacked; +} + +/* Data structure used by the ctrl_is_valid_target visitor function below */ +struct ctrl_select_target_data { + class Character *target; /* best target found so far */ + class Character *attacker; /* attacking character */ + int distance; /* distance to 'target' */ +}; + +/***************************************************************************** + * ctrl_is_valid_target - check if 'obj' is a valid target for 'attacker' + *****************************************************************************/ +static int ctrl_is_valid_target(class Character *attacker, class Object *obj) +{ + /* Skip NULL */ + if (! obj) + return 0; + + /* Skip non-characters */ + if (! obj->isType(CHARACTER_ID)) + return 0; + + /* Skip the attacker */ + if (obj == attacker) + return 0; + + /* Skip dead beings */ + if (obj->isDead()) + return 0; + + /* Skip non-hostiles */ + if (! are_hostile(attacker, (Being*)obj)) + return 0; + + /* Skip non-visible objects */ + if (! attacker->canSee(obj)) + return 0; + + /* Skip off-map beings (is this even possible?) */ + if (! obj->isOnMap()) + return 0; + + return 1; +} + +/***************************************************************************** + * ctrl_select_target_visitor - find and remember the closest valid target for + * an attacker + *****************************************************************************/ +static void ctrl_select_target_visitor(struct node *node, void *parm) +{ + class Object *obj; + struct ctrl_select_target_data *data; + int distance; + + /* Extract the typed variables from the generic parms */ + obj = (class Object*)node->ptr; + data = (struct ctrl_select_target_data *)parm; + + /* Check if this object makes a valid target */ + if (! ctrl_is_valid_target(data->attacker, obj)) + return; + + /* Compute the distance from attacker to obj */ + distance = place_flying_distance(data->attacker->getPlace(), + data->attacker->getX(), + data->attacker->getY(), + obj->getX(), + obj->getY()); + + /* Memoize the closest target and its distance */ + if (distance < data->distance) { + data->distance = distance; + data->target = (class Character*)obj; + } +} + +/***************************************************************************** + * ctrl_select_target - use a heuristic to pick a target for an attacker + *****************************************************************************/ +static class Character * ctrl_select_target(class Character *character) +{ + struct ctrl_select_target_data data; + + /* Initialize the search data. */ + data.attacker = character; + data.target = NULL; + data.distance = place_max_distance(character->getPlace()) + 1; + + /* Search all objects in the current place for targets. */ + node_foldr(place_get_all_objects(character->getPlace()), + ctrl_select_target_visitor, + &data); + + /* Check if one was found */ + if (data.target) { + character->setAttackTarget((class Character*)data.target); + return data.target; + } + + /* Try the old one */ + if (ctrl_is_valid_target(character, + character->getAttackTarget(NULL))) + return character->getAttackTarget(NULL); + + /* No valid targets */ + character->setAttackTarget(NULL); + return NULL; +} + + +static void ctrl_idle(class Character *character) +{ + class Character *target; + + if (character->getAI()) { + + /* closure returns true if it handled the turn, otherwise fall + * through to standard AI */ + if (closure_exec(character->getAI(), "p", character)) + return; + + if (character->getActionPoints() <= 0) + return; + } + + // ------------------------------------------------------------------- + // If they see an enemy they'll engage. Otherwise they just wander + // uselessly within the rectangular area imposed by their schedule (or + // freely if they have no schedule). + // ------------------------------------------------------------------- + + target = ctrl_select_target(character); + if (!target) { + ctrl_wander(character); + return; + } + + // ------------------------------------------------------------------- + // A bit confusing here next. If the NPC can't see a target I still let + // them pathfind. Why? Because the target might be "remembered" - maybe + // they were visible last turn and they just stepped out of LOS. + // ------------------------------------------------------------------- + + // note isOnMap checks so that if something has removed the character + // from the map (or killed it) as a result of its move attempt then + // you should quit having it wander around + + if (!character->canSee(target)) + { + if (! character->pathfindTo(target->getPlace(), + target->getX(), + target->getY())) + { + if (character->isOnMap()) + { + ctrl_wander(character); + } + return; + } + } + + if (ctrl_too_close_to_target(character, target)) { + if (! ctrl_move_away_from_target(character, target)) + /*if (! ctrl_switch_to_melee_weapon(character))*/ + ctrl_wander(character); + return; + } + + // ------------------------------------------------------------------- + // Then try force. + // ------------------------------------------------------------------- + + if (!ctrl_attack_target(character, target)) + { + if ((! character->pathfindTo(target->getPlace(), + target->getX(), + target->getY())) + && character->isOnMap()) + { + ctrl_wander(character); + } + } +} + +void ctrl_character_ai(class Character *character) +{ + if (character->isFleeing() + && character->flee()) { + return; + } + ctrl_idle(character); +} + +void ctrl_character_ui(class Character *character) +{ + struct KeyHandler kh; + /* Setup cmdwin prompt for first entry to the control loop */ + cmdwin_clear(); + cmdwin_push("%s:", character->getName()); + + /* Push the key handler and enter the event loop until character is + * done with turn */ + kh.fx = &ctrl_character_key_handler; + kh.data = character; + eventPushKeyHandler(&kh); + G_turnaround = SDL_GetTicks() - G_turnaround_start; + eventHandle(); + G_turnaround_start = SDL_GetTicks(); + eventPopKeyHandler(); + mapUpdate(REPAINT_IF_DIRTY); +} + +void ctrl_party_ui(class PlayerParty *party) +{ + struct KeyHandler kh; + + /* ready the cmdwin prompt */ + cmdwin_clear(); + cmdwin_push("Party [%d ap]:",party->getActionPoints()); + + kh.fx = &ctrl_party_key_handler; + kh.data = party; + eventPushKeyHandler(&kh); + G_turnaround = SDL_GetTicks() - G_turnaround_start; + eventHandle(); + G_turnaround_start = SDL_GetTicks(); + eventPopKeyHandler(); + mapUpdate(REPAINT_IF_DIRTY); +} diff --git a/src/ctrl.h b/src/ctrl.h new file mode 100644 index 0000000..86f1f60 --- /dev/null +++ b/src/ctrl.h @@ -0,0 +1,33 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef ctrl_h +#define ctrl_h + +extern void ctrl_party_ui(class PlayerParty *party); +extern void ctrl_party_ai(class Party *party); +extern void ctrl_character_ui(class Character *character); +extern void ctrl_character_ai(class Character *character); +extern void ctrl_wander(class Object *obj); +extern void ctrl_do_attack(class Character *character, class ArmsType *weapon, + class Character *target, int penalty); + +#endif diff --git a/src/cursor.cpp b/src/cursor.cpp new file mode 100644 index 0000000..10c8f61 --- /dev/null +++ b/src/cursor.cpp @@ -0,0 +1,198 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "cursor.h" +#include "place.h" +#include "map.h" +#include "templ.h" + +Cursor::Cursor() + : range(0) + , bounded(0) + , originX(0) + , originY(0) + , active(false) + , useRange(false) + , useZone(false) + , zone(0) +{ +} + +Cursor::~Cursor() +{ +} + +void Cursor::init(class ObjectType * type) +{ + Object::init(type); +} + +bool Cursor::inRange(int x, int y) +{ + if (useRange) { + // this works on wrapping maps + int d = place_flying_distance(getPlace(), originX, originY, + x, y); + + // Is the new location out of range? + if (d > range) { + return false; + } + } + + if (useZone) { + assert(zone); + if (! templ_get(zone, x, y)) { + return false; + } + } + + return true; +} + +enum MoveResult Cursor::move(int dx, int dy) +{ + // SAM: Found a few things, noted below. + // + // -- Cursor sometimes not drawn: + // If the cursor is moved out of LOS, it is not drawn. + // That is not desirable, methinks. + // + // -- Cursor range "any range within viewport" + // Cursor::setViewportBounded() makes this possible. + // The caller need only set the range to some large value, + // and turn on 'bounded'. + int newx = getX() + dx; + int newy = getY() + dy; + + newx = place_wrap_x(getPlace(), newx); + newy = place_wrap_y(getPlace(), newy); + + // Is the new location off the map? + if (place_off_map(getPlace(), newx, newy)) + return OffMap; + + // Is the new location out of the current viewport (without scrolling)? + if (bounded && !mapTileIsWithinViewport(newx,newy)) + return OutOfRange; + + // Is the new location out of range? + if (! inRange(newx, newy)) + return OutOfRange; + + // move the cursor + relocate(getPlace(), newx, newy, REL_NOTRIG); + + // Keep the cursor in view. + if (! mapIsInCameraView(getPlace(), getX(), getY())) { + mapCenterCamera(getX(), getY()); + } + + return MovedOk; +} + +void Cursor::setViewportBounded(bool val) +{ + bounded = val; +} + +void Cursor::setRange(int val) +{ + range = val; + useRange = true; +} + +void Cursor::setOrigin(int x, int y) +{ + originX = x; + originY = y; + if (zone) { + templ_set_origin(zone, x, y); + } +} + +void Cursor::relocate(struct place *newplace, int newx, int newy, bool noStep, + struct closure *place_switch_hook) +{ + Object::relocate(newplace, newx, newy, REL_NOTRIG, NULL); + active = true; +} + +void Cursor::remove() +{ + Object::remove(); + active = false; +} + +bool Cursor::is_active(void) +{ + return active; +} + +int Cursor::getRange() +{ + return range; +} + +int Cursor::getOriginX() +{ + return originX; +} + +int Cursor::getOriginY() +{ + return originY; +} + +void Cursor::shadeRange(bool val) +{ + shade = val; +} + +bool Cursor::isRangeShaded() +{ + return shade; +} + +void Cursor::setZone(struct templ *val) +{ + if (zone) { + templ_unref(zone); + zone = 0; + useZone = false; + } + + if (val) { + templ_ref(val); + zone = val; + useZone = true; + templ_set_origin(zone, originX, originY); + } +} + +void Cursor::reset() +{ + setZone(0); + setRange(0); + useRange = false; + shade = false; + active = false; +} diff --git a/src/cursor.h b/src/cursor.h new file mode 100644 index 0000000..4281e20 --- /dev/null +++ b/src/cursor.h @@ -0,0 +1,61 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef cursor_h +#define cursor_h + +#include "object.h" + +class Cursor:public Object { + public: + Cursor(); + + virtual ~ Cursor(); + virtual void init(class ObjectType * type); + virtual enum MoveResult move(int dx, int dy); + virtual void relocate(struct place *newplace, int newx, int newy, + bool noStep = true, + struct closure *place_switch_hook = NULL); + virtual void remove(); + + bool is_active(void); + void setViewportBounded(bool val); + int getRange(); + void setRange(int val); + void setOrigin(int x, int y); + int getOriginX(); + int getOriginY(); + bool inRange(int x, int y); + void shadeRange(bool val); + bool isRangeShaded(); + void setZone(struct templ *zone); + void reset(); + + protected: + int range, bounded, originX, originY; + bool active; + bool shade; + bool useRange; + bool useZone; + struct templ *zone; +}; + +#endif // cursor_h diff --git a/src/debug.c b/src/debug.c new file mode 100644 index 0000000..3aa29dc --- /dev/null +++ b/src/debug.c @@ -0,0 +1,52 @@ +#include "debug.h" + +#include +#include +#include + +// revisit: make these command-line options +int DEBUG = 1; +int VERBOSE = 1; + +void dbg(const char *fmt, ...) +{ + if (DEBUG) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + } +} + +void err(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + fprintf(stderr, "\n"); + exit(-1); +} + +void info(const char *fmt, ...) +{ + if (VERBOSE) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + } +} + +void warn(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + +void vwarn(const char *fmt, va_list args) +{ + vprintf(fmt, args); +} diff --git a/src/debug.h b/src/debug.h new file mode 100644 index 0000000..6194183 --- /dev/null +++ b/src/debug.h @@ -0,0 +1,43 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +/* Ripped this off from linux/include/linux/usb.h + */ +#ifndef debug_h +#define debug_h + +#include "macros.h" +#include + +BEGIN_DECL + +extern int DEBUG; +extern int VERBOSE; + +extern void dbg(const char *fmt, ...); +extern void err(const char *fmt, ...); +extern void info(const char *fmt, ...); +extern void warn(const char *fmt, ...); +extern void vwarn(const char *fmt, va_list args); + +END_DECL + +#endif diff --git a/src/dice.c b/src/dice.c new file mode 100644 index 0000000..af26aa5 --- /dev/null +++ b/src/dice.c @@ -0,0 +1,167 @@ +#include +#include +#include + +static int dice_parse(const char *ptr, int *num, int *faces, int *bias) +{ + int state = 0; + int val = 0; + int sign = 1; + + *num = 0; + *faces = 0; + *bias = 0; + + while (*ptr) { + switch (state) { + + case 0: + if (*ptr == '+') { + sign = 1; + state = 4; + } else if (*ptr == '-') { + sign = -1; + state = 4; + } else if (isdigit(*ptr)) { + val = *ptr - '0'; + if (val) + state = 1; + } else { + goto error; + } + break; + + case 1: + if (*ptr == 'd') { + *num = val * sign; + val = 0; + sign = 1; + state = 2; + } else if (isdigit(*ptr)) { + val = (val * 10) + *ptr - '0'; + } else { + goto error; + } + break; + + case 2: + if (isdigit(*ptr)) { + val = *ptr - '0'; + if (val) + state = 3; + } else { + goto error; + } + break; + + case 3: + if (isdigit(*ptr)) { + val = (val * 10) + *ptr - '0'; + } else if (*ptr == '+') { + *faces = val; + val = 0; + state = 4; + sign = 1; + } else if (*ptr == '-') { + *faces = val; + val = 0; + state = 4; + sign = -1; + } else { + goto error; + } + break; + + case 4: + if (isdigit(*ptr)) { + val = atoi(ptr); + if (val) + state = 5; + } else { + goto error; + } + break; + + case 5: + if (isdigit(*ptr)) { + val = (val * 10) + *ptr - '0'; + } else { + goto error; + } + break; + default: + assert(false); /* impossible state */ + goto error; + } + + ptr++; + } + + switch (state) { + case 0: + break; + case 1: + *bias = val * sign; + break; + case 2: + goto error; + break; + case 3: + *faces = val * sign; + break; + case 4: + *bias = val * sign; + break; + case 5: + *bias = val * sign; + break; + default: + assert(false); /* impossible state */ + goto error; + } + + return 0; + + error: + return -1; +} + +int dice_roll_numeric(int num, int faces, int bias) +{ + int val = 0; + while (num--) { + val += (rand() % faces) + 1; + } + val += bias; + return val; +} + +int dice_roll(const char *ptr) +{ + int num = 0; + int faces = 0; + int bias = 0; + + if (dice_parse(ptr, &num, &faces, &bias)) { + assert(false); /* if uncertain, caller should have checked + * first */ + return 0; + } + + return dice_roll_numeric(num,faces,bias); +} + +int dice_valid(const char *fmt) +{ + int num, faces, bias; + if (!fmt) + return 0; + return dice_parse(fmt, &num, &faces, &bias) ? 0 : 1; +} + +int dice_average(const char *fmt) +{ + int num, faces, bias; + dice_parse(fmt, &num, &faces, &bias); + return ((faces / 2) + 1) * num + bias; +} diff --git a/src/dice.h b/src/dice.h new file mode 100644 index 0000000..73ee81b --- /dev/null +++ b/src/dice.h @@ -0,0 +1,23 @@ + +/* A dice roll is specified by a string format. For example, "2d20+6". The + * legal formats are defined by a regular expression: + * + * ([1-9][0-9]*]d[1-9][0-9]*)?([\+\-]?[1-9][0-9]*)? + * + * Which means the following are all legal examples: + * + * "1d1" + * "2" + * "" (note: returns 0) + * "5064d21023902-10909012" + * + * The result of the dice roll is returned. If the format is invalid then it + * will always return 0, but since 0 is a valid response you won't necessarily + * be able to tell. To check if a format is bad use the separate dice_valid() + * call, which returns non-zero if the format is ok and 0 otherwise. + * + */ +extern int dice_roll(const char *fmt); +extern int dice_valid(const char *fmt); +extern int dice_average(const char *fmt); +extern int dice_roll_numeric(int num, int faces, int bias); diff --git a/src/dimensions.c b/src/dimensions.c new file mode 100644 index 0000000..33466d1 --- /dev/null +++ b/src/dimensions.c @@ -0,0 +1,152 @@ +/* + * nazghul - an old-school RPG engine + * Copyright (C) 2002, 2003 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * Gordon McNutt + * gmcnutt@users.sourceforge.net + */ + +#include "dimensions.h" +#include "common.h" /* for MOON_WINDOW_W */ +#include "cfg.h" + +#include + +int STATUS_MAX_MSG_SZ; +int SCREEN_W; +int SCREEN_H; +int CONSOLE_MAX_MSG_SZ; +int MAP_TILE_W; +int MAP_TILE_H; +int MAP_X; +int MAP_Y; +int MAP_W; +int MAP_H; +int CMD_X; +int CMD_Y; +int CMD_W; +int CMD_H; +int STAT_X; +int STAT_Y; +int STAT_W; +int STAT_H; +int STAT_H_MAX; +int FOOGOD_X; +int FOOGOD_Y; +int FOOGOD_W; +int FOOGOD_H; +int WIND_X; +int WIND_Y; +int WIND_W; +int WIND_H; +int CONS_X; +int CONS_Y; +int CONS_W; +int CONS_H; +int CONS_LINES; +int SKY_X; +int SKY_Y; +int SKY_W; +int SKY_H; +int SKY_SPRITE_W; + +/* dimensions_get_map_size -- figure out the biggest map window that will + * satisfy the screen dimensions. */ +static int dimensions_get_map_size(char *dimstr) +{ + struct dimstr2mapsz { + const char *dimstr; + int map_sz; + }; +# define ADD_SCREEN_DIM(dim,mapw) { (dim), (mapw) }, + struct dimstr2mapsz tbl[] = { +# include "screen_dims.h" + }; + + int i; + + if (!dimstr) { + warn("warn: NULL dimensions"); + return -1; + } + + for (i = 0; i < array_sz(tbl); i++) { + if (! strcmp(tbl[i].dimstr, dimstr)) { + return tbl[i].map_sz; + } + } + + warn("warn: screen res %s not found in table\n", dimstr); + return -1; +} + +int dimensions_init() +{ + int map_size = dimensions_get_map_size(cfg_get("screen-dims")); + if (map_size < 0) + return -1; + + MAP_TILE_W = map_size; + MAP_TILE_H = map_size; + + MAP_X = BORDER_W; + MAP_Y = BORDER_H; + MAP_W = (TILE_W * MAP_TILE_W); + MAP_H = (TILE_H * MAP_TILE_H); + + CMD_X = MAP_X; + CMD_Y = (MAP_Y + MAP_H + BORDER_H); + CMD_W = MAP_W; + CMD_H = ASCII_H; + + SCREEN_H = (BORDER_H * 3 + MAP_H + CMD_H); + + STATUS_MAX_MSG_SZ = 128; + STAT_X = (MAP_X + MAP_W + BORDER_W); + STAT_Y = BORDER_H; + STAT_W = (/*BORDER_W * 2*/ + ASCII_W * STAT_CHARS_PER_LINE); + STAT_H = (3 * TILE_H); + STAT_H_MAX = (16 * TILE_H); + + CONS_X = STAT_X; + CONS_Y = (FOOGOD_Y + FOOGOD_H + BORDER_H); + CONS_W = STAT_W; + CONS_H = (SCREEN_H - BORDER_H - CONS_Y); + CONS_LINES = (CONS_H / ASCII_H); + + CONSOLE_MAX_MSG_SZ = (CONS_W / ASCII_W); + + FOOGOD_X = STAT_X; + FOOGOD_Y = (STAT_Y + STAT_H + BORDER_H); + FOOGOD_W = STAT_W; + FOOGOD_H = (2 * ASCII_H); + + WIND_W = (strlen("wind:northeast") * ASCII_W); + WIND_H = BORDER_H; + WIND_X = (BORDER_W + (MAP_W - WIND_W) / 2); + WIND_Y = (MAP_Y + MAP_H); + + SKY_W = MOON_WINDOW_W; + SKY_H = BORDER_H; + SKY_X = (MAP_X + (MAP_W - SKY_W) / 2); + SKY_Y = 0; + SKY_SPRITE_W = (TILE_W/2); + + SCREEN_W = (BORDER_W * 3 + MAP_W + CONS_W); + + return 0; +} diff --git a/src/dimensions.h b/src/dimensions.h new file mode 100644 index 0000000..06787fa --- /dev/null +++ b/src/dimensions.h @@ -0,0 +1,92 @@ +/* + * nazghul - an old-school RPG engine + * Copyright (C) 2002, 2003 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * Gordon McNutt + * gmcnutt@users.sourceforge.net + */ +#ifndef dimensions_h +#define dimensions_h + +#include "macros.h" + +BEGIN_DECL + +#define STAT_CHARS_PER_LINE 46 + +#define TILE_W 32 +#define TILE_H 32 +#define ASCII_W 8 +#define ASCII_H 16 +#define BORDER_W 16 +#define BORDER_H 16 + +#define MIN_MAP_SIZE 11 +#define MAX_MAP_SIZE 19 +#define DEF_MAP_SIZE 19 + +extern int STATUS_MAX_MSG_SZ; +extern int SCREEN_W; +extern int SCREEN_H; +extern int CONSOLE_MAX_MSG_SZ; + +extern int MAP_TILE_W; +extern int MAP_TILE_H; +extern int MAP_X; +extern int MAP_Y; +extern int MAP_W; +extern int MAP_H; + +extern int CMD_X; +extern int CMD_Y; +extern int CMD_W; +extern int CMD_H; + +extern int STAT_X; +extern int STAT_Y; +extern int STAT_W; +extern int STAT_H; +extern int STAT_H_MAX; + +extern int FOOGOD_X; +extern int FOOGOD_Y; +extern int FOOGOD_W; +extern int FOOGOD_H; + +extern int WIND_X; +extern int WIND_Y; +extern int WIND_W; +extern int WIND_H; + +extern int CONS_X; +extern int CONS_Y; +extern int CONS_W; +extern int CONS_H; +extern int CONS_LINES; + +extern int SKY_X; +extern int SKY_Y; +extern int SKY_W; +extern int SKY_H; +extern int SKY_SPRITE_W; + +/* Set all the runtime-configurable UI dimensions */ +int dimensions_init(); + +END_DECL + +#endif diff --git a/src/dtable.c b/src/dtable.c new file mode 100644 index 0000000..aa9d21f --- /dev/null +++ b/src/dtable.c @@ -0,0 +1,171 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "dtable.h" +#include "debug.h" +#include "session.h" /* for save */ + +#include +#include + +#define dtable_is_valid_faction(dtable,fac) \ + ((fac) >= 0 && (fac) < (dtable)->n_factions) + +#define dtable_clamp_level(dtable,lvl) \ + clamp((lvl), (dtable)->lower_bound, (dtable)->upper_bound) + +struct dtable *dtable_new(int n_factions) +{ + struct dtable *dtable; + + /* allocate the "main" struct */ + dtable = (struct dtable*)calloc(1, sizeof(*dtable)); + assert(dtable); + + dtable->n_factions = n_factions; + + /* allocate the table of stack pointers */ + dtable->table = (int*)calloc(n_factions * n_factions, + sizeof(dtable->table[0])); + assert(dtable->table); + + /* For now, hardcode the table limits and settings. Note that we must + * set the upper and lower bounds before poking any entries into the + * table. */ + dtable_set_hostile(dtable, DTABLE_DEFAULT_HOSTILE); + dtable_set_allies(dtable, DTABLE_DEFAULT_ALLIES); + dtable_set_upper_bound(dtable, DTABLE_DEFAULT_UPPER_BOUND); + dtable_set_lower_bound(dtable, DTABLE_DEFAULT_LOWER_BOUND); + + return dtable; +} + +static int dtable_check(struct dtable *dtable, int faction) +{ + if (! dtable_is_valid_faction(dtable, faction)) { + warn("dtable_check: invalid faction=%d\n", faction); + return -1; + } + + return 0; +} + +static int dtable_index(struct dtable *dtable, int f1, int f2) +{ + if (dtable_check(dtable, f1)) + return -1; + + if (dtable_check(dtable, f2)) + return -1; + + return f1 * dtable->n_factions + f2; + +} + +void dtable_set(struct dtable *dtable, int f1, int f2, int level) +{ + int index; + + dtable_clamp_level(dtable, level); + + if ((index = dtable_index(dtable, f1, f2)) < 0) + return; + + dtable->table[index] = level; + + /* mirror the change on the other half of the table */ + index = dtable_index(dtable, f2, f1); + dtable->table[index] = level; +} + +int dtable_get(struct dtable *dtable, int f1, int f2) +{ + int index; + + if ((index = dtable_index(dtable, f1, f2)) < 0) { + warn("dtable_get: defaulting to neutral\n"); + return 0; + } + + return dtable->table[index]; +} + +void dtable_del(struct dtable *dtable) +{ + assert(dtable); + + if (dtable->table) { + free(dtable->table); + } + free(dtable); +} + + +void dtable_save(struct dtable *dtable, struct save *save) +{ + int rows; + int cols; + int index; + + save->enter(save, "(kern-mk-dtable\n"); + + index = 0; + for (rows = 0; rows < dtable->n_factions; rows++) { + save->write(save, "(list "); + for (cols = 0; cols < dtable->n_factions; cols++) { + save->write(save, "%2d ", dtable->table[index]); + index++; + } + save->append(save, ")\n"); + } + + save->exit(save, ")\n"); +} + +void dtable_inc(struct dtable *dtable, int f1, int f2) +{ + int level; + + level = dtable_get(dtable, f1, f2); + dtable_set(dtable, f1, f2, level+1); +} + +void dtable_dec(struct dtable *dtable, int f1, int f2) +{ + int level; + + level = dtable_get(dtable, f1, f2); + dtable_set(dtable, f1, f2, level-1); + +} + +extern const char *dtable_describe(struct dtable *dtable, int f1, int f2) +{ + int level = dtable_get(dtable, f1, f2); + + if (level <= dtable->hostile) + return "hostile"; + else if (level >= dtable->allies) + return "allied"; + else + return "neutral"; +} diff --git a/src/dtable.h b/src/dtable.h new file mode 100644 index 0000000..084979d --- /dev/null +++ b/src/dtable.h @@ -0,0 +1,70 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#ifndef dtable_h +#define dtable_h + +#include "macros.h" + +BEGIN_DECL + +#define FACTION_NONE 0 +#define DTABLE_DEFAULT_LOWER_BOUND -2 +#define DTABLE_DEFAULT_UPPER_BOUND 2 +#define DTABLE_DEFAULT_HOSTILE -2 +#define DTABLE_DEFAULT_ALLIES 2 + +#define dtable_are_hostile(dtable,f1, f2) \ + (dtable_get((dtable),(f1),(f2)) <= dtable_hostile((dtable))) + +#define dtable_are_allies(dtable,f1, f2) \ + (dtable_get((dtable),(f1),(f2)) >= dtable_allies((dtable))) + +#define dtable_set_hostile(tab,lvl) ((tab)->hostile = (lvl)) +#define dtable_set_allies(tab,lvl) ((tab)->allies = (lvl)) +#define dtable_set_lower_bound(tab,lvl) ((tab)->lower_bound = (lvl)) +#define dtable_set_upper_bound(tab,lvl) ((tab)->upper_bound = (lvl)) + +#define dtable_hostile(tab) ((tab)->hostile) +#define dtable_allies(tab) ((tab)->allies) + +struct dtable { + int n_factions; + int hostile; + int allies; + int lower_bound; + int upper_bound; + int *table; +}; + +extern struct dtable *dtable_new(int n_factions); +extern void dtable_del(struct dtable *dtable); +extern void dtable_set(struct dtable *dtable, int f1, int f2, int level); +extern int dtable_get(struct dtable *dtable, int f1, int f2); +extern void dtable_save(struct dtable *dtable, struct save *save); +extern void dtable_inc(struct dtable *dtable, int f1, int f2); +extern void dtable_dec(struct dtable *dtable, int f1, int f2); +extern const char *dtable_describe(struct dtable *dtable, int f1, int f2); + +END_DECL + +#endif diff --git a/src/dup_constants.h b/src/dup_constants.h new file mode 100644 index 0000000..4b36c9e --- /dev/null +++ b/src/dup_constants.h @@ -0,0 +1,91 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef dup_constants_h +#define dup_constants_h + +// This section defines the mechanism events reserved by the game engine. +#define MECH_ATTACK 1 +#define MECH_STEP 2 +#define MECH_HANDLE 3 +#define MECH_OPEN 4 +#define MECH_CLOSE 5 +#define MECH_LOCK 6 +#define MECH_UNLOCK 7 +#define MECH_MAGIC_LOCK 8 +#define MECH_MAGIC_UNLOCK 9 +#define MECH_TURN 10 +#define MECH_FULL_MOON 11 + +// This value marks the beginning of the unreserved events. A game script can +// define its own events and number them starting from here. +#define MECH_FIRST_UNRESERVED_EVENT 100 + +/* Effects */ +// gmcnutt: EFFECT_NATURAL was bit 30, and is intended to be used for natural +// abilities (like snakes spitting venom) so that they will not be affected by +// negate magic. But I ran into a problem: I needed to add EFFECT_RESTORE for +// mana restoration potions, but I found that using a constant with bit 31 set +// did not work out right. The parser uses atol(), which sees the high bit set +// and I think assumes it's an overflow, so it converts the value to LONG_MAX, +// which isn't what we intended. Since I'm basically out of bits something had +// to give, and I sacrificed EFFECT_NATURAL for EFFECT_RESTORE. +// +// During the 0.3.x development line we'll address this issue. A simple thing +// to do would be to start using multi-byte bitmaps and fix the parser. But the +// new effect system may make this a non-issue anyway, so let's wait and see. +// +#define EFFECT_NATURAL 0 +#define EFFECT_NONE 0 +#define EFFECT_POISON 1 /* 0 */ +#define EFFECT_BURN 2 /* 1 */ +#define EFFECT_SLEEP 4 /* 2 */ +#define EFFECT_LIGHT 8 /* 3 */ +#define EFFECT_CURE 16 /* 4 */ +#define EFFECT_HEAL 32 /* 5 */ +#define EFFECT_AWAKEN 64 /* 6 */ +#define EFFECT_CHARM 128 /* 7 */ +#define EFFECT_DAMAGE 256 /* 8 */ +#define EFFECT_UNLOCK 512 /* 9 */ +#define EFFECT_REPEL 1024 /* 10 */ +#define EFFECT_LOCATE 2048 /* 11 */ +#define EFFECT_SUMMON 4096 /* 12 */ +#define EFFECT_WIND_CHANGE 8192 /* 13 */ +#define EFFECT_TELEPORT 16384 /* 14 */ +#define EFFECT_DESTROY 32768 /* 15 */ +#define EFFECT_ARMOUR 65536 /* 16 */ +#define EFFECT_REVEAL 131072 /* 17 */ +#define EFFECT_QUICK 262144 /* 18 */ +#define EFFECT_NEGATE 524288 /* 19 */ +#define EFFECT_TREMOR 1048576 /* 20 */ +#define EFFECT_CONFUSE 2097152 /* 21 */ +#define EFFECT_SHOW_TERRAIN 4194304 /* 22 */ +#define EFFECT_WIND 8388608 /* 23 */ +#define EFFECT_PEER 16777216 /* 24 */ +#define EFFECT_CLONE 33554432 /* 25 */ +#define EFFECT_INVISIBLE 67108864 /* 26 */ +#define EFFECT_TIME_STOP 134217728 /* 27 */ +#define EFFECT_RESURRECT 268435456 /* 28 */ +#define EFFECT_GATE_TRAVEL 536870912 /* 29 */ +#define EFFECT_RESTORE 1073741824 /* 30 */ +// WARNING: bit 31 will not work as intended! We are out of bits! + +#endif diff --git a/src/effect.c b/src/effect.c new file mode 100644 index 0000000..c0fb0a1 --- /dev/null +++ b/src/effect.c @@ -0,0 +1,83 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2004 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "effect.h" + +#include +#include +#include + +const int EFFECT_ID = 0xeffec1; + +struct effect *effect_new(char *tag, scheme *sc, pointer exec_proc, + pointer apply_proc, pointer rm_proc, + pointer restart, + char *name) +{ + struct effect *et; + + et = (struct effect*)calloc(1, sizeof(*et)); + assert(et); + + et->ID = EFFECT_ID; + + if (exec_proc) { + et->exec = closure_new_ref(sc, exec_proc); + } + + if (apply_proc) { + et->apply = closure_new_ref(sc, apply_proc); + } + + if (rm_proc) { + et->rm = closure_new_ref(sc, rm_proc); + } + + if (restart) { + et->restart = closure_new_ref(sc, restart); + } + + et->tag = strdup(tag); + assert(et->tag); + + /* Effects with no name should be considered invisible to the UI */ + if (name) { + et->name = strdup(name); + assert(et->name); + } + + return et; +} + +extern void effect_del(struct effect *et) +{ + free(et->tag); + free(et->name); + closure_unref_safe(et->exec); + closure_unref_safe(et->apply); + closure_unref_safe(et->rm); + closure_unref_safe(et->restart); + /* Need to free sprite? Nope -- sprites are global resources + * managed by the session. When the session is torn down it frees all + * of the sprites created when it loaded. */ + free(et); +} diff --git a/src/effect.h b/src/effect.h new file mode 100644 index 0000000..f396b22 --- /dev/null +++ b/src/effect.h @@ -0,0 +1,71 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2004 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef effect_h +#define effect_h + +#include "macros.h" +#include "closure.h" + +BEGIN_DECL + +/* Negative expiration codes */ +#define EFFECT_PERMANENT -1 /* never expires */ +#define EFFECT_NONDETERMINISTIC -2 /* can't tell when it expires */ + +/* Runtime type-verification: */ +extern const int EFFECT_ID; +#define is_effect(eff) ((eff) && ((eff)->ID == EFFECT_ID)) +#define effect_will_expire(eff) ((eff)->duration > 0) + +/* An effect type defines an effect like poison, protection, etc. Effects are + * attached to objects. */ +struct effect { + int ID; /* for runtime type-verification */ + closure_t *exec; /* scheme proc to execute on-hook */ + closure_t *apply; /* scheme proc to execute on-attach */ + closure_t *rm; /* scheme proc to execute on-removal */ + closure_t *restart; /* scheme proc to restart effect on reload */ + char *tag; /* identifier tag name */ + char *name; /* short name */ + struct sprite *sprite; /* might be used in ztats window */ + int detect_dc; /* detection difficulty class (default zero) */ + int cumulative; /* more then one instance can be attached */ + int duration; /* minutes before expire (-1 for never) */ + int hook_id; /* hook the effect attaches to */ + struct sprite *status_icon; /* 8x16 sprite for status window */ +}; + +/* Create the closure and dup the strings. Zero out other fields (caller must + * fill them in). */ +extern struct effect *effect_new(char *tag, scheme *sc, + pointer exec, + pointer apply, + pointer rm, + pointer restart, + char *name); + +/* Dealloc the closure, the strings and the struct. */ +extern void effect_del(struct effect *effect); + +END_DECL + +#endif diff --git a/src/escape.c b/src/escape.c new file mode 100644 index 0000000..9f34bb9 --- /dev/null +++ b/src/escape.c @@ -0,0 +1,110 @@ +/* + * nazghul - an old-school RPG engine + * Copyright (C) 2008 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * Gordon McNutt + * gmcnutt@users.sourceforge.net + */ + +#include "cmd.h" +#include "event.h" +#include "log.h" +#include "session.h" + +#include + +static struct KeyHandler esc_key_hndlr; + +static void esc_help(void) +{ + log_begin("F)ollow mode\n"); + log_continue("Q)uit\n"); + log_continue("[1-9] Solo mode\n"); + log_continue("CTRL-R)eload\n"); + log_continue("CTRL-S)ave\n"); + log_end("ESC to continue game\n"); +} + +static int esc_menu_key_fx(struct KeyHandler *kh, int key, int keymod) +{ + switch (key) { + case 'f': + cmdToggleFollowMode(); + return 1; + case 'q': + cmdQuit(); + return 1; + case SDLK_1: + case SDLK_2: + case SDLK_3: + case SDLK_4: + case SDLK_5: + case SDLK_6: + case SDLK_7: + case SDLK_8: + case SDLK_9: + cmdSetSoloMode(key - SDLK_1); + return 1; + case KEY_CTRL_S: + cmdSave(); + break; + case KEY_CTRL_R: + cmdReload(); + return 1; + case SDLK_F10: + cmdSettings(); + break; + case SDLK_ESCAPE: + log_msg("Continue"); + return 1; + case '?': + esc_help(); + break; + default: + //log_msg("Sorry, %d is not a valid command."); + break; + } + return 0; +} + +static int esc_key_fx(struct KeyHandler *esckh, int key, int keymod) +{ + struct KeyHandler kh; + + if (SDLK_ESCAPE != key) { + return 0; + } + + log_banner("ESC mode - press '?' for help"); + + kh.fx = esc_menu_key_fx; + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + return 0; +} + +void escape_start_handler(void) +{ + esc_key_hndlr.fx = esc_key_fx; + eventPushKeyHandler(&esc_key_hndlr); +} + +void escape_stop_handler(void) +{ + eventPopKeyHandler(); +} diff --git a/src/escape.h b/src/escape.h new file mode 100644 index 0000000..1786f3a --- /dev/null +++ b/src/escape.h @@ -0,0 +1,28 @@ +/* + * nazghul - an old-school RPG engine + * Copyright (C) 2008 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * Gordon McNutt + * gmcnutt@users.sourceforge.net + */ +#ifndef escape_h +#define escape_h + +void escape_start_handler(void); +void escape_stop_handler(void); + +#endif diff --git a/src/event.c b/src/event.c new file mode 100644 index 0000000..a90548b --- /dev/null +++ b/src/event.c @@ -0,0 +1,433 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "event.h" +#include "cfg.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef DEBUG_KEYS +# define DEBUG_KEYS 0 +#endif + +#define EVENT_NONBLOCK (1 << 0) +#define EVENT_NOPLAYBACK (1 << 1) + +#define getHandler(stack,type) \ + (list_empty((stack)) ? NULL : (type*)(stack)->next) +#define pushHandler(stack,handler) (list_add((stack), &(handler)->list)) + +typedef struct { + struct list list; + SDL_Event event; +} sdl_event_list_t; + +static struct list KeyHandlers; +static struct list TickHandlers; +static struct list QuitHandlers; +static struct list MouseButtonHandlers; +static struct list MouseMotionHandlers; +static struct list backlog; + +static bool record_events; +static int record_fd; +static bool playback_events; +static int playback_fd; +static int event_playback_speed = 0; + +static void (*eventHook) (void); +static int (*wait_event) (SDL_Event * event, int flags); +static int qcount = 0; + +static struct list *popHandler(struct list *stack) +{ + if (list_empty(stack)) { + return NULL; + } + + struct list *lptr = stack->next; + list_remove(lptr); + return lptr; +} + +static void backlog_enqueue(SDL_Event *event) +{ + sdl_event_list_t *elem = (sdl_event_list_t*)malloc(sizeof(*elem)); + elem->event = *event; + list_add(&backlog, &elem->list); + qcount++; +} + +static int backlog_dequeue(SDL_Event *event) +{ + sdl_event_list_t *elem; + struct list *ptr; + if (list_empty(&backlog)) + return -1; + ptr = backlog.next; + elem = outcast(ptr, sdl_event_list_t, list); + list_remove(&elem->list); + *event = elem->event; + free(elem); + qcount--; + return 0; +} + +static int mapKey(SDL_keysym * keysym) +{ + int key = keysym->sym; + + if (DEBUG_KEYS) { + printf("sym='%c'[%d] mod=%02x unicode=%04x\n", + keysym->sym, + keysym->sym, + keysym->mod, + keysym->unicode); + } + + /* If the key has a UNICODE representation and its from the default + * Basic Latin code page then return it as an ASCII character. */ + /* fixme: unicode is messing up ctrl+key sequences */ + if (keysym->unicode) { + + /* Map CR to LF (legacy code expects this) */ + if (keysym->unicode == 0x000d) + return '\n'; + + /* Map all other Basic Latin codes to ASCII */ + if (keysym->unicode < 0x7f) + return keysym->unicode & 0x7f; + + /* Code page not supported... fall through */ + } + + /* Map arrow keys to equivalent numberpad entries */ + if (key >= SDLK_UP && key <= SDLK_LEFT) { + static int map[] = { KEY_NORTH, KEY_SOUTH, KEY_EAST, + KEY_WEST }; + key = map[key - SDLK_UP]; + } + + /* Set the "shift" bit */ + if (keysym->mod & KMOD_SHIFT) { + key |= KEY_SHIFT; + } + + /* Unsupported? fallback to the SDL sym */ + return key; +} + +static int event_get_next_event(SDL_Event *event, int flags) +{ + /* if a key handler exists */ + if (getHandler(&KeyHandlers, struct KeyHandler)) { + + /* if the backlog queue is not empty */ + if (! backlog_dequeue(event)) { + + /* get the event from the backlog queue */ + return 1; + } + } + + if (flags & EVENT_NONBLOCK) + return SDL_PollEvent(event); + else + return SDL_WaitEvent(event); +} + +static int playback_event(SDL_Event * event, int flags) +{ + // For now use the expedient but non-portable technique of reading the + // binary data straight to the file. + int n; + int len = sizeof(SDL_Event); + char *ptr = (char *) event; + + if (flags & EVENT_NOPLAYBACK) + return 0; + + + while (len) { + n = read(playback_fd, ptr, len); + if (n == -1) { + perror("read"); + return -1; + } + ptr += n; + len -= n; + } + + SDL_Delay(event_playback_speed); + + return 1; +} + +static void record_event(SDL_Event * event) +{ + // For now use the expedient but non-portable technique of writing the + // binary data straight to the file. + int n; + int len = sizeof(SDL_Event); + char *ptr = (char *) event; + while (len) { + n = write(record_fd, ptr, len); + if (n == -1) { + perror("write"); + return; + } + ptr += n; + len -= n; + } +} + +static void event_handle_aux(int flags) +{ + bool done = false; + bool use_hook = false; + + while (!done) { + + SDL_Event event; + if (!wait_event(&event, flags)) { + return; + } + if (record_events) + record_event(&event); + + switch (event.type) { + + case SDL_USEREVENT: + { + struct TickHandler *tickh; + tickh = getHandler(&TickHandlers, + struct TickHandler); + if (tickh) { + use_hook = true; + if (tickh->fx(tickh)) { + done = true; + } + } + + } + break; + + case SDL_KEYDOWN: + { + struct KeyHandler *keyh; + keyh = getHandler(&KeyHandlers, + struct KeyHandler); + if (keyh) { + int mapped_key = + mapKey(&event.key.keysym); + use_hook = true; + if (keyh->fx(keyh, mapped_key, + event.key.keysym.mod)) { + done = true; + } + } else { + /* enqueue this event */ + backlog_enqueue(&event); + } + } + break; + + case SDL_QUIT: + { + struct QuitHandler *quith; + quith = + getHandler(&QuitHandlers, + struct QuitHandler); + if (quith && quith->fx(quith)) + done = true; + } + break; + + case SDL_MOUSEBUTTONDOWN: + { + struct MouseButtonHandler *mouseh; + mouseh = getHandler(&MouseButtonHandlers, + struct MouseButtonHandler); + if (mouseh && + mouseh->fx(mouseh, &event.button)) { + done = true; + } + } + break; + + case SDL_MOUSEMOTION: + { + struct MouseMotionHandler *mouseh; + mouseh = getHandler(&MouseMotionHandlers, + struct MouseMotionHandler); + if (mouseh && + mouseh->fx(mouseh, &event.motion)) { + done = true; + } + } + break; + + default: + break; + } + + if (use_hook && eventHook) + eventHook(); + + } + +} + +int eventInit(void) +{ + char *record_fname = cfg_get("record-filename"); + char *playback_fname = cfg_get("playback-filename"); + + list_init(&KeyHandlers); + list_init(&TickHandlers); + list_init(&QuitHandlers); + list_init(&MouseButtonHandlers); + list_init(&MouseMotionHandlers); + list_init(&backlog); + eventHook = NULL; + wait_event = event_get_next_event; + qcount=0; + + if (record_fname != NULL) { + record_events = true; + record_fd = open(record_fname, O_WRONLY | O_CREAT, 00666); + if (record_fd == -1) { + perror(record_fname); + return -1; + } + } + + if (playback_fname != NULL) { + char *playback_spd_str = cfg_get("playback-speed"); + playback_events = true; + playback_fd = open(playback_fname, O_RDONLY, 00666); + if (playback_fd == -1) { + perror(playback_fname); + return -1; + } + // Override the normal wait_event routine + wait_event = playback_event; + + /* Set the play back speed. */ + if (playback_spd_str) { + event_playback_speed = atoi(playback_spd_str); + } + } + + SDL_EnableUNICODE(1); + + return 0; +} + +void eventExit(void) +{ + /* cleanup the backlog queue */ + SDL_Event event; + while (! backlog_dequeue(&event)) + ; +} + +void eventHandle(void) +{ + event_handle_aux(0); +} + +void eventHandlePending(void) +{ + event_handle_aux(EVENT_NONBLOCK|EVENT_NOPLAYBACK); +} + +void eventPushKeyHandler(struct KeyHandler *keyh) +{ + pushHandler(&KeyHandlers, keyh); +} + +struct KeyHandler * eventPopKeyHandler(void) +{ + return (struct KeyHandler*)popHandler(&KeyHandlers); +} + +void eventPushTickHandler(struct TickHandler *keyh) +{ + pushHandler(&TickHandlers, keyh); +} + +void eventPopTickHandler(void) +{ + popHandler(&TickHandlers); +} + +void eventPushQuitHandler(struct QuitHandler *keyh) +{ + pushHandler(&QuitHandlers, keyh); +} + +void eventPopQuitHandler(void) +{ + popHandler(&QuitHandlers); +} + +void eventPushMouseButtonHandler(struct MouseButtonHandler *keyh) +{ + pushHandler(&MouseButtonHandlers, keyh); +} + +void eventPopMouseButtonHandler(void) +{ + popHandler(&MouseButtonHandlers); +} + +void eventPushMouseMotionHandler(struct MouseMotionHandler *keyh) +{ + pushHandler(&MouseMotionHandlers, keyh); +} + +void eventPopMouseMotionHandler(void) +{ + popHandler(&MouseMotionHandlers); +} + +void eventAddHook(void (*fx) (void)) +{ + eventHook = fx; +} + +void eventRunKeyHandler(key_handler_fx_t fx, void *data) +{ + struct KeyHandler kh; + kh.fx = fx; + kh.data = data; + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); +} diff --git a/src/event.h b/src/event.h new file mode 100644 index 0000000..709ec04 --- /dev/null +++ b/src/event.h @@ -0,0 +1,129 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef event_h +#define event_h + +#include "macros.h" + +BEGIN_DECL + +#include "list.h" +#include + +/* Map directions to the numeric keypad */ +#define KEY_NORTHWEST SDLK_KP7 +#define KEY_NORTH SDLK_KP8 +#define KEY_NORTHEAST SDLK_KP9 +#define KEY_WEST SDLK_KP4 +#define KEY_HERE SDLK_KP5 +#define KEY_EAST SDLK_KP6 +#define KEY_SOUTHWEST SDLK_KP1 +#define KEY_SOUTH SDLK_KP2 +#define KEY_SOUTHEAST SDLK_KP3 +#define KEY_UP KEY_NORTH +#define KEY_DOWN KEY_SOUTH +#define KEY_RIGHT KEY_EAST +#define KEY_LEFT KEY_WEST + +#define KEY_SHIFT (1 << 9) /* 512, SDLK_LAST is 323 */ + +#define KEY_SHIFT_NORTH (KEY_NORTH|KEY_SHIFT) +#define KEY_SHIFT_SOUTH (KEY_SOUTH|KEY_SHIFT) +#define KEY_SHIFT_EAST (KEY_EAST|KEY_SHIFT) +#define KEY_SHIFT_WEST (KEY_WEST|KEY_SHIFT) + +#define KEY_SHIFT_NORTHEAST (KEY_NORTHEAST|KEY_SHIFT) +#define KEY_SHIFT_NORTHWEST (KEY_NORTHWEST|KEY_SHIFT) +#define KEY_SHIFT_SOUTHEAST (KEY_SOUTHEAST|KEY_SHIFT) +#define KEY_SHIFT_SOUTHWEST (KEY_SOUTHWEST|KEY_SHIFT) + +/* + * Give canonical names to the UNICODE versions of the CTRL keypresses + * that we care about. + * CTRL-A is 0x01 and CTRL-Z is 0x1A, others are in-between of course. + */ +#define KEY_CTRL_D 0x04 +#define KEY_CTRL_E 0x05 +#define KEY_CTRL_O 0x0F +#define KEY_CTRL_Q 0x11 +#define KEY_CTRL_R 0x12 +#define KEY_CTRL_S 0x13 +#define KEY_CTRL_T 0x14 +#define KEY_CTRL_Z 0x1A + +typedef int (*key_handler_fx_t)(struct KeyHandler * handler, int key, int keymod); + +struct TickHandler { + struct list list; + bool(*fx) (struct TickHandler * handler); + void *data; +}; + + +struct KeyHandler { + struct list list; + key_handler_fx_t fx; + void *data; + // The data field should always be filled with a struct, + // rather than a scalar such as bool or int, + // to facilitate expansions to two or more subfields + // For example, the 'struct cursor_movement_keyhandler' above. +}; + +struct QuitHandler { + struct list list; + bool(*fx) (struct QuitHandler * handler); + void *data; +}; + +struct MouseMotionHandler { + struct list list; + bool(*fx) (struct MouseMotionHandler * handler, SDL_MouseMotionEvent *event); + void *data; +}; + +struct MouseButtonHandler { + struct list list; + bool(*fx) (struct MouseButtonHandler * handler, SDL_MouseButtonEvent *event); + void *data; +}; + +extern int eventInit(void); +extern void eventExit(void); +extern void eventHandle(void); +extern void eventHandlePending(void); /* non-blocking version of eventHandle */ +extern void eventPushKeyHandler(struct KeyHandler *keyh); +extern struct KeyHandler * eventPopKeyHandler(void); +extern void eventPushTickHandler(struct TickHandler *keyh); +extern void eventPopTickHandler(void); +extern void eventPushQuitHandler(struct QuitHandler *keyh); +extern void eventPopQuitHandler(void); +extern void eventPushMouseButtonHandler(struct MouseButtonHandler *keyh); +extern void eventPopMouseButtonHandler(void); +extern void eventPushMouseMotionHandler(struct MouseMotionHandler *keyh); +extern void eventPopMouseMotionHandler(void); +extern void eventAddHook(void (*fx) (void)); +extern void eventRunKeyHandler(key_handler_fx_t fx, void *data); + +END_DECL + +#endif diff --git a/src/factions.h b/src/factions.h new file mode 100644 index 0000000..67659f0 --- /dev/null +++ b/src/factions.h @@ -0,0 +1,96 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#ifndef factions_h +#define factions_h + +#include "session.h" +#include "dtable.h" +#include "Being.h" + +#define INVALID_HANDLE -1 +#define INVALID_FACTION -1 +#define NIL_FACTION 0 +#define PLAYER_PARTY_FACTION 1 + +static inline int are_hostile(Being *a, Being *b) +{ + return dtable_are_hostile(session_dtable(), + a->getCurrentFaction(), + b->getCurrentFaction()); +} + +static inline int are_natively_hostile(Being *a, Being *b) +{ + return dtable_are_hostile(session_dtable(), + a->getBaseFaction(), + b->getBaseFaction()); +} + +static inline int are_allies(Being *a, Being *b) +{ + return dtable_are_allies(session_dtable(), + a->getCurrentFaction(), + b->getCurrentFaction()); +} + +static inline void make_hostile(Being *a, Being *b) +{ + dtable_set(session_dtable(), + a->getCurrentFaction(), + b->getCurrentFaction(), + dtable_hostile(session_dtable())); +} + +static inline void make_allies(Being *a, Being *b) +{ + dtable_set(session_dtable(), + a->getCurrentFaction(), + b->getCurrentFaction(), + dtable_allies(session_dtable())); +} + +static inline void improve_relations(Being *a, Being *b) +{ + dtable_inc(session_dtable(), + a->getCurrentFaction(), + b->getCurrentFaction()); +} + +static inline void harm_relations(Being *a, Being *b) +{ + if (a->getCurrentFaction() != b->getCurrentFaction()) + { + dtable_dec(session_dtable(), + a->getCurrentFaction(), + b->getCurrentFaction()); + } +} + +static inline const char * diplomacy_string(Being *a, Being *b) +{ + return dtable_describe(session_dtable(), + a->getCurrentFaction(), + b->getCurrentFaction()); +} + +#endif diff --git a/src/file.c b/src/file.c new file mode 100644 index 0000000..8aabef7 --- /dev/null +++ b/src/file.c @@ -0,0 +1,202 @@ +/* $Id: file.c,v 1.4 2010/08/26 05:56:20 gmcnutt Exp $ + * + * Copyright (C) 2006 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + */ + +#include "file.h" + +#include "cfg.h" +#include "kern.h" +#include "scheme.h" + +#include +#include +#include +#include +#include +#include +#include + +static const char *file_errstr = "Success"; + +char *file_mkpath(const char *dir, const char *fname) +{ + char *ret; + size_t dl,fl; + + if (! dir) + return strdup(fname); + dl = strlen(dir); + fl = strlen(fname); + + ret = (char*)malloc(dl+fl+2); + if (! ret) { + file_errstr = "Allocation failed"; + return ret; + } + memcpy(ret,dir,dl); + ret[dl] = '/'; + memcpy(ret+dl+1,fname,fl); + ret[dl+1+fl] = '\0'; + + return ret; +} + +int file_exists(const char *fname) +{ + FILE *file = fopen(fname, "r"); + if (file) { + fclose(file); + return 1; + } + return 0; +} + +int file_exists_in_dir(const char *dirname, const char *fname) +{ + int ret = -1; + char *path = file_mkpath(dirname, fname); + if (path) { + ret = file_exists(path); + free(path); + } + return ret; +} + +int file_exists_in_include_dir(const char *fname) +{ + return file_exists_in_dir(cfg_get("include-dirname"), fname); +} + +int file_exists_in_save_dir(const char *fname) +{ + return file_exists_in_dir(cfg_get("saved-games-dirname"), fname); + +} + +FILE *file_open(const char *fname, const char *mode) +{ + FILE *file = NULL; + + /* Check args. */ + if (!fname) { + file_errstr = "Null filename"; + return 0; + } + + /* Open the file. */ + file = fopen(fname, mode); + if (!file) { + file_errstr = strerror(errno); + return 0; + } + + return file; +} + +FILE *file_open_in_dir(const char *dirname, const char *fname, const char *mode) +{ + FILE *file = 0; + char *path = file_mkpath(dirname, fname); + if (path) { + file = file_open(path, mode); + free(path); + } + return file; +} + +FILE *file_open_in_include_dir(const char *fname) +{ + return file_open_in_dir(cfg_get("include-dirname"), fname, "r"); +} + +FILE *file_open_in_save_dir(const char *fname, const char *mode) +{ + char *dir = cfg_get("saved-games-dirname"); + +#ifndef WIN32 + /* FIXME: cygwin build fails, saying that mkdir below has too + * many arguments. We don't use the save dir so not a + * problem */ + if (dir + && strchr(mode, 'w') + && !file_exists(dir)) { + if (mkdir(dir, 0777)) { + file_errstr = strerror(errno); + return 0; + } + } +#endif + return file_open_in_dir(dir, fname, mode); +} + +int file_load(const char *fname) +{ + scheme *sc = NULL; + FILE *file = NULL; + + /* Open the load file. */ + file = file_open(fname, "r"); + if (! file) { + return -1; + } + + /* Create a new interpreter. */ + if (! (sc = kern_init())) { + file_errstr = "Could not create interpreter"; + fclose(file); + return -1; + } + + /* Load the init file. */ + scheme_load_named_file(sc, file, fname); + + /* Cleanup interpreter. */ + scheme_deinit(sc); + free(sc); + + /* close the file */ + fclose(file); + + return 0; +} + +int file_load_from_dir(const char *dirname, const char *fname) +{ + int ret = -1; + char *path = file_mkpath(dirname, fname); + if (path) { + ret = file_load(path); + free(path); + } + return ret; +} + +int file_load_from_include_dir(const char *fname) +{ + return file_load_from_dir(cfg_get("include-dirname"), fname); +} + +int file_load_from_save_dir(const char *fname) +{ + return file_load_from_dir(cfg_get("saved-games-dirname"), fname); +} + +const char *file_get_error() +{ + return file_errstr; +} diff --git a/src/file.h b/src/file.h new file mode 100644 index 0000000..eae2020 --- /dev/null +++ b/src/file.h @@ -0,0 +1,64 @@ +/* $Id: file.h,v 1.3 2010/08/26 05:56:20 gmcnutt Exp $ + * + * Copyright (C) 2006 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef file_h +#define file_h + +#include + +/* Declare some common file and directory utitilites. */ + +/* This concatenates a bunch of directory names followed by a file name into a + * single string and returns it. Use the stdlib free() function to delete the + * string. */ +extern char *file_mkpath(const char *dir, const char *fname); + +/* The following all test for the existence of a file. The _include_dir and + * _save_dir versions check the configured read-only include dir and read-write + * save dir, resp. */ +extern int file_exists(const char *fname); +extern int file_exists_in_dir(const char *dirname, const char *fname); +extern int file_exists_in_include_dir(const char *fname); +extern int file_exists_in_save_dir(const char *fname); + +/* The following all try to open a file in the respective directories. To close + * the file just use fclose(). The file_open_in_save_dir function will attempt + * to create the configured save dir if it doesn't exist yet, except on win32 + * platforms. */ +extern FILE *file_open(const char *fname, const char *mode); +extern FILE *file_open_in_dir(const char *dirname, const char *fname, const char *mode); +extern FILE *file_open_in_include_dir(const char *fname); +extern FILE *file_open_in_save_dir(const char *fname, const char *mode); + +/* The following all try to load a script file from the respective directories. + * These are meant for loading the various config scripts. They are not + * suitable for loading session save files, because they destroy the + * interpreter context after the scripts have executed (session.c knows this + * and loads save games "by hand" so it can keep the context). */ +extern int file_load(const char *fname); +extern int file_load_from_dir(const char *dirname, const char *fname); +extern int file_load_from_include_dir(const char *fname); +extern int file_load_from_save_dir(const char *fname); + +/* If any of the file_open_ functions return NULL then use the following to get + * an error string description of what went wrong. Obviously this is not meant + * for multi-threaded usage. */ +extern const char *file_get_error(); + +#endif diff --git a/src/floodfill.c b/src/floodfill.c new file mode 100644 index 0000000..f028ef2 --- /dev/null +++ b/src/floodfill.c @@ -0,0 +1,139 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "los.h" + +#include + +static void FLOODFILL_destroy(struct los *los) +{ +} + +static int floodfillCheckDistance(struct los *los, int mx, int my) +{ + int d; + int x; + int y; + + /* Limit LOS to the radius if given (creating a circle of visibility + * centered on the player). Otherwise limit it to the view dimensions + * (making the entire map window potentially visible). */ + if (los->r <= 0) + return (!(mx < 0 || mx >= los->w || my < 0 || my >= los->h)); + + /* Convert coordinates to a system where the origin is in the center of + * the los area */ + x = mx - los->w / 2; + y = my - los->h / 2; + + /* And force coordinates to absolute values so we can use the simple + * distance formula */ + x = (x < 0 ? -x : x); + y = (y < 0 ? -y : y); + + /* Use a quick-and-dirty distance formula (stolen from angband los + * algorithm) */ + d = ((y > x) ? (y + x / 2) : (x + y / 2)); + + return (d <= los->r); +} + +static void FLOODFILL_computeRecursive(struct los *los, int vx, int vy, + int mx, int my) +{ + int vindex; + int mindex; + int vnx; + int vny; + int mnx; + int mny; + + /* If these are not valid viewing coordinates then return. This happens + * when we hit the edges of the los area. */ + if (vx < 0 || vx >= los->w || vy < 0 || vy >= los->h) + return; + + vindex = vy * los->w + vx; + mindex = my * los->w + mx; + + /* If this tile has already been visited then return */ + if (los->vmask[vindex] != 'u') + return; + + /* If this tile is outside of the radius then return */ + if (!floodfillCheckDistance(los, mx, my)) + return; + + /* Mark this tile as visible. */ + los->vmask[vindex] = 1; + + /* If this tile is opaque and not the tile the player is standing on + * then return. */ + if (!los->alpha[mindex] && ((vx != los->w / 2) || (vy != los->h / 2))) + return; + + /* revisit -- consider skipping diagonal neighbors */ + /* revisit -- we could skip some neighbors if we knew which direction + * our parent was. We could also precheck neighbors before recurring, + * saving us some function call overhead */ + /* For each of the eight neighboring tiles, call the recursive + * floodfill function */ + for (vny = vy - 1, mny = my - 1; vny <= vy + 1; vny++, mny++) { + for (vnx = vx - 1, mnx = mx - 1; vnx <= vx + 1; vnx++, mnx++) { + FLOODFILL_computeRecursive(los, vnx, vny, mnx, mny); + } + } + +} + +static void FLOODFILL_compute(struct los *los) +{ + int i; + int len; + + len = los->w * los->h * sizeof(unsigned char); + + /* Fill the mask with the 'unvisited' flag */ + memset(los->vmask, 'u', len); + + /* Start the recursion with the center tile */ + FLOODFILL_computeRecursive(los, los->w / 2, los->h / 2, + los->w / 2, los->h / 2); + + /* Replace all 'unvisited' and 'visited' flags with 'nonvisible' */ + for (i = 0; i < len; i++) { + switch (los->vmask[i]) { + case 0: + case 1: + break; + default: + los->vmask[i] = 0; + } + } + +} + +struct los *FLOODFILL_Init(struct los *los) +{ + los->destroy = FLOODFILL_destroy; + los->compute = FLOODFILL_compute; + return 0; +} diff --git a/src/foogod.c b/src/foogod.c new file mode 100644 index 0000000..05afb12 --- /dev/null +++ b/src/foogod.c @@ -0,0 +1,383 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "foogod.h" +#include "status.h" // for status_get_h() +#include "stdarg.h" +#include "screen.h" +#include "common.h" +#include "player.h" +#include "wq.h" +#include "combat.h" +#include "session.h" +#include "vehicle.h" +#include "sprite.h" +#include "images.h" +#include "effect.h" +#include "cfg.h" + +#include + +#define FOOGOD_CHARS_PER_LINE STAT_CHARS_PER_LINE +#define FOOGOD_MAX_TITLE_LEN (FOOGOD_CHARS_PER_LINE-2) + +struct foogod { + SDL_Rect screenRect; + SDL_Rect turnRect; + SDL_Rect foodRect; + SDL_Rect combatRect; + SDL_Rect goldRect; + SDL_Rect hullRect; + SDL_Rect effectsRect; + SDL_Rect titleRect; + foogod_mode_t mode; + int hintLen; + char *hintText; + unsigned int progress_bar_max_steps; + unsigned int progress_bar_steps; + char *progress_bar_title; + struct images *image; + struct sprite *progress_bar_sprites[3]; + char title[FOOGOD_MAX_TITLE_LEN+1]; +} Foogod; + +static void foogod_repaint_title(void) +{ + screenErase(&Foogod.titleRect); + screenPrint(&Foogod.titleRect, SP_CENTERED | SP_ONBORDER, "%s", Foogod.title); + screenUpdate(&Foogod.titleRect); +} + +static int foogod_load_progress_bar_sprites(void) +{ + int i; + char *fname = cfg_get("progress-bar-image-filename"); + + if (!fname) { + return -1; + } + + Foogod.image = (struct images *)calloc(1, sizeof(*Foogod.image)); + assert(Foogod.image); + + Foogod.image = images_new(0, 8, 16, 1, 3, 0, 0, fname); + if (!Foogod.image) { + err("images_new() failed for file '%s': '%s'\n", fname, SDL_GetError() ); + goto fail; + } + + for (i = 0; i < 3; i++) { + if (!(Foogod.progress_bar_sprites[i] = sprite_new(0, 1, i, 0, 0, Foogod.image))) { + err("sprite_new() failed\n"); + goto fail; + } + } + + return 0; + + fail: + for (i = 0; i < 3; i++) { + if ((Foogod.progress_bar_sprites[i])) { + sprite_del(Foogod.progress_bar_sprites[i]); + Foogod.progress_bar_sprites[i] = 0; + } + } + + if (Foogod.image) { + free(Foogod.image); + Foogod.image = 0; + } + + return -1; +} + +void foogodAdvanceTurns(void) +{ + foogodRepaint(); +} + +int foogodInit(void) +{ + memset(&Foogod, 0, sizeof(Foogod)); + + Foogod.mode = FOOGOD_DEFAULT; + + // hint text buffer + Foogod.hintLen = FOOGOD_W / ASCII_W; + Foogod.hintText = (char*)malloc(Foogod.hintLen+1); + memset(Foogod.hintText, 0, Foogod.hintLen); + + Foogod.screenRect.x = FOOGOD_X; + Foogod.screenRect.w = FOOGOD_W; + foogod_set_y(STAT_Y + status_get_h() + BORDER_H); + Foogod.screenRect.h = FOOGOD_H; + + // turns + Foogod.turnRect.x = FOOGOD_X; + Foogod.turnRect.y = foogod_get_y(); + Foogod.turnRect.w = FOOGOD_W / 3; + Foogod.turnRect.h = ASCII_H; + + // food + Foogod.foodRect.x = FOOGOD_X; + Foogod.foodRect.y = foogod_get_y() + ASCII_H; + Foogod.foodRect.w = FOOGOD_W / 3; + Foogod.foodRect.h = ASCII_H; + + // hull + Foogod.hullRect.x = FOOGOD_X + FOOGOD_W / 3; + Foogod.hullRect.y = foogod_get_y(); + Foogod.hullRect.w = FOOGOD_W / 3; + Foogod.hullRect.h = ASCII_H; + + // effects + Foogod.effectsRect.x = FOOGOD_X + FOOGOD_W / 3; + Foogod.effectsRect.y = foogod_get_y() + ASCII_H; + Foogod.effectsRect.w = FOOGOD_W / 3; + Foogod.effectsRect.h = ASCII_H; + + // gold + Foogod.goldRect.w = FOOGOD_W / 3; + Foogod.goldRect.x = FOOGOD_X + FOOGOD_W - FOOGOD_W / 3; + Foogod.goldRect.y = foogod_get_y(); + Foogod.goldRect.h = ASCII_H; + + // mode + Foogod.combatRect.w = FOOGOD_W / 3; + Foogod.combatRect.x = FOOGOD_X + FOOGOD_W - FOOGOD_W / 3; + Foogod.combatRect.y = foogod_get_y() + ASCII_H; + Foogod.combatRect.h = ASCII_H; + + // title (on the border) + Foogod.titleRect.x = FOOGOD_X; + Foogod.titleRect.y = foogod_get_y() - BORDER_H; + Foogod.titleRect.w = FOOGOD_W; + Foogod.titleRect.h = BORDER_H; + + return foogod_load_progress_bar_sprites(); +} + +static void foogodPaintEffect(SDL_Rect *rect, struct sprite *sprite) +{ + sprite_paint(sprite, 0, rect->x, rect->y); + rect->x += ASCII_W; +} + +static int foogod_paint_effect_wrapper(struct hook_entry *entry, void *data) +{ + SDL_Rect *rect = (SDL_Rect*)data; + struct effect *effect = entry->effect; + if (effect->sprite) { + foogodPaintEffect(rect, effect->sprite); + } + return 0; +} + +static void foogodPaintEffects() +{ + SDL_Rect rect = Foogod.effectsRect; + + /* Effects well-known to the engine */ + if (TimeStop) { + foogodPaintEffect(&rect, time_stop_effect_sprite()); + } + + if (Reveal) { + foogodPaintEffect(&rect, reveal_effect_sprite()); + } + + if (Quicken) { + foogodPaintEffect(&rect, quicken_effect_sprite()); + } + + if (MagicNegated) { + foogodPaintEffect(&rect, magic_negated_effect_sprite()); + } + + if (XrayVision) { + foogodPaintEffect(&rect, xray_vision_effect_sprite()); + } + + /* Custom effects added by the game */ + for (int i = 0; i < OBJ_NUM_HOOKS; i++) { + player_party->hookForEach(i, foogod_paint_effect_wrapper, 0); + } + + +} + +static void foogodPaintSessionInfo() +{ + screenPrint(&Foogod.turnRect, 0, "Turn: %d", session_get_turn_count()); + foogodPaintEffects(); + + if (player_party) { + screenPrint(&Foogod.foodRect, 0, "Food: %d", + player_party->food); + screenPrint(&Foogod.goldRect, SP_RIGHTJUSTIFIED, "Gold: %d", + player_party->gold); + if (player_party->getVehicle()) { + screenPrint(&Foogod.hullRect, 0, "Hull: %d", + player_party->getVehicle()->getHp()); + } + } +} + +static void foogod_progress_bar_paint() +{ + int i; + int ticks; + int max_ticks; + SDL_Rect rect = Foogod.screenRect; + + /* title */ + rect.h = ASCII_H; + screenPrint(&rect, SP_CENTERED, Foogod.progress_bar_title); + + /* bar */ + rect.y += ASCII_H; + rect.w = ASCII_W; + + /* (ticks : maxTicks) = (steps : totalSteps) */ + max_ticks = (Foogod.screenRect.w / ASCII_W); + + /* Subtract two for the edges pieces of the progress bar. */ + max_ticks -= 2; + + ticks = (Foogod.progress_bar_steps * max_ticks) + / Foogod.progress_bar_max_steps; + + /* Paint the left edge. */ + sprite_paint(Foogod.progress_bar_sprites[0], 0, rect.x, rect.y); + rect.x += ASCII_W; + + /* Paint the center. */ + for (i = 0; i < ticks; i++) { + sprite_paint(Foogod.progress_bar_sprites[1], 0, rect.x, rect.y); + //screenPrint(&rect, 0, "."); + rect.x += ASCII_W; + } + + /* Paint the right edge. */ + sprite_paint(Foogod.progress_bar_sprites[2], 0, rect.x, rect.y); +} + +void foogodRepaint(void) +{ + screenErase(&Foogod.screenRect); + + switch (Foogod.mode) { + + default: + case FOOGOD_DEFAULT: + if (Session) { + foogodPaintSessionInfo(); + } + screenPrint(&Foogod.combatRect, SP_RIGHTJUSTIFIED, + "Combat: %c", combatGetState()); + break; + + case FOOGOD_HINT: + screenPrint(&Foogod.screenRect, 0, Foogod.hintText); + break; + + case FOOGOD_PROGRESS_BAR: + foogod_progress_bar_paint(); + break; + } + + foogod_repaint_title(); + screenUpdate(&Foogod.screenRect); +} + +void foogod_set_y(int y) +{ + Foogod.screenRect.y = y; + Foogod.turnRect.y = y; + Foogod.foodRect.y = y + ASCII_H; + Foogod.goldRect.y = y; + Foogod.combatRect.y = y + ASCII_H; + Foogod.hullRect.y = y; + Foogod.effectsRect.y = y + ASCII_H; + Foogod.titleRect.y = y - BORDER_H; +} + +int foogod_get_y(void) +{ + return Foogod.screenRect.y; +} + +int foogod_get_h(void) +{ + return (FOOGOD_H + BORDER_H); +} + +void foogodSetMode(foogod_mode_t mode) +{ + Foogod.mode = mode; + foogodRepaint(); +} + +void foogodSetHintText(const char *text) +{ + strncpy(Foogod.hintText, text, Foogod.hintLen); +} + +void foogod_progress_bar_set_title(const char *title) +{ + if (Foogod.progress_bar_title) { + free(Foogod.progress_bar_title); + Foogod.progress_bar_title = 0; + } + + if (title) { + Foogod.progress_bar_title = strdup(title); + } +} + +void foogod_progress_bar_set_max_steps(unsigned int val) +{ + Foogod.progress_bar_max_steps = val; + Foogod.progress_bar_steps = 0; +} + +void foogod_progress_bar_advance(unsigned int steps) +{ + Foogod.progress_bar_steps += steps; + if (Foogod.progress_bar_steps > Foogod.progress_bar_max_steps) { + Foogod.progress_bar_steps = Foogod.progress_bar_max_steps; + } +} + +void foogod_progress_bar_finish() +{ + dbg("Foogod.progress_bar_steps=%d\n", Foogod.progress_bar_steps); + Foogod.progress_bar_steps = Foogod.progress_bar_max_steps; +} + +void foogod_set_title(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vsnprintf(Foogod.title, FOOGOD_MAX_TITLE_LEN, fmt, args); + va_end(args); +} + diff --git a/src/foogod.h b/src/foogod.h new file mode 100644 index 0000000..e62c9b0 --- /dev/null +++ b/src/foogod.h @@ -0,0 +1,63 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef foogod_h +#define foogod_h + +#include "macros.h" + +BEGIN_DECL + +/* Food-Gold-Date window */ +typedef enum { + FOOGOD_DEFAULT = 0 + , FOOGOD_HINT + , FOOGOD_PROGRESS_BAR +} foogod_mode_t; + +typedef enum { + FOOGOD_QUICKEN = 0, + FOOGOD_REVEAL, + FOOGOD_MAGIC_NEGATED, + FOOGOD_TIME_STOP, + FOOGOD_XRAY_VISION, + FOOGOD_NUM_EFFECTS +} foogod_effect_t; + +extern int foogodInit(void); +extern void foogodRepaint(void); +extern void foogodAdvanceTurns(); +extern void foogod_set_y(int y); +extern int foogod_get_y(void); +extern int foogod_get_h(void); + +extern void foogodSetMode(foogod_mode_t mode); +extern void foogodSetHintText(const char *text); + +extern void foogod_progress_bar_set_title(const char *title); +extern void foogod_progress_bar_set_max_steps(unsigned int val); +extern void foogod_progress_bar_advance(unsigned int steps); +extern void foogod_progress_bar_finish(void); +extern void foogod_set_title(const char *fmt, ...); + +END_DECL + +#endif diff --git a/src/formation.c b/src/formation.c new file mode 100644 index 0000000..5ed0b69 --- /dev/null +++ b/src/formation.c @@ -0,0 +1,69 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "formation.h" +#include "common.h" + +static struct formation_entry default_formation_entries[] = { + {0, 0}, + {1, 1}, + {-1, 1}, + {2, 2}, + {0, 2}, + {-2, 2}, + {3, 3}, + {1, 3}, + {-1, 3}, + {-3, 3}, + {4, 4}, + {2, 4}, + {0, 4}, + {-2, 4}, + {-4, 4}, + {5, 5}, + {3, 5}, + {1, 5}, + {-1, 5}, + {-3, 5}, + {-5, 5}, + {6, 6}, + {4, 6}, + {2, 6}, + {0, 6}, + {-2, 6}, + {-4, 6}, + {-6, 6}, /* 28 */ +}; + +static struct formation default_formation; + +int formation_init(void) +{ + default_formation.n = array_sz(default_formation_entries); + default_formation.entry = default_formation_entries; + return 0; +} + +struct formation *formation_get_default(void) +{ + return &default_formation; +} diff --git a/src/formation.h b/src/formation.h new file mode 100644 index 0000000..44203e9 --- /dev/null +++ b/src/formation.h @@ -0,0 +1,42 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef formation_h +#define formation_h + +#include "list.h" + +struct formation_entry { + int x; + int y; +}; + +struct formation { + struct list list; + char *tag; + int n; + struct formation_entry *entry; +}; + +extern int formation_init(void); +extern struct formation *formation_get_default(void); + +#endif diff --git a/src/gob.c b/src/gob.c new file mode 100644 index 0000000..5b04e63 --- /dev/null +++ b/src/gob.c @@ -0,0 +1,47 @@ +#include "gob.h" +#include "session.h" + +#include +#include + +#define scm_car(sc, arg) ((sc)->vptr->pair_car(arg)) +#define scm_cdr(sc, arg) ((sc)->vptr->pair_cdr(arg)) + +/* Fixme: gob_new should start with refcount 1 */ +struct gob *gob_new(scheme *sc, pointer p) +{ + struct gob *gob = (struct gob *)calloc(1, sizeof(*gob)); + assert(gob); + gob->sc = sc; + gob->p = p; + sc->vptr->protect(sc, p); + return gob; +} + +/* Fixme: this should not be public; clients should be required to use gob_unref */ +void gob_del(struct gob *gob) +{ + gob->sc->vptr->unprotect(gob->sc, gob->p); + free(gob); +} + +void gob_save(struct gob *gob, struct save *save) +{ + pointer cell; + + /* The car of the gob pointer is often non-data (kobj, etc). So only + * serialize the car of the cdr unless the creator specifically wants + * to. */ + cell = (gob->flags & GOB_SAVECAR) ? gob->p : + scm_car(gob->sc, scm_cdr(gob->sc, gob->p)); + + scheme_serialize(gob->sc, cell, save); +} + +void gob_unref(struct gob *gob) +{ + assert(gob->refcount > 0); + gob->refcount--; + if (! gob->refcount) + gob_del(gob); +} diff --git a/src/gob.h b/src/gob.h new file mode 100644 index 0000000..473123e --- /dev/null +++ b/src/gob.h @@ -0,0 +1,22 @@ +#ifndef gob_h +#define gob_h + +#include "scheme-private.h" + +#define GOB_SAVECAR (1 << 0) + +struct gob { + scheme *sc; + pointer p; + int flags; + int refcount; +}; + +#define gob_ref(gob) ((gob)->refcount++) + +extern struct gob *gob_new(scheme *sc, pointer p); +extern void gob_del(struct gob *gob); +extern void gob_save(struct gob *gob, struct save *save); +extern void gob_unref(struct gob *gob); + +#endif diff --git a/src/hash.c b/src/hash.c new file mode 100644 index 0000000..0f0b523 --- /dev/null +++ b/src/hash.c @@ -0,0 +1,61 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "hash.h" +#include "olist.h" +#include "common.h" + +struct hash *hash_create(int n) +{ + struct hash *hash; + int i; + + CREATE(hash, struct hash, 0); + hash->n = n; + hash->buckets = (struct olist *) malloc(n * sizeof(struct olist)); + if (!hash->buckets) { + hash_destroy(hash); + return 0; + } + for (i = 0; i < n; i++) { + list_init(&hash->buckets[i].list); + } + return hash; +} + +void hash_destroy(struct hash *hash) +{ + if (hash->buckets) + free(hash->buckets); + free(hash); +} + +void hash_add(struct hash *hash, struct olist *val) +{ + struct olist *b = &hash->buckets[val->key % hash->n]; + olist_add(b, val); +} + +struct olist *hash_lookup(struct hash *hash, int key) +{ + struct olist *b = &hash->buckets[key % hash->n]; + return olist_lookup(b, key, 1); +} diff --git a/src/hash.h b/src/hash.h new file mode 100644 index 0000000..ede2838 --- /dev/null +++ b/src/hash.h @@ -0,0 +1,44 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef hash_h +#define hash_h + +#ifdef __cplusplus +extern "C" { +#endif + + struct olist; + + struct hash { + struct olist *buckets; + int n; + }; + + extern struct hash *hash_create(int n); + extern void hash_destroy(struct hash *hash); + extern void hash_add(struct hash *hash, struct olist *val); + extern struct olist *hash_lookup(struct hash *hash, int key); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/heap.c b/src/heap.c new file mode 100644 index 0000000..53c7660 --- /dev/null +++ b/src/heap.c @@ -0,0 +1,139 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "heap.h" + +#include +#include + +struct heap *heap_create(unsigned int max_entries) +{ + struct heap *heap; + + heap = (struct heap *) malloc(sizeof(struct heap)); + if (!heap) + return 0; + memset(heap, 0, sizeof(struct heap)); + + heap->max_entries = max_entries; + heap->num_entries = 0; + + heap->entries = (int **) malloc(sizeof(int *) * max_entries); + if (!heap->entries) { + free(heap); + return 0; + } + memset(heap->entries, 0, sizeof(void *) * max_entries); + + return heap; +} + +void heap_destroy(struct heap *heap) +{ + if (heap->entries) + free(heap->entries); + free(heap); +} + +void heapify(struct heap *heap, int i) +{ + unsigned int left; + unsigned int right; + int largest; + + left = 2 * i; + right = left + 1; + + if (left < heap->num_entries && + *heap->entries[left] > *heap->entries[i]) + largest = left; + else + largest = i; + + if (right < heap->num_entries && + *heap->entries[right] > *heap->entries[largest]) + largest = right; + + if (largest != i) { + int *tmp = heap->entries[i]; + heap->entries[i] = heap->entries[largest]; + heap->entries[largest] = tmp; + heapify(heap, largest); + } +} + +int heap_expand(struct heap *heap) +{ + int **tmp; + tmp = + (int **) realloc(heap->entries, + heap->max_entries * 2 * sizeof(int *)); + if (!tmp) + return -1; + heap->entries = tmp; + heap->max_entries *= 2; + return 0; +} + +int heap_insert(struct heap *heap, int *entry) +{ + int i; + + /* Expand the heap if necessary */ + if (heap->num_entries == heap->max_entries) { + if (heap_expand(heap) < 0) + return -1; + } + + /* Put the new entry at the bottom of the heap */ + i = heap->num_entries++; + + /* Percolate the new entry up to where it belongs */ + while (i > 0 && *heap->entries[i / 2] < *entry) { + heap->entries[i] = heap->entries[i / 2]; + i /= 2; + } + + heap->entries[i] = entry; + + return 0; +} + +int *heap_extract(struct heap *heap) +{ + int *max; + + if (!heap->num_entries) + return 0; + + max = heap->entries[0]; + heap->entries[0] = heap->entries[heap->num_entries - 1]; + heap->num_entries--; + heapify(heap, 0); + + return max; +} + +void heap_clean(struct heap *heap) +{ + memset(heap->entries, 0, heap->num_entries * sizeof(heap->entries[0])); + heap->num_entries = 0; +} diff --git a/src/heap.h b/src/heap.h new file mode 100644 index 0000000..a68b99f --- /dev/null +++ b/src/heap.h @@ -0,0 +1,50 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef heap_h +#define heap_h + +#include "macros.h" + +BEGIN_DECL + +#define heap_entry(ptr,type,field) \ + ((type*)((char*)(ptr)-(unsigned long)(&((type *)0)->field))) + +#define heap_empty(h) (!(h)->num_entries) + +struct heap { + unsigned int max_entries; + unsigned int num_entries; + int **entries; +}; + +extern struct heap *heap_create(unsigned int max_entries); +extern void heap_destroy(struct heap *heap); +extern void heapify(struct heap *heap, int i); +extern int heap_expand(struct heap *heap); +extern int heap_insert(struct heap *heap, int *entry); +extern int *heap_extract(struct heap *heap); +extern void heap_clean(struct heap *heap); + +END_DECL + +#endif diff --git a/src/images.c b/src/images.c new file mode 100644 index 0000000..580c5e5 --- /dev/null +++ b/src/images.c @@ -0,0 +1,230 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "images.h" +#include "screen.h" +#include "file.h" +#include "cfg.h" +#include "debug.h" +#include "screen.h" // for screenFormat() + +#include +#include +#include +#include + +void images_dump_surface(char *name, SDL_Surface *surf) +{ + printf("DUMP SURFACE ============================\n"); + printf("%s info:\n", name); + printf(" w, h: %d %d\n", surf->w, surf->h); + printf(" pitch: %d\n", surf->pitch); + printf("clip_rect: [%d %d %d %d]\n", surf->clip_rect.x, + surf->clip_rect.y, surf->clip_rect.w, surf->clip_rect.h); + printf(" format:\n"); + printf(" palette: %s\n", + surf->format->palette ? "yes" : "no"); + printf(" BitsPerPixel: %d\n", + surf->format->BitsPerPixel); + printf("BytesPerPixel: %d\n", + surf->format->BytesPerPixel); + printf(" R/G/B/Amask: 0x%x 0x%x 0x%x 0x%x\n", + surf->format->Rmask, surf->format->Gmask, surf->format->Bmask, + surf->format->Amask); + printf(" R/G/B/Ashift: %d %d %d %d\n", + surf->format->Rshift, surf->format->Gshift, + surf->format->Bshift, surf->format->Ashift); + printf(" R/G/B/Aloss: %d %d %d %d\n", + surf->format->Rloss, surf->format->Gloss, + surf->format->Bloss, surf->format->Aloss); + printf(" colorkey: 0x%x\n", surf->format->colorkey); + printf(" alpha: 0x%x\n", surf->format->alpha); + printf(" flags:\n"); + if (surf->flags & SDL_SWSURFACE) + printf(" SDL_SWSURFACE\n"); + if (surf->flags & SDL_HWSURFACE) + printf(" SDL_HWSURFACE\n"); + if (surf->flags & SDL_ASYNCBLIT) + printf(" SDL_ASYNCBLIT\n"); + if (surf->flags & SDL_ANYFORMAT) + printf(" SDL_ANYFORMAT\n"); + if (surf->flags & SDL_HWPALETTE) + printf(" SDL_HWPALETTE\n"); + if (surf->flags & SDL_DOUBLEBUF) + printf(" SDL_DOUBLEBUF\n"); + if (surf->flags & SDL_FULLSCREEN) + printf(" SDL_FULLSCREEN\n"); + if (surf->flags & SDL_OPENGL) + printf(" SDL_OPENGL\n"); + if (surf->flags & SDL_OPENGLBLIT) + printf(" SDL_OPENGLBLIT\n"); + if (surf->flags & SDL_RESIZABLE) + printf(" SDL_RESIZABLE\n"); + if (surf->flags & SDL_HWACCEL) + printf(" SDL_HWACCEL\n"); + if (surf->flags & SDL_SRCCOLORKEY) + printf(" SDL_SRCCOLORKEY\n"); + if (surf->flags & SDL_RLEACCEL) + printf(" SDL_RLEACCEL\n"); + if (surf->flags & SDL_SRCALPHA) + printf(" SDL_SRCALPHA\n"); + if (surf->flags & SDL_PREALLOC) + printf(" SDL_PREALLOC\n"); + +} + +void images_del(struct images *images) +{ + if (images->tag) + free(images->tag); + if (images->fname) + free(images->fname); + if (images->images) + SDL_FreeSurface(images->images); + if (images->faded) + SDL_FreeSurface(images->faded); + delete images; +} + + +int images_fade(struct images *images) +{ + + if (images->faded) + return 0; + + images->faded = screenCreateSurface(images->images->w, + images->images->h); + if (images->faded == NULL) + return -1; + + memcpy(images->faded->pixels, images->images->pixels, + images->faded->pitch * images->faded->h); + + screen_fade_surface(images->faded, 1); + return 0; +} + +int images_convert2display(struct images *images) +{ + SDL_Surface *tmp; + int imagesbits, screenbits; + imagesbits = images->images->format->BitsPerPixel; + screenbits = screenFormat()->BitsPerPixel; + + /* Convert to video format for faster blitting + * (*much* faster on certain display bit depths). + * 8-bit surfaces are a special case in Nazghul though. + */ + if (imagesbits != screenbits && imagesbits != 8) { + + if ((tmp = SDL_DisplayFormat(images->images)) == NULL) { + err("SDL_DisplayFormat: %s", SDL_GetError()); + return 0; + } + imagesbits = screenbits; + SDL_FreeSurface(images->images); + images->images = tmp; + } + + /* Images which are saved with a transparency layer will have the + * SDL_SRCALPHA flag set. Their alpha layer will be managed + * automatically by SDL_BlitSurface(). For images without an alpha + * layer, assume that magenta (RGB 0xff00ff) is the special color for + * transparency. To correctly support transparent blitting we have to + * set their color key to magenta and we have to convert them to match + * the display format. */ + if (! (images->images->flags & SDL_SRCALPHA)) { + + if (imagesbits != screenbits) { + /* Convert to video format for faster blitting */ + if ((tmp = SDL_DisplayFormat(images->images)) == NULL) { + err("SDL_DisplayFormat: %s", SDL_GetError()); + return 0; + } + SDL_FreeSurface(images->images); + images->images = tmp; + } + + /* Make magenta the transparent color */ + if (SDL_SetColorKey(images->images, SDL_SRCCOLORKEY, + SDL_MapRGB(images->images->format, + 0xff, 0x00, 0xff)) < 0) { + err("SDL_SetColorKey: %s", SDL_GetError()); + return 0; + } + } + return 1; +} + +struct images *images_new(const char *tag, int w, int h, int rows, int cols, + int offx, int offy, const char *fname) +{ + struct images *images; + char *filename; + + images = new struct images; + assert(images); + memset(images, 0, sizeof(*images)); + + if (tag) { + images->tag = strdup(tag); + assert(images->tag); + } + + images->fname = strdup(fname); + assert(images->fname); + + images->w = w; + images->h = h; + images->offx = offx; + images->offy = offy; + images->rows = rows; + images->cols = cols; + + filename = file_mkpath(cfg_get("include-dirname"),fname); + if (filename) { + images->images = IMG_Load(filename); + free(filename); + } + if (!images->images) { + // BUG: Mac OS X fails to load PNG images here, but GIF works + // OK. This could be a libPNG, libSDL, or libSDL_Image bug. In + // the meantime, better error logging is helpful. + err("IMG_Load() failed to load file '%s' because '%s'.\n", + fname, SDL_GetError() ); + assert(false); + // err("IMG_Load: %s", SDL_GetError()); The err() macro acted + // strangely, emitting different error text than the above + // would indicate. Perhaps that is a clue to the bug? + // + // Perhaps the err() macro, or the call above, + // differ from the nazghul-0.2.0 release and recent CVS? + } + + if (images_convert2display(images)) { + //images_dump_surface(fname, images->images); + return images; + } + images_del(images); + return NULL; +} + diff --git a/src/images.h b/src/images.h new file mode 100644 index 0000000..0075eb3 --- /dev/null +++ b/src/images.h @@ -0,0 +1,55 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef images_h +#define images_h + +#include "macros.h" + +BEGIN_DECL + +#include "list.h" + +#include + +struct images { + char *tag; + char *fname; + int w; /* in pixels of the images */ + int h; /* in pixels of the images */ + int rows; /* in the image file */ + int cols; /* in the image file */ + int offx; /* pixels separating images */ + int offy; /* pixels separating images */ + SDL_Surface *images; + SDL_Surface *faded; /* faded copy of image set for + * sem-transparent sprites */ +}; + +extern struct images *images_new(const char *tag, int w, int h, int rows, int cols, + int offx, int offy, const char *fname); +extern int images_convert2display(struct images *images); +extern void images_del(struct images *images); +extern int images_fade(struct images *images); + +END_DECL + +#endif diff --git a/src/kern.c b/src/kern.c new file mode 100644 index 0000000..15f841a --- /dev/null +++ b/src/kern.c @@ -0,0 +1,10544 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#include "session.h" + +#include "applet.h" +#include "blender.h" +#include "character.h" +#include "cmd.h" +#include "conv.h" +#include "config.h" +#include "ctrl.h" +#include "dice.h" +#include "effect.h" +#include "event.h" +#include "gob.h" +#include "object.h" +#include "sched.h" +#include "sprite.h" +#include "terrain.h" +#include "vmask.h" +#include "wq.h" +#include "place.h" +#include "ptable.h" +#include "images.h" +#include "Party.h" +#include "common.h" +#include "player.h" +#include "sky.h" +#include "ascii.h" +#include "map.h" +#include "cursor.h" +#include "Arms.h" +#include "Field.h" +#include "occ.h" +#include "species.h" +#include "Reagent.h" +#include "screen.h" +#include "vehicle.h" +#include "formation.h" +#include "combat.h" +#include "Container.h" +#include "clock.h" +#include "wind.h" +#include "foogod.h" +#include "sound.h" +#include "Missile.h" +#include "conv.h" +#include "mmode.h" +#include "log.h" +#include "dtable.h" +#include "factions.h" +#include "cmdwin.h" +#include "cfg.h" +#include "kern_intvar.h" // SAM +#include "menus.h" +#include "file.h" +#include "skill.h" +#include "skill_set.h" +#include "skill_set_entry.h" +#include "templ.h" +#include "macros.h" +#include "ztats.h" +#include "ztats_pane.h" +#include "../config.h" /* for USE_QUESTS */ +// kern.c *doesnt* include kern.h?? wtf?? + +#include +#include // isspace() +#include +#include +#include +#include +#include +#include +#include +#include // for SDL_GetTicks() + +#include "scheme-private.h" + +#define API_DECL(sc, sym, val) \ + scm_define(sc, sym, scm_mk_ptr(sc, val)) + +#define KERN_API_CALL(name) static pointer name(scheme *sc, pointer args) +#define KERN_OBSOLETE_CALL(name) \ +static pointer name(scheme *sc, pointer args) { \ + warn("warn: '" #name "' is obsolete\n"); \ + return sc->NIL; \ +} + +#define KERN_ALLOC(type) (type *)calloc(1, sizeof(type)) +#define KERN_FREE(ptr) (free(ptr)) + +#define TAG_UNK "" + + +struct kjob { + void *data; + closure_t *clx; +}; + +/* Struct used by callbacks which build scheme lists */ +struct kern_append_info { + scheme *sc; + pointer head; + pointer tail; + int (*filter)(Object *, struct kern_append_info *); + void *data; +}; + +struct kern_ui_target_info { + struct place *place; + int x, y, range; + struct list suggest; +}; + +/* Redefine the session query macro to turn its arg into a string, then #include + * the list of querys directly into an array of string pointers. */ +#undef SESSION_DECL_QUERY +#define SESSION_DECL_QUERY(id) #id +static const char * query_to_id[] = { +# include "session_queries.h" +}; + +/***************************************************************************** + * + * kjob - wrapper for work queue jobs + * + *****************************************************************************/ +static struct kjob * kjob_new(void *data, closure_t *clx) +{ + struct kjob *kjob; + kjob = (struct kjob *)malloc(sizeof(*kjob)); + assert(kjob); + kjob->data = data; + kjob->clx = clx; + closure_ref(clx); + return kjob; +} + +static void kjob_del(struct kjob *kjob) +{ + closure_unref(kjob->clx); + free(kjob); +} + +static void kern_run_wq_job(struct wq_job *job, struct list *wq) +{ + struct kjob *kjob; + kjob = (struct kjob*)job->data; + //dbg("kjob_run: %08lx\n", kjob); + closure_exec(kjob->clx, "p", kjob->data); + kjob_del(kjob); + wq_job_del(job); +} +/*****************************************************************************/ + +static void image_dtor(void *val) +{ + images_del((struct images*)val); +} + +static void sprite_dtor(void *val) +{ + sprite_del((struct sprite*)val); +} + +static void sound_dtor(void *val) +{ + sound_del((sound_t*)val); +} + +static void terrain_palette_dtor(void *val) +{ + terrain_palette_del((struct terrain_palette*)val); +} + +static void terrain_map_dtor(void *val) +{ + terrain_map_unref((struct terrain_map*)val); +} + +static void incfile_dtor(void *val) +{ + free((char*)val); +} + +static void incfile_save(save_t *save, void *val) +{ + save->write(save, "(kern-load \"%s\")\n\n", (char*)val); +} + +static void place_dtor(void *val) +{ + place_del((struct place*)val); +} + +static void species_dtor(void *val) +{ + species_del((struct species*)val); +} + +static void occ_dtor(void *val) +{ + occ_unref((struct occ*)val); +} + +static void arms_type_dtor(void *val) +{ + delete (class ArmsType *)val; +} + +static void missile_type_dtor(void *val) +{ + delete (class MissileType *)val; +} + +static void field_type_dtor(void *val) +{ + delete (class FieldType *)val; +} + +static void obj_type_dtor(void *val) +{ + delete (class ObjectType *)val; +} + +static void vehicle_type_dtor(void *val) +{ + delete (class VehicleType*)val; +} + +static void blender_dtor(void *val) +{ + blender_t *blender=(blender_t*)val; + list_remove(&blender->list); + free(blender); +} + +static int unpack(scheme *sc, pointer *cell, const char *fmt, ...) +{ + va_list args; + int expect, count = 0, errs = 0; + pointer car; + char **strval; + int *ival; + float *rval; + void **ptrval; + pointer *cval; + + expect = strlen(fmt); + + va_start(args, fmt); + + while (*fmt && scm_is_pair(sc, *cell)) { + + count++; + car = scm_car(sc, *cell); + *cell = scm_cdr(sc, *cell); + + switch(*fmt++) { + case 'b': /* bool */ + ival = va_arg(args, int*); + if (car == sc->T) { + *ival = 1; + } else if (car == sc->F) { + *ival = 0; + } else { + errs++; + load_err("arg %d not a bool", count); + } + break; + case 'c': /* closure (actually, a symbol, possibly for a + * closure; this is misleading) */ + cval = va_arg(args, pointer*); + if (car == sc->NIL) { + *cval = sc->NIL; + } else if (! scm_is_sym(sc, car)) { + errs++; + load_err("arg %d not a symbol", count); + } else { + *cval = car; + } + break; + case 'd': /* integer */ + ival = va_arg(args, int*); + if (! scm_is_num(sc, car)) { + errs++; + load_err("arg %d not a number", count); + } else if (! scm_is_int(sc, car)) { + /*errs++; + load_err("arg %d not an int", count);*/ + /* coerce it */ + *ival = (int)scm_real_val(sc, car); + } else { + *ival = scm_int_val(sc, car); + } + break; + case 'f': /* float */ + rval = va_arg(args, float*); + if (! scm_is_num(sc, car)) { + errs++; + load_err("arg %d not a number", count); + } else if (! scm_is_real(sc, car)) { + /* coerce it */ + *rval = scm_int_val(sc, car); + } else { + *rval = scm_real_val(sc, car); + } + break; + case 'o': /* procedure */ + cval = va_arg(args, pointer*); + if (car == sc->NIL) { + *cval = sc->NIL; + } else if (! scm_is_closure(sc, car)) { + errs++; + load_err("arg %d not a closure", count); + } else { + *cval = car; + } + break; + case 'p': /* C pointer */ + ptrval = va_arg(args, void**); + if (car == sc->NIL) { + *ptrval = 0; + } else if (scm_is_ptr(sc, car)) { + *ptrval = scm_ptr_val(sc, car); + } else { + errs++; + load_err("arg %d not a C ptr", count); + } + break; + case 'r': /* real number */ + rval = va_arg(args, float*); + if (! scm_is_num(sc, car)) { + errs++; + load_err("arg %d not a number", count); + } else if (! scm_is_real(sc, car)) { + errs++; + load_err("arg %d not an int", count); + } else { + *rval = scm_real_val(sc, car); + } + break; + case 's': /* string */ + strval = va_arg(args, char**); + if (car == sc->NIL) { + *strval = 0; + } else if (scm_is_str(sc, car)) { + *strval = scm_str_val(sc, car); + } else { + errs++; + load_err("arg %d not a string", count); + } + break; + case 'y': /* symbol */ + strval = va_arg(args, char**); + if (car == sc->NIL) { + *strval = 0; + } else if (scm_is_sym(sc, car)) { + *strval = scm_sym_val(sc, car); + } else { + errs++; + load_err("arg %d not a symbol", count); + } + break; + case 'l': /* plain old cell, (eg a gob) */ + cval = va_arg(args, pointer*); + *cval = car; + break; + default: + dbg("unknown format char: %c\n", *(fmt - 1)); + assert(0); + break; + } + } + + if (*fmt) { + load_err("received only %d of %d arguments", + count, count + strlen(fmt)); + } + + va_end(args); + + return (! *fmt && ! errs) ? 0 : -1; +} + +static Object *unpack_obj(scheme *sc, pointer *args, const char *caller) +{ + class Object *obj; + + if (unpack(sc, args, "p", &obj)) { + rt_err("%s: bad args", caller); + return NULL; + } + + if (obj == NULL) { + rt_err("%s: null kernel object", caller); + return NULL; + } + + return obj; +} + +static int unpack_loc(scheme *sc, pointer *args, struct place **place, int *x, + int *y, const char *func) +{ + pointer loc; + + if (! scm_is_pair(sc, *args)) { + rt_err("%s: location not a list", func); + return -1; + } + + loc = scm_car(sc, *args); + *args = scm_cdr(sc, *args); + + if (unpack(sc, &loc, "pdd", place, x, y)) { + rt_err("%s: bad location list", func); + return -1; + } + + if (!place) { + rt_err("%s: null place", func); + return -1; + } + + return 0; +} + +static int unpack_rect(scheme *sc, pointer *args, SDL_Rect *rect) +{ + pointer prect = scm_car(sc, *args); + *args = scm_cdr(sc, *args); + long x, y, w, h; + + /* Can't use the rect fields directly because they're only Uint16 */ + if (unpack(sc, &prect, "dddd", &x, &y, &w, &h)) { + load_err("%s: error unpacking rect elements", __FUNCTION__); + return -1; + } + + rect->x = x; + rect->y = y; + rect->w = w; + rect->h = h; + + return 0; +} + +pointer vpack(scheme *sc, const char *fmt, va_list ap) +{ + pointer head=sc->NIL; + pointer tail=sc->NIL; + pointer cell=sc->NIL; + pointer arg=sc->NIL; + void *ptr; + int ival; + char *strval; + + while (*fmt) { + + switch(*fmt++) { + case 'p': + ptr = va_arg(ap, void*); + arg = scm_mk_ptr(sc, ptr); + break; + case 'd': + ival = va_arg(ap, int); + arg = scm_mk_integer(sc, ival); + break; + case 'y': + strval = va_arg(ap, char*); + arg = scm_mk_symbol(sc, strval); + break; + case 'l': + arg = va_arg(ap, pointer); + if (!arg) { + arg = sc->NIL; + } + break; + default: + assert(false); + break; + } + + /* Note: arg already protected during _cons */ + cell = _cons(sc, arg, sc->NIL, 0); + + if (head == sc->NIL) { + head = cell; + tail = cell; + + /* By protecting the head we protect the rest of the + * list */ + scm_protect(sc, head); + } else { + tail->_object._cons._cdr = cell; + tail = cell; + } + } + + /* Allocations are over so unprotect the list */ + if (head != sc->NIL) + scm_unprotect(sc, head); + + return head; +} + +struct mview * kern_unpack_mview(scheme *sc, pointer *args, const char *caller) +{ + struct mview *obj; + + if (unpack(sc, args, "p", &obj)) { + rt_err("%s: bad args", caller); + return NULL; + } + + if (obj == NULL) { + rt_err("%s: null view object"); + return NULL; + } + + return obj; +} + +static int kern_unpack_loc(scheme *sc, pointer *args, struct place **place, + int *x, int *y, const char *caller) +{ + pointer loc; + + loc = scm_car(sc, *args); + if (! scm_is_pair(sc, loc)) { + rt_err("%s: location not a list", caller); + return 0; + } + + *args = scm_cdr(sc, *args); + + if (unpack(sc, &loc, "pdd", place, x, y)) { + rt_err("%s: bad location args", caller); + return 0; + } + + if (!(*place)) { + rt_err("%s: null place", caller); + return 0; + } + + return 1; +} + +static pointer pack(scheme *sc, const char *fmt, ...) +{ + pointer head; + va_list ap; + + va_start(ap, fmt); + head = vpack(sc, fmt, ap); + va_end(ap); + + return head; +} + +static pointer kern_mk_sprite_set(scheme *sc, pointer args) +{ + int width, height, rows, cols, offx, offy; + char *fname; + struct images *image = NULL; + const char *tag = TAG_UNK; + pointer ret; + + if (unpack(sc, &args, "ydddddds", &tag, &width, &height, &rows, &cols, + &offx, &offy, &fname)) { + load_err("kern-mk-sprite-set %s: bad args", tag); + return sc->NIL; + } + + image = images_new(tag, width, height, rows, cols, offx, offy, fname); + session_add(Session, image, image_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, image); + scm_define(sc, tag, ret); + + return ret; +} + +static pointer kern_mk_sprite(scheme *sc, pointer args) +{ + struct images *images; + int n_frames, index, facings, wave; + struct sprite *sprite; + const char *tag = TAG_UNK; + pointer ret; + + if (unpack(sc, &args, "ypddbd", &tag, &images, &n_frames, &index, + &wave, &facings)) { + load_err("kern-mk-sprite %s: bad args", tag); + return sc->NIL; + } + + sprite = sprite_new(tag, n_frames, index, wave, facings, images); + session_add(Session, sprite, sprite_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, sprite); + scm_define(sc, tag, ret); + + return ret; +} + +struct connection { + Object *from; + char *to; +}; + +static pointer kern_mk_terrain(scheme *sc, pointer args) +{ + int alpha, light; + void *sprite; + struct terrain *terrain; + const char *tag = TAG_UNK, *name; + pointer ret; + int pclass; + pointer proc = NULL; + + /* Revisit: ignore effects for now */ + + if (unpack(sc, &args, "ysdpddc", &tag, &name, &pclass, &sprite, + &alpha, &light, &proc)) { + load_err("kern-mk-terrain %s: bad args", tag); + return sc->NIL; + } + + terrain = terrain_new(tag, name, (struct sprite*)sprite, pclass, + alpha, light); + + if (proc != sc->NIL) { + terrain->effect = closure_new_ref(sc, proc); + } + terrain->renderCombat = NULL; + + list_add(&Session->terrains, &terrain->session_list); + ret = scm_mk_ptr(sc, terrain); + scm_define(sc, tag, ret); + + return ret; +} + +static pointer kern_mk_sound(scheme *sc, pointer args) +{ + sound_t *sound; + const char *tag = TAG_UNK, *name; + pointer ret; + + if (unpack(sc, &args, "ys", &tag, &name)) { + load_err("kern-mk-sound %s: bad args", tag); + return sc->NIL; + } + + sound = sound_new(tag, name); + + /* Add it to the session */ + session_add(Session, sound, sound_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, sound); + scm_define(sc, tag, ret); + + return ret; +} + +static pointer kern_mk_palette(scheme *sc, pointer args) +{ + int argno = 1; + const char *tag = TAG_UNK; + pointer ret; + + if (Session->palette) { + load_err("kern-mk-palette: %s already set as the session "\ + "palette", + Session->palette->tag); + return sc->NIL; + } + + if (unpack(sc, &args, "y", &tag)) { + load_err("kern-mk-palette %s: bad args", tag); + return sc->NIL; + } + + Session->palette = terrain_palette_new(tag); + + /* The next argument after the tag shoud be a list of (glyph, terrain) + * pairs. Since these are pairs - and not lists - */ + + if (! scm_is_pair(sc, args)) { + load_err("kern-mk-palette arg %d: arg list too short", argno); + terrain_palette_del(Session->palette); + return sc->NIL; + } + + args = scm_car(sc, args); + argno = 1; + + while (scm_is_pair(sc, args)) { + + char *glyph; + void *terrain; + pointer pair; + + pair = scm_car(sc, args); + args = scm_cdr(sc, args); + unpack(sc, &pair, "sp", &glyph, &terrain); + terrain_palette_add(Session->palette, glyph, + (struct terrain*)terrain); + } + + session_add(Session, Session->palette, terrain_palette_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, Session->palette); + scm_define(sc, tag, ret); + + return ret; +} + +static pointer kern_mk_map(scheme *sc, pointer args) +{ + int width, height, x, y, i; + struct terrain_palette *pal; + const char *tag = TAG_UNK; + struct terrain_map *map; + pointer ret; + struct list *elem; + + if (unpack(sc, &args, "yddp", &tag, &width, &height, &pal)) { + load_err("kern-mk-map %s: bad args", tag); + return sc->NIL; + } + + /* Final argument should be a list of strings. */ + + if (! scm_is_pair(sc, args)) { + load_err("kern-mk-map %s: arg list too short", tag); + return sc->NIL; + } + + args = scm_car(sc, args); + map = terrain_map_new(tag, width, height, pal); + i = 0; + + for (y = 0; y < height; y++) { + + char *map_line; + char *glyph; + + if (unpack(sc, &args, "s", &map_line)) + goto abort; + + for (x = 0; x < width; x++) { + + struct terrain *tt; + + glyph = strtok(x ? NULL : map_line, " "); + if (! glyph) { + load_err("kern-mk-map %s: line %d only "\ + "%d wide, should be %d wide", tag, + y, x, width); + goto abort; + } + + tt = palette_terrain_for_glyph(pal, glyph); + if (! tt) { + load_err("kern-mk-map %s: line %d "\ + "column %d: glyph %s "\ + "has no terrain in palette %s", tag, + y, x, glyph, pal->tag); + goto abort; + } + + map->terrain[i] = tt; + i++; + + } + } + + /* run all registered terrain blenders on the new map */ + list_for_each(&Session->blenders, elem) { + blender_t *blender=outcast(elem, blender_t, list); + terrain_map_blend(map, blender->inf, blender->n_nonsup, + blender->nonsup, blender->range); + } + + + map->handle = session_add(Session, map, terrain_map_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, map); + + /* Embedded maps (those defined within and used exclusively for) place + * constructors may not have and do not need tags. */ + if (tag) + scm_define(sc, tag, ret); + + return ret; + + abort: + terrain_map_unref(map); + return sc->NIL; +} + + + +static pointer kern_mk_composite_map(scheme *sc, pointer args) +{ + int width, height, x = 0, y = 0, i = 0; + const char *tag = TAG_UNK; + struct terrain_map *map=NULL, *submap=NULL; + pointer ret; + struct list *elem; + + /* parse supermap tag and dimensions */ + if (unpack(sc, &args, "ydd", &tag, &width, &height)) { + load_err("kern-mk-composite-map %s: bad args", tag); + return sc->NIL; + } + + /* unpack the first submap */ + if (unpack(sc, &args, "p", &submap)) { + load_err("kern-mk-composite-map %s: first submap invalid", tag); + goto abort; + } + + /* create the supermap, inferring the submap dimensions and palette + * from the first submap */ + map = terrain_map_new(tag, width * submap->w, height * submap->h, + submap->palette); + + /* set the supermap info */ + map->submap_w = submap->w; + map->submap_h = submap->h; + map->composite = 1; + + /* blit the first submap onto the supermap in the upper left-hand + * corner */ + terrain_map_blit(map, 0, 0, submap, 0, 0, submap->w, submap->h); + + /* for each remaining submap in the list... */ + for (y = 0; y < height; y++) { + + for (x = 0; x < width; x++) { + + /* except the first one... */ + if (x == 0 && y == 0) + continue; + + /* unpack it */ + if (unpack(sc, &args, "p", &submap)) { + load_err("kern-mk-composite-map %s: submap "\ + "%d invalid", tag, i); + goto abort; + } + + /* check its palette and dimensions */ + if (map->palette != submap->palette) { + load_err("kern-mk-composite-map %s: submap %d "\ + "palette doesn't match first submap "\ + "palette", tag, i); + goto abort; + } + if (map->submap_w != submap->w) { + load_err("kern-mk-composite-map %s: submap %d "\ + "width doesn't match first submap "\ + "width", tag, i); + goto abort; + } + if (map->submap_h != submap->h) { + load_err("kern-mk-composite-map %s: submap %d "\ + "height doesn't match first submap "\ + "height", tag, i); + goto abort; + } + + /* blit the submap onto the supermap */ + terrain_map_blit(map, x * map->submap_w, y * map->submap_h, + submap, 0, 0, + map->submap_w, map->submap_h); + } + } + + /* run all registered terrain blenders on the new map */ + list_for_each(&Session->blenders, elem) { + blender_t *blender=outcast(elem, blender_t, list); + terrain_map_blend(map, blender->inf, blender->n_nonsup, + blender->nonsup, blender->range); + } + + /* add it to the session */ + map->handle = session_add(Session, map, terrain_map_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, map); + + /* define its tag (if specified) */ + if (tag) + scm_define(sc, tag, ret); + + return ret; + + abort: + terrain_map_unref(map); + return sc->NIL; +} + +static int kern_place_load_subplaces(scheme *sc, pointer *args, struct place *place) +{ + pointer subplaces; + + if (! scm_is_pair(sc, *args)) { + load_err("kern-mk-place %s: missing the subplaces list", + place->tag); + return -1; + } + + subplaces = scm_car(sc, *args); + *args = scm_cdr(sc, *args); + + while (scm_is_pair(sc, subplaces)) { + struct place *subplace = 0; + int x, y; + pointer cell; + + cell = scm_car(sc, subplaces); + subplaces = scm_cdr(sc, subplaces); + + if (unpack(sc, &cell, "pdd", &subplace, &x, &y)) { + load_err("kern-mk-place %s: bad arg in subplaces list", + place->tag); + return -1; + } + + if (!subplace) { + load_err("kern-mk-place %s: null place in subplaces "\ + "list", place->tag); + return -1; + } + + if (subplace->magic != PLACE_MAGIC) { + load_err("kern-mk-place %s: subplace is not a place", + place->tag); + return -1; + } + + if (place_add_subplace(place, subplace, x, y)) { + load_err("kern-mk-place %s: failed to put %s as a "\ + "subplace at [%d, %d]; is another subplace "\ + "already there? Are the coordinates off-map?", + place->tag, subplace->tag, x, y); + return -1; + } + } + + return 0; +} + + + +static int kern_place_load_neighbors(scheme *sc, pointer *args, + struct place *place) +{ + pointer neighbors; + + if (! scm_is_pair(sc, *args)) { + load_err("kern-mk-place %s: missing the contents list", + place->tag); + return -1; + } + + neighbors = scm_car(sc, *args); + *args = scm_cdr(sc, *args); + + while (scm_is_pair(sc, neighbors)) { + int dir, opdir; + struct place *neighbor, *tmp; + pointer cell; + + cell = scm_car(sc, neighbors); + neighbors = scm_cdr(sc, neighbors); + + if (unpack(sc, &cell, "pd", &neighbor, &dir)) { + load_err("kern-mk-place %s: error in neighbor list", + place->tag); + return -1; + } + + if (! IS_LEGAL_DIRECTION(dir)) { + load_err("kern-mk-place %s: invalid direction for "\ + "neighbor: %d\n", place->tag, dir); + return -1; + } + + opdir = directionToOpposite(dir); + + /* check for existing neighbors */ + if ((tmp = place_get_neighbor(place, dir))) { + load_err("kern-mk-place %s: already has %s as a "\ + "neighbor in direction %d\n", + place->tag, tmp->tag, dir); + return -1; + } + + if ((tmp = place_get_neighbor(neighbor, opdir))) { + load_err("kern-mk-place %s: already has %s as a "\ + "neighbor in direction %d\n", + neighbor->tag, + tmp->tag, opdir); + return -1; + } + + /* finally, hook them up */ + place_set_neighbor(place, dir, neighbor); + } + + return 0; +} + +KERN_API_CALL(kern_place_set_neighbor) +{ + int dir; + struct place *place, *neighbor; + + if (unpack(sc, &args, "dpp", &dir, &place, &neighbor)) { + rt_err("kern-place-set-neighbor: bad args"); + return sc->F; + } + + // neighbor == null is allowed (it unlinks current neighbor) + if (! place) { + rt_err("kern-place-set-neighbor: null place"); + return sc->F; + } + + if (! IS_LEGAL_DIRECTION(dir)) { + rt_err("kern-place-set-neighbor: bad direction %d", dir); + return sc->F; + } + + /* link (works both ways) */ + place_set_neighbor(place, dir, neighbor); + + return sc->T; +} + +KERN_API_CALL(kern_place_apply_tile_effects) +{ + struct place *place; + class Object *obj; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-apply-tile-effects: bad place arg"); + return sc->NIL; + } + + obj = unpack_obj(sc, &args, "kern-obj-relocate"); + if (!obj) + return sc->NIL; + + place_apply_tile_effects(place, obj); + return sc->NIL; +} + +static int kern_place_load_contents(scheme *sc, pointer *args, + struct place *place) +{ + pointer contents; + + if (! scm_is_pair(sc, *args)) { + load_err("kern-mk-place %s: missing the contents list", + place->tag); + return -1; + } + + contents = scm_car(sc, *args); + *args = scm_cdr(sc, *args); + + while (scm_is_pair(sc, contents)) { + + class Object *obj = 0; + int x, y; + pointer cell; + + cell = scm_car(sc, contents); + contents = scm_cdr(sc, contents); + + if (unpack(sc, &cell, "pdd", &obj, &x, &y)) { + load_err("kern-mk-place %s: bad arg in content list", + place->tag); + return -1; + } + + if (!obj) { + load_err("kern-mk-place %s: null obj in content list", + place->tag); + return -1; + } + + obj->relocate(place, x, y, REL_NOTRIG); + } + + return 0; +} + +static int kern_place_load_entrances(scheme *sc, pointer *args, + struct place *place) +{ + pointer entrances; + + if (! scm_is_pair(sc, *args)) { + load_err("kern-mk-place %s: missing the entrances list", + place->tag); + return -1; + } + + entrances = scm_car(sc, *args); + *args = scm_cdr(sc, *args); + + while (scm_is_pair(sc, entrances)) { + + int dir, x, y; + pointer cell; + + cell = scm_car(sc, entrances); + entrances = scm_cdr(sc, entrances); + + if (unpack(sc, &cell, "ddd", &dir, &x, &y)) { + load_err("kern-mk-place %s: bad arg in entrances list", + place->tag); + return -1; + } + + if (place_set_edge_entrance(place, dir, x, y)) { + load_err("kern-mk-place %s: failed to set entrance for "\ + "direction %d to [%d %d]", place->tag, dir, x, y); + return -1; + } + } + + return 0; +} + +static int kern_place_load_hooks(scheme *sc, pointer *args, + struct place *place) +{ + pointer contents; + pointer pre_entry_proc; + + if (! scm_is_pair(sc, *args)) { + load_err("kern-mk-place %s: missing the hooks list", + place->tag); + return -1; + } + + contents = scm_car(sc, *args); + *args = scm_cdr(sc, *args); + + while (scm_is_pair(sc, contents)) { + + if (unpack(sc, &contents, "c", &pre_entry_proc)) { + load_err("kern-mk-place %s: bad arg in hook list", + place->tag); + return -1; + } + + place_add_on_entry_hook(place, + closure_new_ref(sc, pre_entry_proc)); + } + + return 0; +} + +KERN_API_CALL(kern_place_add_on_entry_hook) +{ + struct place *place; + pointer proc; + + if (unpack(sc, &args, "pc", &place, &proc)) { + rt_err("kern-place-add-on-entry-hook: bad args"); + return sc->NIL; + } + + if (! place) { + rt_err("kern-place-add-on-entry-hook: null place"); + return sc->NIL; + } + + place_add_on_entry_hook(place, + closure_new_ref(sc, proc)); + return sc->NIL; +} + +KERN_API_CALL(kern_mk_place) +{ + int wild, wraps, underground, combat; + struct terrain_map *map; + struct place *place; + struct sprite *sprite; + const char *tag = TAG_UNK, *name; + pointer ret; + + if (unpack(sc, &args, "ysppbbbb", &tag, &name, &sprite, &map, + &wraps, &underground, &wild, &combat)) { + load_err("kern-mk-place %s: bad args", tag); + return sc->NIL; + } + + if ( ! map->handle) { + load_err("kern-mk-place %s: map %s has no session handle; "\ + "is it already being used in another place?", tag, + map->tag); + return sc->NIL; + } + + session_rm(Session, map->handle); + map->handle = 0; + place = place_new(tag, name, sprite, map, wraps, underground, wild, + combat); + + + if (kern_place_load_subplaces(sc, &args, place) || + kern_place_load_neighbors(sc, &args, place) || + kern_place_load_contents(sc, &args, place) || + kern_place_load_hooks(sc, &args, place) || + kern_place_load_entrances(sc, &args, place)) + goto abort; + + place->handle = session_add(Session, place, place_dtor, place_save, place_start); + ret = scm_mk_ptr(sc, place); + scm_define(sc, tag, ret); + return ret; + + abort: + place_del(place); + return sc->NIL; +} + +static pointer kern_mk_species(scheme *sc, pointer args) +{ + struct species *species; + int str, intl, dex, spd, vr, hpmod, hpmult, argno = 1; + int mpmod, mpmult, visible, n_slots, n_spells, i, xpval; + int stationary=0; + struct sprite *sleep_sprite; + class ArmsType *weapon; + const char *tag = TAG_UNK, *name, *armor_dice; + sound_t *damage_sound, *walking_sound; + pointer slots; + pointer spells; + pointer ret; + struct mmode *mmode; + + + if (unpack(sc, &args, "ysdddddpddddppbppdbs", &tag, &name, &str, + &intl, &dex, &spd, &vr, &mmode, &hpmod, &hpmult, &mpmod, + &mpmult, &sleep_sprite, &weapon, + &visible, &damage_sound, &walking_sound, + &xpval, &stationary, &armor_dice)) { + load_err("kern-mk-species %s: bad args", tag); + return sc->NIL; + } + + if (scm_len(sc, args) < 2) { + load_err("kern-mk-species %s: arg list too short", tag, + argno++); + return sc->NIL; + } + + if (! mmode) { + load_err("kern-mk-species %s: null mmode", tag); + return sc->NIL; + } + + + /* get the list of slots */ + slots = scm_car(sc, args); + args = scm_cdr(sc, args); + + /* get the list of spells */ + spells = scm_car(sc, args); + args = scm_cdr(sc, args); + + /* get the sizes of the various lists */ + n_slots = scm_len(sc, slots); + n_spells = scm_len(sc, spells); + + species = species_new(tag, name, damage_sound, walking_sound, str, + intl, dex, spd, vr, hpmod, hpmult, + mpmod, mpmult, visible, + n_slots, n_spells); + species->weapon = weapon; + species->sleep_sprite = sleep_sprite; + species->mmode = mmode; + species->xpval = xpval; + species->stationary = stationary; + + /* Optional armor dice */ + if (armor_dice) { + species->armor_dice = strdup(armor_dice); + } + + /* Load the list of slots. */ + i = 0; + while (scm_is_pair(sc, slots)) { + if (unpack(sc, &slots, "d", &species->slots[i++])) + goto abort; + } + + /* Load the list of spells */ + i = 0; + while (scm_is_pair(sc, spells)) { + char *code; + if (unpack(sc, &spells, "s", &code)) + goto abort; + species->spells[i] = strdup(code); + assert(species->spells[i]); + i++; + } + + session_add(Session, species, species_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, species); + scm_define(sc, tag, ret); + return ret; + + abort: + species_del(species); + return sc->NIL; +} + +static pointer kern_mk_arms_type(scheme *sc, pointer args) +{ + class ArmsType *arms; + const char *tag = TAG_UNK, *name; + sound_t *fire_sound; + int slots, hands, range, weight; + char *hit, *defend, *damage, *armor; + int rap, AP_mod, thrown, ubiq; + struct sprite *sprite; + class MissileType *missile; + class ObjectType *ammo; + pointer gifc; + pointer ret; + int gifc_cap; + int str_attack_mod; + int dex_attack_mod; + int char_damage_mod; + float char_avoid_mod; + struct mmode *mmode; + + + if (unpack(sc, &args, "yspssssdddddppbbdpdodddrp", + &tag, + &name, + &sprite, + &hit, &damage, &armor, &defend, + &slots, &hands, &range, &rap, &AP_mod, + &missile, &ammo, + &thrown, &ubiq, + &weight, + &fire_sound, + &gifc_cap, + &gifc, + &str_attack_mod, &dex_attack_mod, &char_damage_mod, + &char_avoid_mod, + &mmode)) { + load_err("kern-mk-arms-type %s: bad args", tag); + return sc->NIL; + } + + if (! dice_valid(hit)) { + load_err("kern-mk-arms-type %s: bad dice format '%s'", + tag, hit); + return sc->NIL; + } + + if (! dice_valid(defend)) { + load_err("kern-mk-arms-type %s: bad dice format '%s'", + tag, defend); + return sc->NIL; + } + + if (! dice_valid(damage)) { + load_err("kern-mk-arms-type %s: bad dice format '%s'", + tag, damage); + return sc->NIL; + } + + if (! dice_valid(armor)) { + load_err("kern-mk-arms-type %s: bad dice format '%s'", + tag, armor); + return sc->NIL; + } + + arms = new ArmsType(tag, name, sprite, slots, hit, defend, hands, + range, + weight, damage, armor, rap, AP_mod, thrown, ubiq, + fire_sound, missile, ammo, str_attack_mod, dex_attack_mod, + char_damage_mod, char_avoid_mod, false); + + arms->setMovementMode(mmode); + + if (gifc != sc->NIL) { + /* arms->get_handler = closure_new(sc, get_handler); */ + arms->setGifc(closure_new(sc, gifc), gifc_cap); + } + + session_add(Session, arms, arms_type_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, arms); + scm_define(sc, tag, ret); + return ret; +} + +static pointer kern_mk_missile_type(scheme *sc, pointer args) +{ + class MissileType *arms; + const char *tag = TAG_UNK, *name; + struct sprite *sprite; + pointer gifc; + pointer ret; + int gifc_cap; + struct mmode *mmode; + int beam; + int fixedrange; + + + if (unpack(sc, &args, "yspdopbb", + &tag, + &name, + &sprite, + &gifc_cap, + &gifc, + &mmode, + &beam, + &fixedrange)) + { + load_err("kern-mk-projectile-type %s: bad args", tag); + return sc->NIL; + } + + arms = new MissileType(tag, name, sprite, beam, fixedrange, mmode); + + if (gifc != sc->NIL) + { + /* arms->get_handler = closure_new(sc, get_handler); */ + arms->setGifc(closure_new(sc, gifc), gifc_cap); + } + + session_add(Session, arms, missile_type_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, arms); + scm_define(sc, tag, ret); + + return ret; +} + +static pointer kern_mk_field_type(scheme *sc, pointer args) +{ + class FieldType *field; + const char *tag = TAG_UNK, *name; + struct sprite *sprite; + int light, duration, pclass; + closure_t *clx = NULL; + pointer func = sc->NIL; + pointer ret; + struct mmode *mmode = NULL; + + if (unpack(sc, &args, "yspdddcp", &tag, &name, &sprite, &light, + &duration, &pclass, &func, &mmode)) { + load_err("kern-mk-field-type %s: bad args", tag); + return sc->NIL; + } + + if (func != sc->NIL) { + clx = closure_new(sc, func); + } + + field = new FieldType(tag, name, sprite, light, duration, pclass, clx); + field->setMovementMode(mmode); + session_add(Session, field, field_type_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, field); + scm_define(sc, tag, ret); + return ret; +} + +static void mmode_dtor(void *ptr) +{ + mmode_del((struct mmode*)ptr); +} + +KERN_API_CALL(kern_mk_mmode) +{ + char *tag, *name; + int index; + struct mmode *mmode; + pointer ret; + + if (unpack(sc, &args, "ysd", &tag, &name, &index)) { + load_err("kern-mk-mmode: bad args"); + return sc->NIL; + } + + mmode = mmode_new(tag, name, index); + session_add(Session, mmode, mmode_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, mmode); + scm_define(sc, tag, ret); + return ret; +} + +static pointer kern_mk_obj_type(scheme *sc, pointer args) +{ + class ObjectType *type; + const char *tag = TAG_UNK, *name; + char *pluralName=NULL; + enum layer layer; + struct sprite *sprite; + pointer ret; + pointer gifc; + int gifc_cap; + struct mmode *mmode; + + /* unpack the tag */ + if (unpack(sc, &args, "y", &tag)) { + load_err("kern-mk-obj-type %s: bad args (did you mean to use "\ + "kern-mk-obj instead?)", tag); + return sc->NIL; + } + + /* probe the name to see if it is a list, if so then use the car as the + * name and the cadr as the pluralName */ + if (scm_is_pair(sc, scm_car(sc, args))) { + pointer list = scm_car(sc, args); + args=scm_cdr(sc, args); + if (unpack(sc, &list, "ss", &name, &pluralName)) { + load_err("kern-mk-obj-type %s: bad name arg", tag); + return sc->NIL; + } + } else if (unpack(sc, &args, "s", &name)) { + load_err("kern-mk-obj-type %s: bad name arg", tag); + return sc->NIL; + } + + /* continue unpacking the rest of the args */ + if (unpack(sc, &args, "pddop", &sprite, &layer, &gifc_cap, &gifc, &mmode)) { + load_err("kern-mk-obj-type %s: bad args (did you mean to use "\ + "kern-mk-obj instead?)", tag); + return sc->NIL; + } + + type = new ObjectType(tag, name, sprite, layer); + assert(type); + + if (gifc != sc->NIL) { + type->setGifc(closure_new(sc, gifc), gifc_cap); + } + + if (pluralName) { + type->setPluralName(pluralName); + } + + type->setMovementMode(mmode); + session_add(Session, type, obj_type_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, type); + scm_define(sc, tag, ret); + return ret; +} + +static pointer kern_mk_occ(scheme *sc, pointer args) +{ + struct occ *occ; + int hpmod, hpmult; + int mpmod, mpmult, hit, def, dam, arm, xpval; + const char *tag = TAG_UNK, *name; + struct skill_set *skset; + float magic; + pointer ret; + + /* Basic args */ + if (unpack(sc, &args, "ysrdddddddddp", + &tag, &name, &magic, &hpmod, &hpmult, &mpmod, &mpmult, &hit, + &def, &dam, &arm, &xpval, &skset)) { + load_err("kern-mk-occ %s: bad args", tag); + return sc->NIL; + } + + occ = occ_new(tag, name, magic, hpmod, hpmult, mpmod, mpmult, hit, def, + dam, arm); + occ_ref(occ); + occ->xpval = xpval; + occ_set_skills(occ, skset); + + session_add(Session, occ, occ_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, occ); + scm_define(sc, tag, ret); + return ret; +} + +static int kern_load_hooks(scheme *sc, pointer hook_tbl, Object *obj) +{ + while (scm_is_pair(sc, hook_tbl)) { + + struct effect *effect; + int flags; + pointer gobcell; + pointer hook_entry; + struct gob *gob = NULL; + clock_alarm_t clk; + + hook_entry = scm_car(sc, hook_tbl); + hook_tbl = scm_cdr(sc, hook_tbl); + + if (unpack(sc, &hook_entry, "pldd", &effect, &gobcell, &flags, + &clk)) { + return -1; + } + + /* Note: even if gobcell is sc->NIL we want to wrap it. I once + * tried to use a NULL gob instead but if we pass that back + * into scheme as an arg and the gc tries to mark it we'll + * crash. */ + gob = gob_new(sc, gobcell); + gob->flags |= GOB_SAVECAR; + + obj->restoreEffect(effect, gob, flags, clk); + } + + return 0; +} + +static void kern_load_conv(scheme *sc, pointer sym, Object *obj) +{ + struct conv *conv; + struct closure *proc; + + if (sym == sc->NIL) { + return; + } + + if (! (proc = closure_new_ref(sc, sym))) { + load_err("%s: closure_new failed", __FUNCTION__); + return; + } + + if (!(conv = conv_new(proc))) { + load_err("%s: conv_new failed", __FUNCTION__); + goto done2; + } + + obj->setConversation(conv); + conv_unref(conv); + done2: + closure_unref(proc); +} + +static pointer kern_mk_char(scheme *sc, pointer args) +{ + class Character *character; + int str, intl, dex, hpmod, hpmult; + int mpmod, mpmult, hp, xp, mp, AP_per_round, lvl, dead; + const char *tag = TAG_UNK, *name; + struct species *species; + struct occ *occ; + struct sprite *sprite; + pointer conv; + pointer readied; + pointer ret; + pointer ai; + pointer hook_tbl; + int base_faction; + struct sched *sched; + class Container *inventory; + + if (unpack(sc, &args, "yspppdddddddddddddbcpcp", + &tag, &name, &species, &occ, + &sprite, &base_faction, &str, + &intl, &dex, &hpmod, &hpmult, &mpmod, &mpmult, + &hp, &xp, &mp, &AP_per_round, &lvl, &dead, + &conv, &sched, &ai, &inventory)) { + load_err("kern-mk-char %s: bad args", tag); + return sc->NIL; + } + + if (! scm_is_pair(sc, args)) { + load_err("kern-mk-char %s: no readied arms list", tag); + return sc->NIL; + } + + readied = scm_car(sc, args); + args = scm_cdr(sc, args); + + character = new class Character(tag, name, sprite,species, occ, + str, intl, dex, hpmod, hpmult, mpmod, + mpmult, + hp, xp, mp, AP_per_round, lvl); + assert(character); + character->setBaseFaction(base_faction); + character->setSchedule(sched); + character->setInventoryContainer(inventory); + character->setDead(dead); + + kern_load_conv(sc, conv, character); + + if (ai != sc->NIL) { + character->setAI(closure_new(sc, ai)); + } + + /* Load the list of arms. */ + while (scm_is_pair(sc, readied)) { + class ArmsType *arms; + if (unpack(sc, &readied, "p", &arms)) { + load_err("kern-mk-char %s: error in arms list", tag); + goto abort; + } + /*character->add(arms, 1);*/ + character->ready(arms); + } + + /* Load the hooks. */ + hook_tbl = scm_car(sc, args); + args = scm_cdr(sc, args); + if (kern_load_hooks(sc, hook_tbl, character)) { + load_err("kern-mk-char %s: bad hook entry", tag); + goto abort; + } + + + ret = scm_mk_ptr(sc, character); + + /* If the character is tagged then it's not "anonymous", and we'll + * assign it to a scheme variable named after the tag. */ + if (tag) { + scm_define(sc, tag, ret); + + /* Tagged objects may be referred to in the script by their + * tag. If the object is destroyed, the scheme variable that + * refers to the object is still valid (in Scheme, it isn't + * really possible to undefine variables). To prevent crashes + * on dereferencing this variable we'll bump the refcount. To + * ensure the object is destroyed on session teardown, we'll + * mark it for custom finalization, which will decrement the + * extra refcount. */ + obj_inc_ref(character); + scm_set_cust_fin(sc, ret); + } + + return ret; + + abort: + delete character; + return sc->NIL; +} + +static pointer kern_mk_obj(scheme *sc, pointer args) +{ + class Object *obj; + class ObjectType *type = 0; + int count; + + if (unpack(sc, &args, "pd", &type, &count)) { + load_err("kern-mk-obj: bad args"); + return sc->NIL; + } + + if (!type) { + load_err("kern-mk-obj: null type"); + return sc->NIL; + } + + // Fixme: we need a MAGIC number field, but it won't work because + // 'type' is a c++ object. If the script hands us something that is not + // really an ObjectType we'll crash sooner or later. + + obj = type->createInstance(); + assert(obj); + obj->setCount(count); + + if (kern_load_hooks(sc, scm_car(sc, args), obj)) { + load_err("kern-mk-obj: error in hook list"); + goto abort; + } + args = scm_cdr(sc, args); + + // Objects aren't added to the session the way types are. Every object + // will end up in some type of container; objects should always be + // loaded as part of a container's contents; and the container should + // always save the objects it contains. + // + // There's nothing to prevent a script from creating a "dangling" + // object which is never put anywhere. Although weird (and probably a + // bug in the script), it should be benign. Memory leaks are prevented + // by deinitializing the interpreter every time we load a new session. + // Furthermore, such orphan objects will never be saved, so they won't + // propogate. + + return scm_mk_ptr(sc, obj); + + abort: + delete obj; + return sc->NIL; +} + +static pointer kern_mk_field(scheme *sc, pointer args) +{ + class Field *obj; + class FieldType *type = 0; + int duration; + + if (unpack(sc, &args, "pd", &type, &duration)) { + load_err("kern-mk-obj: bad args"); + return sc->NIL; + } + + if (!type) { + load_err("kern-mk-obj: null type"); + return sc->NIL; + } + + obj = new Field(type, duration); + assert(obj); + + // Objects aren't added to the session the way types are. Every object + // will end up in some type of container; objects should always be + // loaded as part of a container's contents; and the container should + // always save the objects it contains. + + return scm_mk_ptr(sc, obj); +} + +static pointer kern_mk_party(scheme *sc, pointer args) +{ + class Party *obj; + + obj = new Party(); + assert(obj); + + return scm_mk_ptr(sc, obj); +} + +static pointer kern_obj_put_at(scheme *sc, pointer args) +{ + class Object *obj; + struct place *place; + pointer loc; + int x, y; + + if (unpack(sc, &args, "p", &obj)) { + rt_err("kern-obj-put-at: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-put-at: null obj"); + return sc->NIL; + } + + loc = scm_car(sc, args); + if (! scm_is_pair(sc, loc)) { + rt_err("kern-obj-put-at: invalid location"); + return sc->NIL; + } + + if (unpack(sc, &loc, "pdd", &place, &x, &y)) { + rt_err("kern-obj-put-at: bad location args"); + return sc->NIL; + } + + if (!place) { + rt_err("kern-obj-put-at: null place"); + return sc->NIL; + } + + obj->relocate(place, x, y, REL_NOSTEP); + return sc->NIL; +} + +static pointer kern_obj_relocate(scheme *sc, pointer args) +{ + class Object *obj; + struct place *place; + pointer cutscene; + int x, y; + struct closure *clx = NULL; + + obj = unpack_obj(sc, &args, "kern-obj-relocate"); + if (!obj) + return sc->NIL; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-obj-relocate")) + return sc->NIL; + + if (unpack(sc, &args, "o", &cutscene)) { + rt_err("kern-obj-relocate: bad args"); + return sc->NIL; + } + + if (cutscene != sc->NIL) { + clx = closure_new_ref(sc, cutscene); + } + + obj->relocate(place, x, y, REL_NOSTEP, clx); + + closure_unref_safe(clx); + + return sc->NIL; +} + +static pointer kern_obj_get_location(scheme *sc, pointer args) +{ + class Object *obj; + struct place *place; + int x, y; + + if (!(obj = unpack_obj(sc, &args, "kern-obj-get-location"))) { + assert(false); + return sc->NIL; + } + + if ((place = obj->getPlace())) { + x = obj->getX(); + y = obj->getY(); + return pack(sc, "pdd", place, x, y); + } + + return sc->NIL; +} + +static pointer kern_obj_get_dir(scheme *sc, pointer args) +{ + class Object *obj; + int dx, dy; + + if (!(obj = unpack_obj(sc, &args, "kern-obj-get-dir"))) { + assert(false); + return sc->NIL; + } + + dx = obj->getDx(); + dy = obj->getDy(); + + return pack(sc, "dd", dx, dy); +} + +static pointer kern_place_get_location(scheme *sc, pointer args) +{ + struct place *place; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-get-location: bad args"); + return sc->NIL; + } + + if (! place) { + rt_err("kern-place-get-location: null place"); + return sc->NIL; + } + + if (! place->location.place) + return sc->NIL; + + return pack(sc, "pdd", + place->location.place, + place->location.x, + place->location.y); +} + +static int kern_append_effect(struct hook_entry *entry, void *data) +{ + pointer cell; + struct kern_append_info *info; + + info = (struct kern_append_info *)data; + + cell = scm_mk_ptr(info->sc, entry->effect); + cell = _cons(info->sc, cell, info->sc->NIL, 0); + + if (info->head == info->sc->NIL) { + info->head = cell; + info->tail = cell; + } else { + info->tail->_object._cons._cdr = cell; + info->tail = cell; + } + + return 0; +} + +KERN_API_CALL(kern_obj_get_effects) +{ + class Object *obj; + int i; + struct kern_append_info info; + + if (!(obj = unpack_obj(sc, &args, "kern-obj-get-effects"))) { + return sc->NIL; + } + + /* initialize the context used by the callback to append objects */ + info.sc = sc; + info.head = sc->NIL; + info.tail = sc->NIL; + info.filter = NULL; + + /* for each effect hook on the object */ + for (i = 0; i < OBJ_NUM_HOOKS; i++) { + + /* build a scheme list of the attached effects */ + obj->hookForEach(i, kern_append_effect, &info); + } + + return info.head; +} + +static pointer kern_obj_get_vision_radius(scheme *sc, pointer args) +{ + class Object *obj; + + if (!(obj = unpack_obj(sc, &args, "kern-obj-get-location"))) { + return sc->NIL; + } + + return scm_mk_integer(sc, obj->getVisionRadius()); +} + +static pointer kern_obj_put_into(scheme *sc, pointer args) +{ + class Object *obj; + class Object *container; + + if (unpack(sc, &args, "pp", &obj, &container)) { + load_err("kern-obj-put: bad args"); + return sc->F; + } + + if (!obj) { + rt_err("kern-obj-put: null obj"); + return sc->F; + } + + if (!container) { + rt_err("kern-obj-put: null container"); + return sc->F; + } + + return container->add(obj->getObjectType(), + obj->getCount()) ? sc->T : sc->F; + +} + +/* + * kern_obj_remove - remove an object from the map. Note that this implicitly + * destroys most objects automatically, unless the object has another reference + * count. Use kern_obj_inc_ref to prevent destruction during this call. + */ +static pointer kern_obj_remove(scheme *sc, pointer args) +{ + class Object *obj; + + if (!(obj=unpack_obj(sc, &args, "kern-obj-remove"))) { + return sc->NIL; + } + + /* Bugfix: don't use place_remove_object() because it doesn't call + setOnMap(false). */ + //place_remove_object(obj->getPlace(), obj); + obj->remove(); + + return sc->NIL; +} + +#if 0 +/* + * kern_obj_destroy - obsolete explicit destructor. Try to use kern_obj_dec_ref + * instead, wait and see if we really need this. + */ +static pointer kern_obj_destroy(scheme *sc, pointer args) +{ + class Object *obj; + + if (!(obj=unpack_obj(sc, &args, "kern-obj-destroy"))) { + return sc->NIL; + } + + delete obj; + + return sc->NIL; +} +#endif + +static pointer kern_obj_inc_ref(scheme *sc, pointer args) +{ + class Object *obj; + + if (!(obj=unpack_obj(sc, &args, "kern-obj-inc-ref"))) { + return sc->NIL; + } + + obj_inc_ref(obj); + + return scm_mk_ptr(sc, obj); +} + +static pointer kern_obj_dec_ref(scheme *sc, pointer args) +{ + class Object *obj; + int refcount; + + if (!(obj=unpack_obj(sc, &args, "kern-obj-dec-ref"))) { + return sc->NIL; + } + + refcount = obj->refcount; + obj_dec_ref(obj); + + if (refcount > 1) + /* object was not destroyed - return it */ + return scm_mk_ptr(sc, obj); + + /* object was destroyed - return NIL */ + return sc->NIL; +} + +static pointer kern_obj_add_food(scheme *sc, pointer args) +{ + class Object *obj; + int quantity; + + if (unpack(sc, &args, "pd", &obj, &quantity)) { + load_err("kern-obj-add-food: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-add-food: null obj"); + return sc->NIL; + } + + if (! obj->addFood(quantity)) { + rt_err("kern-obj-add-food: '%s' does not use food", + obj->getName()); + } + + return sc->NIL; +} + +static pointer kern_obj_add_gold(scheme *sc, pointer args) +{ + class Object *obj; + int quantity; + + if (unpack(sc, &args, "pd", &obj, &quantity)) { + load_err("kern-obj-add-gold: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-add-gold: null obj"); + return sc->NIL; + } + + if (! obj->addGold(quantity)) { + /* NPC's can't add gold (not even if they have containers) + * because gold is not an object! Gold coins are, but that's + * not what gets passed in here, is it? */ + rt_err("kern-obj-add-gold: '%s' does not use gold", + obj->getName()); + } + + return sc->NIL; +} + +static pointer kern_mk_inventory(scheme *sc, pointer args) +{ + class Container *container; + pointer contents; + + container = new Container(); + + /* contents */ + contents = scm_car(sc, args); + args = scm_cdr(sc, args); + while (contents != sc->NIL) { + + int num; + class ObjectType *type; + pointer entry; + + entry = scm_car(sc, contents); + contents = scm_cdr(sc, contents); + + if (! scm_is_pair(sc, entry)) { + load_err("kern-mk-inventory: error in inv list "\ + "(not a pair)"); + goto abort; + } + + if (unpack(sc, &entry, "dp", &num, &type)) { + load_err("kern-mk-inventory: error in inv list"); + goto abort; + } + + container->add(type, num); + } + + /* hooks */ + if (kern_load_hooks(sc, scm_car(sc, args), container)) { + load_err("kern-mk-inventory: error in hook list"); + goto abort; + } + args = scm_cdr(sc, args); + + return scm_mk_ptr(sc, container); + + abort: + delete container; + return sc->NIL; +} + +KERN_API_CALL(kern_mk_player) +{ + int food, gold, ttnm; + char *mv_desc, *tag; + sound_t *mv_sound; + struct sprite *sprite; + struct terrain_map *campsite; + struct formation *form, *camp_form; + class Container *inventory; + Vehicle *vehicle; + pointer members; + pointer ret; + + if (unpack(sc, &args, "ypspdddppppp", + &tag, + &sprite, + &mv_desc, &mv_sound, + &food, &gold, &ttnm, + &form, &campsite, &camp_form, + &vehicle, + &inventory)) { + load_err("kern-mk-player: bad args"); + return sc->NIL; + } + + if (! inventory) { + load_err("kern-mk-player: nil inventory container"); + return sc->NIL; + } + + //members = scm_car(sc, scm_cdr(sc, args)); + members = scm_car(sc, args); + + player_party = new class PlayerParty(tag, sprite, + mv_desc, + mv_sound, + food, gold, form, + campsite, + camp_form); + player_party->setInventoryContainer(inventory); + player_party->setTurnsToNextMeal(ttnm); + + /* Load the members. */ + while (scm_is_pair(sc, members)) { + + class Character *ch; + + if (unpack(sc, &members, "p", &ch)) { + load_err("kern-mk-player: error in member list"); + goto abort; + } + + if (!ch) { + load_err("kern-mk-player: null member object"); + goto abort; + } + + if (! player_party->addMember(ch)) { + load_err("kern-mk-player: failed to add %s to player " + "party", ch->getName()); + goto abort; + } + } + + /* Board the vehicle */ + if (vehicle) { + + /* This sets the vehicle's occupant, too. */ + player_party->setVehicle(vehicle); + + /* bugfix: party unrefs vehicle when it disembarks; needs to + * keep a refcount while boarded */ + obj_inc_ref(vehicle); + } + + session_add_obj(Session, player_party, player_dtor, player_save, NULL); + ret = scm_mk_ptr(sc, player_party); + scm_define(sc, tag, ret); + return ret; + + abort: + delete player_party; + player_party = 0; + return sc->NIL; +} + +static void sched_dtor(void *data) +{ + sched_del((struct sched *)data); +} + +static void effect_dtor(void *data) +{ + effect_del((struct effect *)data); +} + +static pointer kern_mk_sched(scheme *sc, pointer args) +{ + struct sched *sched; + char *tag; + char *activity; + int n_appts; + int i; + pointer ret; + + /* unpack the tag */ + if (unpack(sc, &args, "y", &tag)) { + load_err("kern-mk-sched: bad args"); + return sc->NIL; + } + + /* count the number of appointments */ + n_appts = scm_len(sc, args); + + /* alloc the schedule */ + sched = sched_new(tag, n_appts); + sched->sc = sc; + + /* loop, adding the appointments to the schedule */ + for (i = 0; i < n_appts; i++) { + struct appt *appt = &sched->appts[i]; + pointer p = scm_car(sc, args); + pointer rect; + args = scm_cdr(sc, args); + + if (unpack(sc, &p, "dd", &appt->hr, &appt->min, &activity)) { + load_err("kern-mk-sched %s: bad args in appt %d time", + tag, i); + goto abort; + } + + rect = scm_car(sc, p); + p = scm_cdr(sc, p); + + if (unpack(sc, &rect, "cdddd", &appt->place_sym, + &appt->x, &appt->y, + &appt->w, &appt->h)) { + load_err("kern-mk-sched %s: bad args in appt %d rect", + tag, i); + goto abort; + } + + if (unpack(sc, &p, "s", &activity)) { + load_err("kern-mk-sched %s: bad args in appt %d activity", + tag, i); + goto abort; + } + + appt->act = sched_name_to_activity(activity); + if (appt->act < 0) { + load_err("kern-mk-sched %d: unknown activity name %s", + tag, activity); + goto abort; + } + } + + session_add(Session, sched, sched_dtor, 0, NULL); + ret = scm_mk_ptr(sc, sched); + scm_define(sc, tag, ret); + return ret; + + abort: + sched_del(sched); + return sc->NIL; +} + +static pointer kern_interp_error(scheme *sc, pointer args) +{ + load_err("interpreter error"); + return sc->NIL; +} + +static pointer kern_include(scheme *sc, pointer args) +{ + char *fname; + + if (unpack(sc, &args, "s", &fname)) { + load_err("kern-include: bad args"); + return sc->NIL; + } + + session_add(Session, strdup(fname), incfile_dtor, incfile_save, NULL); + Session->num_kern_includes++; + return sc->NIL; +} + + +static pointer kern_set_crosshair(scheme *sc, pointer args) +{ + if (unpack(sc, &args, "p", &Session->crosshair_type)) { + load_err("kern-set-crosshair: bad args"); + } + return sc->NIL; +} + + +static pointer kern_set_damage_sprite(scheme *sc, pointer args) +{ + if (unpack(sc, &args, "p", &Session->damage_sprite)) { + load_err("kern-set-damage-sprite: bad args"); + } + return sc->NIL; +} + +static pointer kern_set_clock(scheme *sc, pointer args) +{ + if (unpack(sc, &args, "dddddd", + &Session->clock.year, + &Session->clock.month, + &Session->clock.week, + &Session->clock.day, + &Session->clock.hour, + &Session->clock.min)) { + load_err("kern-set-clock: bad args"); + return sc->NIL; + } + + if (Session->clock.month >= MONTHS_PER_YEAR || + Session->clock.week >= WEEKS_PER_MONTH || + Session->clock.day >= DAYS_PER_WEEK || + Session->clock.hour >= HOURS_PER_DAY || + Session->clock.min >= MINUTES_PER_HOUR) { + load_err("kern-set-clock: invalid time"); + return sc->NIL; + } + + Session->clock.total_minutes = + Session->clock.min + + Session->clock.hour * MINUTES_PER_HOUR + + Session->clock.day * MINUTES_PER_DAY + + Session->clock.week * MINUTES_PER_WEEK + + Session->clock.month * MINUTES_PER_MONTH; + Session->clock.tick_to_change_time = CLOCK_TICKS_PER_MINUTE; + Session->clock.set = 1; + + return sc->NIL; +} + +static pointer kern_obj_apply_damage(scheme *sc, pointer args) +{ + class Object *obj; + char *desc; + int amount; + + if (unpack(sc, &args, "psd", &obj, &desc, &amount)) { + rt_err("kern-obj-inflict-damage: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-inflict-damage: null object"); + return sc->NIL; + } + + obj->damage(amount); + + return sc->NIL; +} + +static pointer kern_obj_inflict_damage(scheme *sc, pointer args) +{ + class Object *obj; + char *desc; + int amount; + class Character *attacker; + + if (unpack(sc, &args, "psdp", &obj, &desc, &amount, &attacker)) { + rt_err("kern-obj-apply-damage: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-apply-damage: null object"); + return sc->NIL; + } + + obj->inflictDamage(amount,attacker); + + return sc->NIL; +} + +static pointer kern_obj_add_effect(scheme *sc, pointer args) +{ + class Object *obj; + struct effect *effect = NULL; + pointer gobcell; + struct gob *gob = NULL; + + if (unpack(sc, &args, "ppl", &obj, &effect, &gobcell)) { + rt_err("kern-obj-add-effect: bad args"); + return sc->F; + } + + if (!obj) { + rt_err("kern-obj-add-effect: null object"); + return sc->F; + } + + if (! is_effect(effect)) { + rt_err("kern-obj-remove-effect: wrong type for effect!"); + return sc->F; + } + + /* Note: even if gobcell is sc->NIL we want to wrap it. I once tried to + * use a NULL gob instead but if we pass that back into scheme as an + * arg and the gc tries to mark it we'll crash. */ + gob = gob_new(sc, gobcell); + gob->flags |= GOB_SAVECAR; + + return obj->addEffect(effect, gob) ? sc->T : sc->F; +} + +static pointer kern_obj_remove_effect(scheme *sc, pointer args) +{ + class Object *obj; + struct effect *effect; + + if (unpack(sc, &args, "pp", &obj, &effect)) { + load_err("kern-obj-remove-effect: bad args"); + return sc->F; + } + + if (!obj) { + rt_err("kern-obj-remove-effect: null object"); + return sc->F; + } + + if (! is_effect(effect)) { + rt_err("kern-obj-remove-effect: wrong type for effect!"); + return sc->F; + } + + /* Just remove one per call */ + return obj->removeEffect(effect) ? sc->T : sc->F; +} + +static pointer kern_print(scheme *sc, pointer args) +{ + while (scm_is_pair(sc, args)) { + + pointer val = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (scm_is_str(sc, val)) { + consolePrint(scm_str_val(sc, val)); + } else if (scm_is_int(sc, val)) { + consolePrint("%d", scm_int_val(sc, val)); + } else if (scm_is_real(sc, val)) { + consolePrint("%f", scm_real_val(sc, val)); + } else { + rt_err("kern-print: bad args"); + } + } + + return sc->NIL; +} + +static pointer kern_log_msg(scheme *sc, pointer args) +{ + log_begin(NULL); + + while (scm_is_pair(sc, args)) { + + pointer val = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (scm_is_str(sc, val)) { + log_continue(scm_str_val(sc, val)); + } else if (scm_is_int(sc, val)) { + log_continue("%d", scm_int_val(sc, val)); + } else if (scm_is_real(sc, val)) { + log_continue("%f", scm_real_val(sc, val)); + } else { + rt_err("kern-log-msg: bad args"); + } + } + + log_end(NULL); + + return sc->NIL; +} + +KERN_API_CALL(kern_log_begin) +{ + log_begin(NULL); + + while (scm_is_pair(sc, args)) { + + pointer val = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (scm_is_str(sc, val)) { + log_continue(scm_str_val(sc, val)); + } else if (scm_is_int(sc, val)) { + log_continue("%d", scm_int_val(sc, val)); + } else if (scm_is_real(sc, val)) { + log_continue("%f", scm_real_val(sc, val)); + } else { + rt_err("kern-log-begin: bad args"); + } + } + + return sc->NIL; +} + +KERN_API_CALL(kern_log_end) +{ + while (scm_is_pair(sc, args)) { + + pointer val = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (scm_is_str(sc, val)) { + log_continue(scm_str_val(sc, val)); + } else if (scm_is_int(sc, val)) { + log_continue("%d", scm_int_val(sc, val)); + } else if (scm_is_real(sc, val)) { + log_continue("%f", scm_real_val(sc, val)); + } else { + rt_err("kern-log-end: bad args"); + } + } + + log_end(NULL); + + return sc->NIL; +} + +static pointer kern_log_continue(scheme *sc, pointer args) +{ + while (scm_is_pair(sc, args)) { + + pointer val = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (scm_is_str(sc, val)) { + log_continue(scm_str_val(sc, val)); + } else if (scm_is_int(sc, val)) { + log_continue("%d", scm_int_val(sc, val)); + } else if (scm_is_real(sc, val)) { + log_continue("%f", scm_real_val(sc, val)); + } else { + rt_err("kern-log-continue: bad args"); + } + } + + return sc->NIL; +} + +KERN_API_CALL(kern_log_flush) +{ + log_flush(); + return sc->T; +} + +static pointer kern_stdout_msg(scheme *sc, pointer args) +{ + + while (scm_is_pair(sc, args)) { + + pointer val = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (scm_is_str(sc, val)) { + fprintf(stdout,"%s",scm_str_val(sc, val)); + } else if (scm_is_int(sc, val)) { + fprintf(stdout,"%ld",scm_int_val(sc, val)); + } else if (scm_is_real(sc, val)) { + fprintf(stdout,"%f",scm_real_val(sc, val)); + } else { + rt_err("kern-print: bad args"); + } + } + fprintf(stdout,"\n"); + + return sc->NIL; +} + +KERN_API_CALL(kern_log_enable) +{ + int val; + + if (unpack(sc, &args, "b", &val)) { + rt_err("kern_log_enable: bad args"); + return sc->F; + } + + if (val) + log_enable(); + else + log_disable(); + + return sc->T; +} + +static pointer kern_conv_say(scheme *sc, pointer args) +{ + class Character *speaker; + struct conv *conv; + + if (unpack(sc, &args, "p", &speaker)) { + rt_err("kern-conv-say: bad args"); + return sc->NIL; + } + + if (speaker == NULL) { + rt_err("kern-conv-say: null speaker"); + return sc->NIL; + } + + if (!(conv = speaker->getConversation())) { + rt_err("%s() no conv for %s", __FUNCTION__, speaker->getName()); + return sc->NIL; + } + + if (speaker->isKnown()) { + log_begin("^c+%c%s:^c- ", CONV_NPC_COLOR, speaker->getName()); + } else { + log_begin("^c+%c", CONV_NPC_COLOR); + speaker->describe(); + log_continue(":^c- "); + } + + args = scm_car(sc, args); + + while (scm_is_pair(sc, args)) { + + pointer val = scm_car(sc, args); + args = scm_cdr(sc, args); + if (scm_is_str(sc, val)) { + char *beg, *end, *text = scm_str_val(sc, val); + while (text) { + if (! conv_get_word(text, &beg, &end)) { + log_continue(text); + text = NULL; + } else { + int keyword = conv_is_keyword(conv, beg); + if (textNIL; +} + +static pointer kern_conv_get_yes_no(scheme *sc, pointer args) +{ + Object *pc = unpack_obj(sc, &args, "kern-conv-get-yes-no?"); + if (NULL == pc) + return sc->F; + return ui_get_yes_no(pc->getName()) ? sc->T : sc->F; +} + +static pointer kern_conv_get_amount(scheme *sc, pointer args) +{ + cmdwin_clear(); + cmdwin_spush("How much"); + return scm_mk_integer(sc, ui_get_quantity(-1)); +} + +static pointer kern_conv_get_reply(scheme *sc, pointer args) +{ + char buf[32]; + + Object *pc = unpack_obj(sc, &args, "kern-conv-get-reply"); + if (NULL == pc) + return sc->F; + + ui_getline(buf, sizeof(buf)); + log_msg("^c+%c%s:^c- %s", CONV_PC_COLOR, pc->getName(), buf); + + /* Return only the first four characters, to be consistent with the + * usual keyword/reply scheme. */ + buf[4] = 0; + + return scm_mk_symbol(sc, buf); +} + +static pointer kern_conv_get_string(scheme *sc, pointer args) +{ + char buf[32]; + + Object *pc = unpack_obj(sc, &args, "kern-conv-get-string"); + if (NULL == pc) + return sc->F; + + ui_getline(buf, sizeof(buf)); + log_msg("%s: %s", pc->getName(), buf); + + return scm_mk_string(sc, buf); +} + +static pointer kern_conv_trade(scheme *sc, pointer args) +{ + Object *npc; + Object *pc; + struct merchant merch; + int i, traded = 0; + char *menu = 0; + pointer catalog = sc->NIL; + + if (unpack(sc, &args, "pps", &npc, &pc, &menu)) { + rt_err("kern-conv-trade: bad args"); + return sc->NIL; + } + + if (! npc || ! pc) { + rt_err("kern-conv-trade: null kernel object(s)"); + return sc->NIL; + } + + /* Get the catalog */ + if (! scm_is_pair(sc, args)) { + rt_err("kern-conv-trade: no catalog!"); + return sc->NIL; + } + catalog = scm_car(sc, args); + args = scm_cdr(sc, args); + if (! scm_is_pair(sc, catalog)) { + rt_err("kern-conv-trade: catalog is not a list"); + return sc->NIL; + } + + /* setup the merchant struct */ + merch.name = npc->getName(); + merch.n_trades = scm_len(sc, catalog); + if (! merch.n_trades) { + rt_err("kern-conv-trade: nothing in trade list"); + return sc->NIL; + } + merch.trades = (struct trade_info*)calloc(merch.n_trades, + sizeof(struct trade_info)); + assert(merch.trades); + + /* fill out the merchant's item list */ + for (i = 0; i < merch.n_trades; i++) { + + ObjectType *type; + pointer p = scm_car(sc, catalog); + struct trade_info *trade = &merch.trades[i]; + catalog = scm_cdr(sc, catalog); + + if (unpack(sc, &p, "pds", &type, &trade->cost, &trade->sales_pitch)) { + rt_err("kern-conv-trade: bad args in trade list %d", i); + goto abort; + } + + if (! type) { + rt_err("kern-conv-trade: null object type in trade list %d", i); + goto abort; + } + + /* This is kind of dumb. We should just point to the ObjectType + * and be done with it. */ + trade->sprite = type->getSprite(); + trade->name = type->getName(); + trade->data = type; + trade->quantity = player_party->inventory->numAvail(type); + trade->show_sprite = 1; + trade->show_quantity = 1; + } + + if (! strcmp(menu, "buy")) { + traded = ui_buy(&merch); + } else if (! strcmp(menu, "sell")) { + traded = ui_sell(&merch); + } else { + traded = ui_trade(&merch); + } + + abort: + free(merch.trades); + return traded ? sc->T : sc->F; +} + +static pointer kern_obj_get_activity(scheme *sc, pointer args) +{ + class Object *obj = unpack_obj(sc, &args, "kern-obj-get-activity"); + if (obj == NULL) + return sc->NIL; + + return scm_mk_string(sc, + sched_activity_to_name(obj->getActivity())); +} + +static pointer kern_obj_set_sprite(scheme *sc, pointer args) +{ + class Object *obj; + struct sprite *sprite; + + if (unpack(sc, &args, "pp", &obj, &sprite)) { + rt_err("kern-obj-set-sprite: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-set-sprite: null object"); + return sc->NIL; + } + + obj->setSprite(sprite); + + return sc->NIL; +} + +static pointer kern_obj_set_opacity(scheme *sc, pointer args) +{ + class Object *obj; + int opacity; + + if (unpack(sc, &args, "pb", &obj, &opacity)) { + rt_err("kern-obj-set-opacity: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-set-opacity: null object"); + return sc->NIL; + } + + obj->setOpacity(opacity != 0); + + return sc->NIL; +} + +static pointer kern_obj_set_ap(scheme *sc, pointer args) +{ + class Object *obj; + int ap; + + if (unpack(sc, &args, "pd", &obj, &ap)) { + rt_err("kern-obj-set-ap: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-set-ap: null object"); + return sc->NIL; + } + + obj->setActionPoints(ap); + + return sc->NIL; +} + +static pointer kern_obj_set_facing(scheme *sc, pointer args) +{ + class Object *obj; + int facing; + + if (unpack(sc, &args, "pd", &obj, &facing)) { + rt_err("kern-obj-set-facing: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-set-facing: null object"); + return sc->NIL; + } + + obj->setFacing(facing); + + return sc->NIL; +} + +static pointer kern_obj_get_facing(scheme *sc, pointer args) +{ + class Object *obj; + + if (unpack(sc, &args, "p", &obj)) { + rt_err("kern-obj-get-facing: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-get-facing: null object"); + return sc->NIL; + } + + return scm_mk_integer(sc, obj->getFacing()); +} + +static pointer kern_obj_set_conv(scheme *sc, pointer args) +{ + class Object *obj; + pointer conv; + + if (unpack(sc, &args, "pc", &obj, &conv)) { + rt_err("kern-obj-set-conv: bad args"); + return sc->NIL; + } + + if (conv == sc->NIL) { + obj->setConversation(NULL); + } else { + kern_load_conv(sc, conv, obj); + } + + return scm_mk_ptr(sc, obj); +} + +static pointer kern_char_set_known(scheme *sc, pointer args) +{ + class Character *ch; + int val; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-set-known"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "b", &val)) { + rt_err("kern-char-set-known: bad args"); + return sc->NIL; + } + + ch->setKnown(val); + return scm_mk_ptr(sc, ch); +} + +static pointer kern_obj_set_visible(scheme *sc, pointer args) +{ + class Object *obj; + int val; + + if (unpack(sc, &args, "pb", &obj, &val)) { + rt_err("kern-obj-set-visible: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-set-visible: null object"); + return sc->NIL; + } + + obj->setVisible(val); + + return scm_mk_ptr(sc, obj); +} + +static pointer kern_obj_set_submerged(scheme *sc, pointer args) +{ + class Object *obj; + int val; + + if (unpack(sc, &args, "pb", &obj, &val)) { + rt_err("kern-obj-set-submerged: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-set-submerged: null object"); + return sc->NIL; + } + + obj->setSubmerged(val); + + return scm_mk_ptr(sc, obj); +} + +static pointer kern_obj_set_pclass(scheme *sc, pointer args) +{ + class Object *obj; + int val; + + if (unpack(sc, &args, "pd", &obj, &val)) { + rt_err("kern-obj-set-pclass: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-set-pclass: null object"); + return sc->NIL; + } + + obj->setPclass(val); + + return sc->NIL; +} + +static pointer kern_obj_get_type(scheme *sc, pointer args) +{ + Object *obj; + + if (!(obj = unpack_obj(sc, &args, "kern-obj-get-type"))) + return sc->NIL; + + return scm_mk_ptr(sc, obj->getObjectType()); +} + +static pointer kern_place_map(scheme *sc, pointer args) +{ + struct place *place; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-map: bad args"); + return sc->NIL; + } + + if (! place || ! place->terrain_map) { + rt_err("kern-place-map: null place or map"); + return sc->NIL; + } + + return scm_mk_ptr(sc, place->terrain_map); +} + +KERN_API_CALL(kern_place_synch) +{ + struct place *place; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-synch: bad args"); + return sc->NIL; + } + + if (! place) { + rt_err("kern-place-synch: null place"); + return sc->NIL; + } + place_synchronize(place); + return sc->NIL; +} + +KERN_API_CALL(kern_place_is_visible) +{ + struct place *place; + int x, y; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern_place_is_visible")) + return sc->NIL; + + if (! place) { + rt_err("kern_place_is_visible: null place"); + return sc->NIL; + } + + // the player party doesnt wind up being in a temporary combat map, + // but by its existance we can infer the player is there + if (!place_is_wilderness_combat(place) && place != player_party->getPlace()) + { + return sc->F; + } + + if (mapTileIsVisible(x,y) && (mapTileLightLevel(x,y) >= MIN_XAMINE_LIGHT_LEVEL)) + { + return sc->T; + } + else + { + return sc->F; + } +} + +KERN_API_CALL(kern_place_is_combat_map) +{ + struct place *place; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern_place_is_combat_map: bad args"); + return sc->NIL; + } + + if (! place) { + rt_err("kern_place_is_combat_map: null place"); + return sc->NIL; + } + + if (place_is_wilderness_combat(place)) + { + return sc->T; + } + else + { + return sc->F; + } +} + +static pointer kern_blit_map(scheme *sc, pointer args) +{ + struct terrain_map *src; + struct terrain_map *dst; + int dst_x; + int dst_y; + int src_x; + int src_y; + int w; + int h; + + if (unpack(sc, &args, "pddpdddd", &dst, &dst_x, &dst_y, + &src, &src_x, &src_y, &w, &h)) { + rt_err("kern-blit-map: bad args"); + return sc->NIL; + } + + if (! dst || ! src) { + rt_err("kern-blit-map: null src or dst map"); + return sc->NIL; + } + + terrain_map_blit(dst, dst_x, dst_y, src, src_x, src_y, w, h); + + vmask_flush_all(); + + + /* Return the modified destination map */ + return scm_mk_ptr(sc, dst); +} + +static pointer kern_map_rotate(scheme *sc, pointer args) +{ + struct terrain_map *map; + int degree; + + if (unpack(sc, &args, "pd", &map, °ree)) { + rt_err("kern-map-rotate: bad args"); + return sc->NIL; + } + + if (! map) { + rt_err("kern-map-rotate: null map"); + return sc->NIL; + } + + terrain_map_rotate(map, degree); + + /* Return the modified map */ + return scm_mk_ptr(sc, map); +} + + +static pointer kern_map_flash_sprite(scheme *sc, pointer args) +{ + int x, y; + struct sprite *sprite; + + if (unpack(sc, &args, "pdd", &sprite, &x, &y)) { + rt_err("kern_map_flash_sprite: bad args"); + return sc->NIL; + } + + if (!sprite) { + rt_err("kern_map_flash_sprite: null sprite"); + return sc->NIL; + } + + if (mapTileLightLevel(x,y) < MIN_XAMINE_LIGHT_LEVEL || (!mapTileIsVisible(x,y))) + { + return sc->NIL; + } + + mapFlashSprite(x, y, sprite); + + return sc->NIL; +} + +static pointer kern_tag(scheme *sc, pointer args) +{ + char *tag; + Object *obj; + pointer p; + + if (unpack(sc, &args, "y", &tag)) { + rt_err("kern-tag: bad args"); + return sc->NIL; + } + + if (! scm_is_pair(sc, args)) { + rt_err("kern-tag %s: no second arg", tag); + return sc->NIL; + } + + p = scm_car(sc, args); + scm_define(sc, tag, p); + + if (unpack(sc, &args, "p", &obj)) { + rt_err("kern-tag: bad object"); + return sc->NIL; + } + + /* Tagged objects may be referred to in the script by their + * tag. If the object is destroyed, the scheme variable that + * refers to the object is still valid (in Scheme, it isn't + * really possible to undefine variables). To prevent crashes + * on dereferencing this variable we'll bump the refcount. To + * ensure the object is destroyed on session teardown, we'll + * mark it for custom finalization, which will decrement the + * extra refcount. */ + obj_inc_ref(obj); + scm_set_cust_fin(sc, p); + + obj->tag = strdup(tag); + assert(obj->tag); + + return p; +} + +static pointer kern_obj_get_gob(scheme *sc, pointer args) +{ + Object *obj; + + if (unpack(sc, &args, "p", &obj)) { + rt_err("kern-obj-get-gob: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-get-gob: null obj"); + return sc->NIL; + } + + if (obj->getGob() == NULL) { + return sc->NIL; + } + + // It's already a scheme pointer so just return it directly + return obj->getGob()->p; +} + +static pointer kern_obj_set_gob(scheme *sc, pointer args) +{ + Object *obj; + + if (! (obj = unpack_obj(sc, &args, "kern-obj-set-gob"))) { + return sc->NIL; + } + + if (! scm_is_pair(sc, args)) { + rt_err("kern-obj-set-gob: no gob specified"); + return sc->NIL; + } + + obj->setGob(gob_new(sc, scm_car(sc, args))); + + return sc->NIL; +} + +static pointer kern_obj_set_ttl(scheme *sc, pointer args) +{ + Object *obj; + int ttl; + + if (! (obj = unpack_obj(sc, &args, "kern-obj-set-ttl"))) { + goto done; + } + + if (unpack(sc, &args, "d", &ttl)) { + rt_err("kern-obj-set-ttl: bad ttl"); + goto done; + } + + Object::setTTL(obj, ttl); + done: + return scm_mk_ptr(sc, obj); +} + +static pointer kern_astral_body_get_gob(scheme *sc, pointer args) +{ + struct astral_body *astral_body; + + if (unpack(sc, &args, "p", &astral_body)) { + rt_err("kern-astral-body-get-gob: bad args"); + return sc->NIL; + } + + if (! astral_body) { + rt_err("kern-astral-body-get-gob: null object"); + return sc->NIL; + } + + if (astral_body->gob == NULL) { + rt_err("kern-astral-body-get-gob: no gob for %s", + astral_body->name); + return sc->NIL; + } + + // It's already a scheme pointer so just return it directly + return astral_body->gob->p; +} + +static pointer kern_astral_body_get_phase(scheme *sc, pointer args) +{ + struct astral_body *astral_body; + + if (unpack(sc, &args, "p", &astral_body)) { + rt_err("kern-astral-body-get-phase: bad args"); + return sc->NIL; + } + + if (! astral_body) { + rt_err("kern-astral-body-get-phase: null object"); + return sc->NIL; + } + + return scm_mk_integer(sc, astral_body->phase); +} + +static pointer kern_astral_body_set_gob(scheme *sc, pointer args) +{ + struct astral_body *astral_body; + + if (unpack(sc, &args, "p", &astral_body)) { + rt_err("kern-astral-body-set-gob: bad args"); + return sc->NIL; + } + + if (! astral_body) { + rt_err("kern-astral-body-set-gob: null object"); + return sc->NIL; + } + + if (! scm_is_pair(sc, args)) { + rt_err("kern-astral-body-set-gob: no gob specified"); + return sc->NIL; + } + + astral_body->gob = (gob_new(sc, scm_car(sc, args))); + + return sc->NIL; +} + +static pointer kern_type_get_gifc(scheme *sc, pointer args) +{ + ObjectType *cptr; + closure_t *gifc; + + if (unpack(sc, &args, "p", &cptr)) { + rt_err("kern-type-get-gifc: bad args"); + return sc->NIL; + } + + if (cptr == NULL) { + /* This is not necessarily an error. Some objects (like + * characters) have no type, which can result in us getting + * here. */ + return sc->NIL; + } + + gifc = cptr->getGifc(); + + return gifc ? gifc->code : sc->NIL; +} + +static pointer kern_type_get_name(scheme *sc, pointer args) +{ + ObjectType *cptr; + + if (unpack(sc, &args, "p", &cptr)) { + rt_err("kern-type-get-name: bad args"); + return sc->NIL; + } + + if (cptr == NULL) { + /* This is not necessarily an error. Some objects (like + * characters) have no type, which can result in us getting + * here. */ + return sc->NIL; + } + + return scm_mk_string(sc, cptr->getName()); +} + +static pointer kern_type_describe(scheme *sc, pointer args) +{ + ObjectType *cptr; + + if (unpack(sc, &args, "p", &cptr)) { + rt_err("kern-type-get-name: bad args"); + return sc->NIL; + } + + if (cptr == NULL) { + /* This is not necessarily an error. Some objects (like + * characters) have no type, which can result in us getting + * here. */ + return sc->NIL; + } + + cptr->describeType(1); + return sc->NIL; +} + +static pointer kern_add_tick_job(scheme *sc, pointer args) +{ + int tick; + pointer proc; + void *data; + + if (unpack(sc, &args, "dop", &tick, &proc, &data)) { + rt_err("kern-add-tick-job: bad args"); + return sc->NIL; + } + + wqCreateJob(&TickWorkQueue, Tick + tick, 0, + kjob_new(data, closure_new(sc, proc)), + kern_run_wq_job); + + return sc->NIL; +} + +static pointer kern_ui_select_party_member(scheme *sc, pointer args) +{ + class Character *member; + + member = select_party_member(); + cmdwin_pop(); + if (! member) { + return sc->NIL; + } + return scm_mk_ptr(sc, member); +} + +static pointer kern_conv_end(scheme *sc, pointer args) +{ + conv_end(); + return sc->T; +} + + +static pointer kern_conv_begin(scheme *sc, pointer args) +{ + class Character *npc, *member; + struct conv *conv; + + if (unpack(sc, &args, "p", &npc)) { + rt_err("kern-conv-begin: bad args"); + return sc->F; + } + + conv = npc->getConversation(); + if (! conv) { + rt_err("kern-conv-begin: npc has no conv!"); + return sc->F; + } + + member = player_party->get_leader(); + if (! member) { + rt_err("kern-conv-begin: no player party leader!"); + return sc->F; + } + + log_begin("You are accosted by "); + Session->subject = player_party; + npc->describe(); + Session->subject = NULL; + log_end("."); + + conv_enter(npc, member, conv); + + return sc->T; +} + +static pointer kern_map_set_dirty(scheme *sc, pointer args) +{ + mapSetDirty(); + return sc->T; +} + +static pointer kern_mk_astral_body(scheme *sc, pointer args) +{ + struct astral_body *body; + char *tag; + char *name; + int minutes_per_phase; + int minutes_per_degree; + int initial_arc; + int initial_phase; + int distance; + pointer proc; + pointer phases; + pointer ret; + int i; + + if (unpack(sc, &args, "ysdddddc", + &tag, + &name, + &distance, + &minutes_per_phase, + &minutes_per_degree, + &initial_arc, + &initial_phase, + &proc)) { + load_err("kern-mk-astral-body: bad args"); + return sc->NIL; + } + + if (! scm_is_pair(sc, args)) { + load_err("kern-mk-astral-body: null phase list"); + return sc->NIL; + } + + phases = scm_car(sc, args); + args = scm_cdr(sc, args); + + body = astral_body_new(tag, name, scm_len(sc, phases)); + body->distance = distance; + body->minutes_per_phase = minutes_per_phase; + body->minutes_per_degree = minutes_per_degree; + body->initial_arc = initial_arc; + body->initial_phase = initial_phase; + body->arc = initial_arc; + body->phase = initial_phase; + + if (proc != sc->NIL) + body->gifc = closure_new_ref(sc, proc); + + i = 0; + while (scm_is_pair(sc, phases)) { + pointer phase = scm_car(sc, phases); + phases = scm_cdr(sc, phases); + char *phase_name = NULL; + + if (unpack(sc, &phase, "pds", + &body->phases[i].sprite, + &body->phases[i].maxlight, + &phase_name)) { + load_err("kern-mk-astral-body: bad args in phase "\ + "list at entry %d", i); + goto abort; + } + if (! phase_name) { + load_err("kern-mk-astral-body %s: null phase name", + body->tag); + goto abort; + } + body->phases[i].name = strdup(phase_name); + assert(body->phases[i].name); + i++; + } + + /* Like types, I define astral bodies in the script so they can be + * referred to by their tags as script variables. I do this because a) + * kern-obj-tag won't work on them, so I need some other way to tag + * them, and b) they are unique enough that it won't hurt to just + * automatically make them variables. */ + sky_add_astral_body(&Session->sky, body); + ret = scm_mk_ptr(sc, body); + scm_define(sc, tag, ret); + + return ret; + + abort: + astral_body_del(body); + return sc->NIL; + +} + +KERN_API_CALL(kern_mk_vehicle_type) +{ + VehicleType *type; + const char *tag = TAG_UNK; + char *name; + struct sprite *sprite; + struct terrain_map *map; + ArmsType *ordnance; + int vulnerable; + int killsOccupants; + int mustTurn; + char *mv_desc; + sound_t *mv_sound; + int tailwind_penalty; + int headwind_penalty; + int crosswind_penalty; + int max_hp; + int speed; + pointer ret; + struct mmode *mmode; + pointer proc; + + if (unpack(sc, &args, "yspppbbbspdddddpo", + &tag, + &name, + &sprite, + &map, + &ordnance, + &vulnerable, + &killsOccupants, + &mustTurn, + &mv_desc, + &mv_sound, + &tailwind_penalty, + &headwind_penalty, + &crosswind_penalty, + &max_hp, + &speed, + &mmode, + &proc + )) { + load_err("kern-mk-vehicle-type %s: bad args", tag); + return sc->NIL; + } + + type = new VehicleType(tag, + name, + sprite, + map, + ordnance, + vulnerable, + killsOccupants, + mustTurn, + mv_desc, + mv_sound, + tailwind_penalty, + headwind_penalty, + crosswind_penalty, + max_hp, + speed + ); + assert(type); + + type->mmode = mmode; + session_add(Session, type, vehicle_type_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, type); + scm_define(sc, tag, ret); + + if (proc != sc->NIL) { + type->renderCombat = closure_new(sc, proc); + closure_ref(type->renderCombat); //TODO clean up this nasty leaky hack + } + else + { + type->renderCombat=NULL; + } + + return ret; +} + +KERN_API_CALL(kern_mk_vehicle) +{ + Vehicle *vehicle; + VehicleType *type; + int facing; + int hp; + + if (unpack(sc, &args, "pdd", &type, &facing, &hp)) { + load_err("kern-mk-vehicle: bad args"); + return sc->NIL; + } + + if (!type) { + load_err("kern-mk-vehicle-type: null type"); + return sc->NIL; + } + + vehicle = new Vehicle(type, facing, hp); + assert(vehicle); + + return scm_mk_ptr(sc, vehicle); +} + +KERN_API_CALL(kern_obj_get_sprite) +{ + Object *obj = unpack_obj(sc, &args, "kern-obj-get-sprite"); + if (!obj) + return sc->NIL; + + return scm_mk_ptr(sc, obj->getSprite()); +} + +KERN_API_CALL(kern_obj_get_light) +{ + Object *obj = unpack_obj(sc, &args, "kern-obj-get-light"); + if (!obj) + return sc->NIL; + + return scm_mk_integer(sc, obj->getLight()); +} + +KERN_API_CALL(kern_obj_get_mmode) +{ + struct mmode *mmode; + + Object *obj = unpack_obj(sc, &args, "kern-obj-get-mmode"); + if (!obj) + return sc->NIL; + + mmode = obj->getMovementMode(); + if (mmode) + return scm_mk_ptr(sc, mmode); + return sc->NIL; +} + +KERN_API_CALL(kern_obj_get_movecost) +{ + class Object *obj; + int val; + + if (unpack(sc, &args, "pd", &obj, &val)) { + rt_err("kern_obj_get_movecost: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern_obj_get_movecost: null object"); + return sc->NIL; + } + + val = obj->getMovementCost(val); + return scm_mk_integer(sc,val); +} + +KERN_API_CALL(kern_obj_get_name) +{ + Object *obj = unpack_obj(sc, &args, "kern-obj-get-name"); + if (!obj) { + return sc->NIL; + } + + if (!obj->getName()) { + return sc->NIL; + } + + return scm_mk_string(sc, obj->getName()); +} + +KERN_API_CALL(kern_obj_set_light) +{ + Object *obj; + int light; + + if (unpack(sc, &args, "pd", &obj, &light)) { + rt_err("kern-obj-set-light: bad args"); + return sc->NIL; + } + + if (!obj) { + rt_err("kern-obj-set-light: null obj"); + return sc->NIL; + } + + obj->setLight(light); + + return sc->NIL; +} + +KERN_API_CALL(kern_sleep) +{ + int msecs; + + if (unpack(sc, &args, "d", &msecs)) { + rt_err("kern-sleep: bad args"); + return sc->F; + } + //usleep(MS_PER_TICK * msecs); + SDL_Delay(msecs); + return sc->T; +} + +KERN_API_CALL(kern_map_view_create) +{ + return scm_mk_ptr(sc, mapCreateView()); +} + + +KERN_API_CALL(kern_map_view_destroy) +{ + struct mview *v = kern_unpack_mview(sc, &args, + "kern-map-view-destroy"); + if (v) + mapDestroyView(v); + return sc->NIL; +} + +KERN_API_CALL(kern_map_view_add) +{ + struct mview *v = kern_unpack_mview(sc, &args, "kern-map-view-add"); + if (v) + mapAddView(v); + return sc->NIL; +} + +KERN_API_CALL(kern_map_view_rm) +{ + struct mview *v = kern_unpack_mview(sc, &args, "kern-map-view-rm"); + if (v) + mapRmView(v); + return sc->NIL; +} + +KERN_API_CALL(kern_map_view_center) +{ + struct place *place; + int x, y; + + struct mview *v = kern_unpack_mview(sc, &args, + "kern-map-view-center"); + if (!v) + return sc->NIL; + + if (! kern_unpack_loc(sc, &args, &place, &x, &y, + "kern-map-view-center")) + return sc->NIL; + + mapSetPlace(place); + mapCenterView(v, x, y); + + return sc->NIL; +} + +KERN_API_CALL(kern_map_center_camera) +{ + struct place *place; + int x, y; + + if (! kern_unpack_loc(sc, &args, &place, &x, &y, + "kern-map-view-center")) + return sc->NIL; + + mapCenterCamera(x, y); + + return sc->NIL; +} + +KERN_API_CALL(kern_map_repaint) +{ + mapUpdate(0); + return sc->NIL; +} + +KERN_API_CALL(kern_map_flash) +{ + int msecs; + if (unpack(sc, &args, "d", &msecs)) { + rt_err("kern-map-flash: bad args"); + return sc->NIL; + } + mapFlash(msecs); + return sc->NIL; +} + +KERN_API_CALL(kern_sound_play) +{ + sound_t *sound; + if (unpack(sc, &args, "p", &sound)) { + rt_err("kern-sound-play: bad args"); + return sc->NIL; + } + sound_play(sound, SOUND_MAX_VOLUME); + return sc->NIL; +} + +//refactor refactor refactor! +KERN_API_CALL(kern_sound_play_at) +{ + sound_t *sound; + struct place *place, *foc_place; + int x, foc_x; + int y, foc_y; + if (unpack(sc, &args, "p", &sound))\ + { + rt_err("kern-sound-play-at: bad args"); + return sc->NIL; + } + if (unpack_loc(sc, &args, &place, &x, &y, "kern-sound-play-at: bad loc")) + { + return sc->NIL; + } + int volume = SOUND_MAX_VOLUME; + int distance; + mapGetCameraFocus(&foc_place, &foc_x, &foc_y); + if (foc_place == place) + { + distance = place_flying_distance(foc_place, foc_x, foc_y, x, y); + if (distance > 1) + volume = (volume * (20 - distance))/20; + if (volume > 0) + { + sound_play(sound, volume, false); + } + } + return sc->NIL; +} + +KERN_API_CALL(kern_sound_play_ambient) +{ + sound_t *sound; + struct place *place, *foc_place; + int x, foc_x; + int y, foc_y; + if (unpack(sc, &args, "p", &sound)) + { + rt_err("kern-sound-play-ambient: bad args"); + return sc->NIL; + } + if (unpack_loc(sc, &args, &place, &x, &y, "kern-sound-play-ambient: bad loc")) + { + return sc->NIL; + } + int volume = SOUND_MAX_VOLUME; + int distance; + mapGetCameraFocus(&foc_place, &foc_x, &foc_y); + if (foc_place == place) + { + distance = place_flying_distance(foc_place, foc_x, foc_y, x, y); + if (distance > 1) + volume = (volume * (20 - distance))/20; + if (volume > 0) + { + sound_play(sound, volume, true); + } + } + return sc->NIL; +} + +KERN_API_CALL(kern_music_play) +{ + char *file; + if (unpack(sc, &args, "s", &file)) + { + rt_err("kern-music-play: bad args"); + return sc->NIL; + } + music_load_track(file); + return sc->NIL; +} + +KERN_API_CALL(kern_set_spell_words) +{ + int i = 0; + pointer words; + pointer word; + + words = args; + + for (i = 0; i < MAX_SPELL_WORDS; i++) { + + /* check for end-of-list */ + if (! scm_is_pair(sc, words)) + break; + + word = scm_car(sc, words); + + /* type-check */ + if (! scm_is_str(sc, word)) { + load_err("kern-set-spell-words: entry %i not a string", + i); + break; + } + + /* copy the word into the global list of words */ + if (magic_add_word(&Session->magic, scm_str_val(sc, word))) { + load_err("kern-set-spell-words: error adding '%s'", + scm_str_val(sc, word)); + } + + words = scm_cdr(sc, words); + } + + return sc->NIL; +} + +KERN_API_CALL(kern_mk_skill) +{ + char *name, *desc; + pointer yuse, can_yuse, list; + struct skill *skill; + int wilderness_ok, passive; + + /* Unpack name and desc */ + if (unpack(sc, &args, "ss", &name, &desc)) { + load_err("kern-mk-skill: bad args"); + return sc->NIL; + } + + skill = skill_new(); + skill_set_name(skill, name); + skill_set_desc(skill, desc); + + /* Unpack ap, mp and yusage procs */ + if (unpack(sc, &args, "ddbbcc", + &skill->ap, + &skill->mp, + &wilderness_ok, + &passive, + &yuse, &can_yuse)) { + load_err("kern-mk-skill %s: bad args", name); + goto abort; + } + + /* I used an int for the unpack since I don't trust the cast to work + * portably on structure bit fields */ + skill->wilderness_ok = wilderness_ok; + skill->passive = passive; + + /* yuse is mandatory for non-passive skills */ + if (! skill->passive + && yuse == sc->NIL) { + load_err("kern-mk-skill %s: active but nil yuse proc", name); + goto abort; + } + + if (yuse != sc->NIL) { + skill->yuse = closure_new_ref(sc, yuse); + } + + /* can_yuse is optional */ + if (can_yuse != sc->NIL) { + skill->can_yuse = closure_new_ref(sc, can_yuse); + } + + /* list of tools */ + list = scm_car(sc, args); + args = scm_cdr(sc, args); + while (scm_is_pair(sc, list)) { + void *objtype; + if (unpack(sc, &list, "p", &objtype)) { + load_err("kern-mk-skill %s: bad tool arg", name); + goto abort; + } + skill_add_tool(skill, objtype); + } + + /* list of materials: (objtype, int) pairs */ + list = scm_car(sc, args); + args = scm_cdr(sc, args); + while (scm_is_pair(sc, list)) { + void *objtype; + int quan; + pointer pair = scm_car(sc, list); + list = scm_cdr(sc, list); + if (unpack(sc, &pair, "pd", &objtype, &quan)) { + load_err("kern-mk-skill %s: bad material arg", name); + goto abort; + } + skill_add_material(skill, objtype, quan); + } + + list_add(&Session->skills, &skill->list); + return scm_mk_ptr(sc, skill); + + abort: + skill_unref(skill); + return sc->NIL; +} + +KERN_API_CALL(kern_mk_skill_set) +{ + char *name; + struct skill_set *skset; + pointer list; + + if (unpack(sc, &args, "s", &name)) { + load_err("kern-mk-skill-set: bad name"); + return sc->NIL; + } + + skset = skill_set_new(); + skill_set_set_name(skset, name); + + list = scm_car(sc, args); + args = scm_cdr(sc, args); + while (scm_is_pair(sc, list)) { + pointer pair; + int lvl; + struct skill *skill; + + pair = scm_car(sc, list); + list = scm_cdr(sc, list); + if (unpack(sc, &pair, "dp", &lvl, &skill)) { + load_err("kern-mk-skill-set %s: bad skill list args", + name); + goto abort; + } + + if (!skill) { + load_err("kern-mk-skill-set %s: nil skill", name); + goto abort; + } + + skill_set_add_skill(skset, skill, lvl); + } + + list_add(&Session->skill_sets, &skset->list); + return scm_mk_ptr(sc, skset); + + abort: + skill_set_unref(skset); + return sc->NIL; +} + +KERN_API_CALL(kern_add_spell) +{ + char *code; + ObjectType *type; + struct spell *spell; + pointer reagents; + + /* Unpack just as far as the word until we can verify that we can add + * this spell. */ + if (unpack(sc, &args, "ps", &type, &code)) { + load_err("kern-add-spell: bad args"); + return sc->NIL; + } + + if (!(spell = magic_add_spell(&Session->magic, code))) { + load_err("kern-add-spell: failed to add %s", + type->getName()); + return sc->NIL; + } + + spell->type = type; + + /* NOTE: unlike other kernel data structures/objects, if we fail we + * don't have to deallocate the spell structure. Nor do we need to + * explicitly add it to the session for teardown later. After + * magic_add_spell() returns the spell structure has already been added + * to the spell tree associated with the session, and will be + * automatically deallocated at end-of-session. */ + + /* unpack remaining fields (other than the reagent list) directly into + * the spell structure. */ + if (unpack(sc, &args, "ddddp", &spell->level, &spell->cost, + &spell->context, &spell->action_points, &spell->sprite)) { + load_err("kern-add-spell: bad args"); + return sc->NIL; + } + + reagents = scm_car(sc, args); + args = scm_cdr(sc, args); + + while (scm_is_pair(sc, reagents)) { + ObjectType *reagent_type; + if (unpack(sc, &reagents, "p", &reagent_type)) { + load_err("kern-add-spell %s: bad arg in reagent list", + spell->type->getName()); + return sc->NIL; + } + if (spell_add_reagent(spell, reagent_type)) { + load_err("kern-add-spell: failed to add reagent %s "\ + "to mixture for spell %s", + reagent_type->getName(), + spell->type->getName()); + return sc->NIL; + } + + } + + return sc->NIL; +} + +KERN_API_CALL(kern_init_random) +{ + /* This should have some timing randomness, + since human interaction is required before scripts run */ + + srand(clock()); + return sc->NIL; +} + +KERN_API_CALL(kern_dice_roll) +{ + static char *dice; + + if (unpack(sc, &args, "s", &dice)) { + rt_err("kern-dice-roll: bad args"); + return scm_mk_integer(sc, 0); + } + + if (!dice_valid(dice)) { + rt_err("kern-dice-roll: bad dice '%s'", dice); + return scm_mk_integer(sc, 0); + } + + return scm_mk_integer(sc, dice_roll(dice)); +} + +KERN_API_CALL(kern_char_set_sleep) +{ + class Character *ch; + int val; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-set-sleep"); + if (!ch) + return sc->F; + + if (unpack(sc, &args, "b", &val)) { + rt_err("kern-char-set-sleep: bad args"); + return sc->F; + } + + if (val) + ch->sleep(); + else + ch->awaken(); + + return sc->T; +} + +KERN_API_CALL(kern_char_force_drop) +{ + class Character *ch; + int val; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-force-drop"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "b", &val)) { + rt_err("kern-char-force-drop: bad args"); + goto done; + } + + ch->setForceContainerDrop(val); + done: + return scm_mk_ptr(sc, ch); +} + +KERN_API_CALL(kern_char_unready) +{ + class Character *ch; + class ArmsType *type; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-unready"); + if (!ch) + return sc->F; + + if (unpack(sc, &args, "p", &type)) { + rt_err("kern-char-unready: bad args"); + return sc->F; + } + + return ch->unready(type) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_char_get_readied_weapons) +{ + class Character *ch; + class ArmsType *weapon; + pointer head = sc->NIL; + pointer tail = sc->NIL; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-unready"); + if (!ch) + return sc->F; + + int armsIndex = 0; + for (weapon = ch->enumerateWeapons(&armsIndex); weapon != NULL; + weapon = ch->getNextWeapon(&armsIndex)) { + + /* skip "natural" weapons that are not really readied */ + if (ch->species && + weapon == ch->species->weapon) + continue; + + pointer cell = scm_mk_ptr(sc, weapon); + cell = _cons(sc, cell, sc->NIL, 0); + + if (head == sc->NIL) { + head = cell; + tail = cell; + } else { + tail->_object._cons._cdr = cell; + tail = cell; + } + } + + return head; +} + +KERN_API_CALL(kern_char_set_hp) +{ + class Character *ch; + int val; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-set-hp"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-set-hp: bad args"); + } else { + ch->setHp(val); + } + + return scm_mk_ptr(sc, ch);; +} + +KERN_API_CALL(kern_char_set_mana) +{ + class Character *ch; + int val; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-set-mana"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-set-mana: bad args"); + } else { + ch->setMana(val); + } + + return scm_mk_ptr(sc, ch);; +} + +KERN_API_CALL(kern_char_set_schedule) +{ + class Character *ch; + struct sched *val; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-set-schedule"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "p", &val)) { + rt_err("kern-char-set-schedule: bad args"); + } else { + ch->setSchedule(val); + } + + return scm_mk_ptr(sc, ch); +} + +/* + * kern_char_join_player -- wrapper for Character::joinPlayer + */ +KERN_API_CALL(kern_char_join_player) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-join-player"); + if (!ch) + return sc->F; + + if (ch->joinPlayer()) + return sc->T; + return sc->F; +} + +KERN_API_CALL(kern_char_is_known) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-is-known"); + if (!ch) { + return sc->F; + } + + return ch->isKnown() ? sc->T : sc->F; +} + +KERN_API_CALL(kern_char_leave_player) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-leave-player"); + if (!ch) + return sc->F; + + if (NULL==ch->getPlace() + || place_is_wilderness(ch->getPlace())) + return sc->F; + + ch->leavePlayer(); + + return sc->T; +} + +/* + * kern_char_set_ai -- change the AI for a Character object + */ +KERN_API_CALL(kern_char_set_ai) +{ + class Character *ch; + pointer ai; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-set-ai"); + if (!ch) + return sc->F; + + if (unpack(sc, &args, "c", &ai)) { + rt_err("kern-char-set-ai: bad args"); + return sc->F; + } + + if (ai == sc->NIL) { + ch->setAI(NULL); + } else { + ch->setAI(closure_new(sc, ai)); + } + + return sc->T; +} + +KERN_API_CALL(kern_char_task_abort) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-task-abort"); + if (ch) { + ch->taskAbort(); + } + return sc->NIL; +} + +KERN_API_CALL(kern_char_task_begin) +{ + char *taskname = NULL; + class Character *ch; + pointer taskproc, taskgob; + struct closure *closure = NULL; + struct gob *gob = NULL; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-task-begin"); + if (!ch) { + return sc->F; + } + + if (unpack(sc, &args, "scl", &taskname, &taskproc, &taskgob)) { + rt_err("%s: bad args", __FUNCTION__); + return sc->F; + } + + if (taskproc == sc->NIL) { + rt_err("%s: nil task procedure not allowed", __FUNCTION__); + return sc->F; + } + + /* For now, disallow starting tasks in the wilderness. Maybe later. */ + if (place_is_wilderness(ch->getPlace())) { + return sc->F; + } + + if (!(closure = closure_new_ref(sc, taskproc))) { + return sc->F; + } + + /* gob is optional */ + if (taskgob != sc->NIL) { + if (!(gob = gob_new(sc, taskgob))) { + closure_unref(closure); + return sc->F; + } + } + + ch->taskBegin(taskname, closure, gob); + closure_unref(closure); + + return sc->T; +} + +KERN_API_CALL(kern_char_task_continue) +{ + char *taskname = NULL; + class Character *ch; + pointer taskproc, taskgob; + struct closure *closure = NULL; + struct gob *gob = NULL; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-task-continue"); + if (!ch) { + return sc->F; + } + + if (unpack(sc, &args, "scl", &taskname, &taskproc, &taskgob)) { + rt_err("%s: bad args", __FUNCTION__); + return sc->F; + } + + if (taskproc == sc->NIL) { + return sc->F; + } + + if (!(closure = closure_new_ref(sc, taskproc))) { + return sc->F; + } + + /* gob is optional */ + if (taskgob != sc->NIL) { + if (!(gob = gob_new(sc, taskgob))) { + closure_unref(closure); + return sc->F; + } + } + + ch->taskContinue(taskname, closure, gob); + closure_unref(closure); + + return sc->T; +} + +KERN_API_CALL(kern_char_task_end) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-task-end"); + if (ch) { + ch->taskEnd(); + } + return sc->NIL; +} + + +KERN_API_CALL(kern_char_set_sched) +{ + class Character *ch; + struct sched *sched = 0; + + if (unpack(sc, &args, "pp", &ch, &sched)) { + rt_err("kern-char-set-sched: bad args"); + return sc->NIL; + } + + if (!ch) { + rt_err("kern-char-set-sched: null object"); + return sc->NIL; + } + + ch->setSchedule(sched); + + return sc->T; +} + +KERN_API_CALL(kern_char_set_control_mode) +{ + static struct { const char *str; enum control_mode mode; } tbl[] = { + { "auto", CONTROL_MODE_AUTO }, + { "player", CONTROL_MODE_PLAYER }, + { "idle", CONTROL_MODE_IDLE }, + { "follow", CONTROL_MODE_FOLLOW } + }; + class Character *ch; + char *modestr = 0; + int i; + + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-set-control-mode"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "s", &modestr)) { + rt_err("kern-char-set-control-mode: bad args"); + return sc->NIL; + } + + for (i = 0; i < array_sz(tbl); i++) { + if (! strcmp(tbl[i].str, modestr)) { + ch->setControlMode(tbl[i].mode); + return sc->NIL; + } + } + + return sc->NIL; +} + +KERN_API_CALL(kern_char_attack) +{ + class Character *attacker, *defender; + class ArmsType *weapon; + + if (unpack(sc, &args, "ppp", &attacker, &weapon, &defender)) { + rt_err("kern-char-attack: bad args"); + return sc->F; + } + + if (! attacker) { + rt_err("kern-char-attack: null attacker"); + return sc->F; + } + + if (! weapon) { + rt_err("kern-char-attack: null weapon"); + return sc->F; + } + + if (! defender) { + rt_err("kern-char-attack: null defender"); + return sc->F; + } + + ctrl_do_attack(attacker, weapon, defender, + attacker->getToHitPenalty()); + + attacker->decActionPoints(weapon->getRequiredActionPoints()); + + return sc->T; +} + +KERN_API_CALL(kern_char_is_asleep) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-is-asleep"); + if (!ch) + return sc->F; + + return ch->isAsleep() ? sc->T : sc->F; +} + +KERN_API_CALL(kern_char_is_dead) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-is-dead"); + if (!ch) + return sc->T; + + return ch->isDead() ? sc->T : sc->F; +} + +KERN_API_CALL(kern_mk_effect) +{ + struct effect *effect; + pointer exec_proc = sc->NIL; + pointer apply_proc = sc->NIL; + pointer rm_proc = sc->NIL; + pointer restart_proc = sc->NIL; + void *sprite; + pointer ret; + char *name, *tag = 0; + int hook_id; + + if (unpack(sc, &args, "yspccccd", &tag, &name, &sprite, &exec_proc, + &apply_proc, &rm_proc, &restart_proc, &hook_id)) { + load_err("kern-mk-effect %s: bad args", tag); + return sc->NIL; + } + + if (exec_proc == sc->NIL) + exec_proc = NULL; + + if (apply_proc == sc->NIL) + apply_proc = NULL; + + if (rm_proc == sc->NIL) + rm_proc = NULL; + + if (restart_proc == sc->NIL) + restart_proc = NULL; + + effect = effect_new(tag, sc, exec_proc, apply_proc, rm_proc, + restart_proc, name); + + effect->hook_id = hook_id; + effect->sprite = (struct sprite*)sprite; + + if (unpack(sc, &args, "dbd", &effect->detect_dc, + &effect->cumulative, &effect->duration)) { + load_err("kern-mk-effect %s: bad args", tag); + goto abort; + } + + session_add(Session, effect, effect_dtor, NULL, NULL); + ret = scm_mk_ptr(sc, effect); + scm_define(sc, tag, ret); + + return ret; + + abort: + effect_del(effect); + return sc->NIL; +} + +/* kern_ui_target_visitor - build a suggested list of targets from all beings + * in range. */ +static void kern_ui_target_visitor(class Object *obj, void *data) +{ + struct kern_ui_target_info *info = (struct kern_ui_target_info*)data; + class Character *npc = 0; + int dist = 0; + struct location_list *entry = 0; + + if (being_layer!=obj->getLayer()) + return; + + npc = (class Character*)obj; + + if (! npc->isVisible() && ! Reveal) + return; + + dist = place_flying_distance(info->place, + info->x, + info->y, + obj->getX(), + obj->getY()); + if (dist > info->range) + return; + + /* Add it to the list */ + entry = (struct location_list*)malloc(sizeof(*entry)); + assert(entry); + entry->x = obj->getX(); + entry->y = obj->getY(); + list_add_tail(&info->suggest, &entry->list); +} + +/* kern_ui_target_cleanup_info - free the suggest list. */ +static void kern_ui_target_cleanup_info(struct kern_ui_target_info *info) +{ + struct list *head = &info->suggest; + struct list *entry = head->next; + while (entry != head) { + struct location_list *tmp = + (struct location_list*)entry; + entry = entry->next; + list_remove(&tmp->list); + free(tmp); + } +} + +KERN_API_CALL(kern_ui_target) +{ + struct place *place; + int ox, oy, tx, ty, range; + struct kern_ui_target_info info; + pointer ret; + + /* Unpack the origin */ + if (unpack_loc(sc, &args, &place, &ox, &oy, "kern-ui-target")) { + return sc->NIL; + } + + /* Unpack the range */ + if (unpack(sc, &args, "d", &range)) { + rt_err("kern-ui-target: bad range arg"); + return sc->NIL; + } + + /* Build a list of suggested targets. */ + memset(&info, 0, sizeof(info)); + info.place = Place; + info.x = ox; + info.y = oy; + info.range = range; + list_init(&info.suggest); + place_for_each_object(Place, + kern_ui_target_visitor, + &info); + + + /* Get the target coords from the user */ + tx = ox; + ty = oy; + if (select_target(ox, oy, &tx, &ty, range, &info.suggest)) { + ret = sc->NIL; + } + + /* Pack the target coords for return */ + else { + ret = pack(sc, "pdd", place, tx, ty); + } + + kern_ui_target_cleanup_info(&info); + return ret; +} + +static int kern_mk_templ_visitor(struct templ *templ, int x, int y, void *data) +{ + closure_t *check = (closure_t*)data; + + /* if the check proc returns #f then turn off this location in the + * template */ + if (! closure_exec(check, "dd", x, y)) { + templ_set(templ, x, y, 0); + } + + return 0; +} + +KERN_API_CALL(kern_mk_templ) +{ + int rad, x, y; + struct place *place; + pointer checkptr; + struct templ *templ; + closure_t *checkproc; + + /* origin */ + if (unpack_loc(sc, &args, &place, &x, &y, "kern-mk-templ")) { + return sc->NIL; + } + + /* radius, check-proc and gob */ + if (unpack(sc, &args, "dc", &rad, &checkptr)) { + rt_err("kern-mk-templ: bad args"); + return sc->NIL; + } + + /* create the templ and set its origin */ + templ = templ_new_from_range(rad); + templ_set_origin(templ, x, y); + + /* run the check procedure on each location covered by the templ */ + checkproc = closure_new_ref(sc, checkptr); + templ_for_each(templ, kern_mk_templ_visitor, checkproc); + closure_unref(checkproc); + + return scm_mk_ptr(sc, templ); +} + +KERN_API_CALL(kern_ui_target_generic) +{ + ui_select_target_req_t req; + pointer move_cb, select_cb, gob, dummy; + + ui_select_target_req_init(&req); + + /* Unpack the origin */ + if (unpack_loc(sc, &args, &req.place, &req.x1, &req.y1, + "kern-ui-target-generic")) { + return sc->NIL; + } + + /* Unpack the initial cursor loc */ + if (unpack_loc(sc, &args, &req.place, &req.x2, &req.y2, + "kern-ui-target-generic")) { + return sc->NIL; + } + + /* Unpack the template */ + if (unpack(sc, &args, "p", &req.tiles)) { + rt_err("kern-ui-target-generic: bad template arg"); + return sc->NIL; + } + + /* fixme: unpack the suggested list */ + if (unpack(sc, &args, "p", &dummy)) { + rt_err("kern-ui-target-generic: bad template arg"); + return sc->NIL; + } + + /* unpack the move-cb, select-cb and gob */ + if (unpack(sc, &args, "ccc", &move_cb, &select_cb, &gob)) { + rt_err("kern-ui-target-generic: bad callback or gob arg"); + return sc->NIL; + } + + /* fixme: convert the cb procs into closures (will have to clean them + * up at the bottom, too) */ + + /* Prompt the player; returns when player has made selection */ + if (ui_select_target_generic(&req)) { + return sc->NIL; + } + + /* Kind of a hack: manually unref the templ here, assuming the caller + * is done with it, which is going to be the usual case. If I encounter + * an unusual case then I'll need to add kern-templ-ref/unref so the + * script can protect it. */ + if (req.tiles) { + templ_unref(req.tiles); + } + + /* Pack the target coords for return */ + return pack(sc, "pdd", req.place, req.x2, req.y2); +} + +KERN_API_CALL(kern_fire_missile) +{ + MissileType *missile_type; + Missile *missile; + struct place *oplace, *dplace; + int ox, oy, dx, dy, hitTarget = 0; + + /* Unpack the missile type */ + if (unpack(sc, &args, "p", &missile_type)) { + rt_err("kern-fire-missile: bad missile type arg"); + return sc->NIL; + } + if (! missile_type) { + rt_err("kern-fire-missile: null missile type"); + return sc->NIL; + } + + /* Unpack the origin */ + if (unpack_loc(sc, &args, &oplace, &ox, &oy, "kern-fire-missile")) + return sc->NIL; + + /* Unpack the destination */ + if (unpack_loc(sc, &args, &dplace, &dx, &dy, "kern-fire-missile")) + return sc->NIL; + + /* Create the missile */ + missile = new Missile(missile_type); + assert(missile); + + /* Fire the missile */ + missile->setPlace(dplace); + missile->animate(ox, oy, &dx, &dy, 0, 0); + hitTarget = missile->hitTarget(); + missile->fireHitLoc(NULL, NULL, oplace,dx,dy,-1); + delete missile; + return hitTarget ? sc->T : sc->F; +} + + +KERN_API_CALL(kern_fire_missile_to_max) +{ + MissileType *missile_type; + Missile *missile; + struct place *oplace, *dplace; + int ox, oy, dx, dy, hitTarget = 0; + int range; + + /* Unpack the missile type */ + if (unpack(sc, &args, "pd", &missile_type, &range)) { + rt_err("kern-fire-missile-to-max: bad missile type arg"); + return sc->NIL; + } + if (! missile_type) { + rt_err("kern-fire-missile-to-max: null missile type"); + return sc->NIL; + } + + /* Unpack the origin */ + if (unpack_loc(sc, &args, &oplace, &ox, &oy, "kern-fire-missile-to-max")) + return sc->NIL; + + /* Unpack the destination */ + if (unpack_loc(sc, &args, &dplace, &dx, &dy, "kern-fire-missile-to-max")) + return sc->NIL; + + /* Create the missile */ + missile = new Missile(missile_type); + assert(missile); + + /* Fire the missile */ + missile->setPlace(dplace); + missile->animate(ox, oy, &dx, &dy, 0, range); + hitTarget = missile->hitTarget(); + missile->fireHitLoc(NULL, NULL, oplace,dx,dy,-1); + delete missile; + return hitTarget ? sc->T : sc->F; +} + +KERN_API_CALL(kern_obj_inc_light) +{ + int light; + + Object *obj = unpack_obj(sc, &args, "kern-obj-inc-light"); + if (!obj) + return sc->F; + + if (unpack(sc, &args, "d", &light)) { + rt_err("kern-obj-inc-light: bad args"); + return sc->F; + } + + obj->setLight(obj->getLight() + light); + + return sc->T; +} + +KERN_API_CALL(kern_obj_dec_light) +{ + int light; + + Object *obj = unpack_obj(sc, &args, "kern-obj-dec-light"); + if (!obj) + return sc->F; + + if (unpack(sc, &args, "d", &light)) { + rt_err("kern-obj-dec-light: bad args"); + return sc->F; + } + + obj->setLight(obj->getLight() - light); + + return sc->T; +} + +KERN_API_CALL(kern_obj_dec_ap) +{ + int val; + + Object *obj = unpack_obj(sc, &args, "kern-obj-add-ap"); + if (!obj) + return sc->F; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-obj-add-ap: bad args"); + return sc->F; + } + + obj->decActionPoints(val); + + return sc->T; +} + +KERN_API_CALL(kern_place_is_wilderness) +{ + struct place *place; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-is-wilderness: bad args"); + return sc->F; + } + + if (!place) { + rt_err("kern-place-is-wilderness: null place"); + return sc->F; + } + + return place_is_wilderness(place) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_place_is_wrapping) +{ + struct place *place; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-is-wrapping: bad args"); + return sc->F; + } + + if (!place) { + rt_err("kern-place-is-wrapping: null place"); + return sc->F; + } + + return place_is_wrapping(place) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_obj_heal) +{ + Object *obj; + int val; + + obj = unpack_obj(sc, &args, "kern-obj-heal"); + if (!obj) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-obj-heal: bad args"); + return sc->NIL; + } + + obj->heal(val); + + return sc->T; +} + +static int kern_filter_being(Object *obj, struct kern_append_info *info) +{ + return (obj->getLayer() == being_layer); +} + +static int kern_filter_visible_hostile(Object *obj, + struct kern_append_info *info) +{ + class Being *subj; + + /* Extract a pointer to the subject looking for hostiles */ + subj = (class Being *)info->data; + + /* Filter out non-beings */ + if (obj->getLayer() != being_layer) + return 0; + + /* Filter out non-hostiles */ + if (! are_hostile(subj, (class Being*)obj)) + return 0; + + /* Filter out objects not in los of the subject */ + if (! place_in_los(subj->getPlace(),subj->getX(),subj->getY(), + obj->getPlace(),obj->getX(),obj->getY())) + return 0; + + /* Filter out object not in the vision radius of the subject */ + if (place_flying_distance(subj->getPlace(),subj->getX(),subj->getY(), + obj->getX(),obj->getY()) + > subj->getVisionRadius()) + return 0; + + /* Filter out invisible objects */ + if (! obj->isVisible()) + return 0; + + return 1; +} + +static int kern_filter_visible_allies(Object *obj, + struct kern_append_info *info) +{ + class Being *subj; + + /* Extract a pointer to the subject looking for hostiles */ + subj = (class Being *)info->data; + + /* Filter out non-beings */ + if (obj->getLayer() != being_layer) + return 0; + + /* Filter out non-allies */ + if (! are_allies(subj, (class Being*)obj)) + return 0; + + /* Filter out objects not in los of the subject */ + if (! place_in_los(subj->getPlace(),subj->getX(),subj->getY(), + obj->getPlace(),obj->getX(),obj->getY())) + return 0; + + /* Filter out object not in the vision radius of the subject */ + if (place_flying_distance(subj->getPlace(),subj->getX(),subj->getY(), + obj->getX(),obj->getY()) + > subj->getVisionRadius()) + return 0; + + /* Filter out invisible objects */ + if (! obj->isVisible()) + return 0; + + return 1; +} + +static void kern_append_object(Object *obj, void *data) +{ + pointer cell; + struct kern_append_info *info; + + info = (struct kern_append_info *)data; + + /* If there is a filter then use it */ + if (info->filter != NULL) + + /* If the filter rejects the object then don't append it */ + if (! info->filter(obj, info)) + return; + + cell = scm_mk_ptr(info->sc, obj); + cell = _cons(info->sc, cell, info->sc->NIL, 0); + + if (info->head == info->sc->NIL) { + info->head = cell; + info->tail = cell; + + /* Protect the list from gc until we can return to scheme */ + scm_protect(info->sc, cell); + } else { + info->tail->_object._cons._cdr = cell; + info->tail = cell; + } +} + +static pointer scm_mk_loc(scheme *sc, struct place *place, int x, int y) +{ + return pack(sc, "pdd", place, x, y); +} + +static pointer +kern_place_for_each_object_at(scheme *sc, struct place *place, int x, int y, + int (*filter)(Object *, + struct kern_append_info *), + void *data) +{ + struct kern_append_info info; + + /* initialize the context used by the callback to append objects */ + info.sc = sc; + info.head = sc->NIL; + info.tail = sc->NIL; + info.filter = filter; + info.data = data; + + /* build a scheme list of the objects at that location */ + place_for_each_object_at(place, x, y, kern_append_object, &info); + + /* unprotect the list prior to return */ + if (info.head != sc->NIL) + scm_unprotect(sc, info.head); + + /* return the scheme list */ + return info.head; + +} + +static pointer +kern_place_for_each_object(scheme *sc, struct place *place, + int (*filter)(Object *, struct kern_append_info *), + void *data) +{ + struct kern_append_info info; + + /* initialize the context used by the callback to append objects */ + info.sc = sc; + info.head = sc->NIL; + info.tail = sc->NIL; + info.filter = filter; + info.data = data; + + /* build a scheme list of the objects at that location */ + place_for_each_object(place, kern_append_object, &info); + + /* unprotect the list prior to return */ + if (info.head != sc->NIL) + scm_unprotect(sc, info.head); + + /* return the scheme list */ + return info.head; + +} + + +KERN_API_CALL(kern_get_objects_at) +{ + struct place *place; + int x, y; + + /* unpack the location */ + if (unpack_loc(sc, &args, &place, &x, &y, "kern-get-objects-at")) + return sc->NIL; + + /* get all objects with no filtering */ + return kern_place_for_each_object_at(sc, place, x, y, NULL, NULL); +} + +KERN_API_CALL(kern_obj_is_char) +{ + /* OBSOLETE! Use kern-obj-is-being */ + Object *obj; + + obj = unpack_obj(sc, &args, "kern-obj-is-char?"); + if (!obj) + return sc->F; + + return (obj->getLayer() == being_layer) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_obj_is_container) +{ + Object *obj; + + obj = unpack_obj(sc, &args, "kern-obj-is-container?"); + if (!obj) + return sc->F; + + return (obj->getLayer() == container_layer) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_obj_is_field) +{ + Object *obj; + + obj = unpack_obj(sc, &args, "kern-obj-is-field?"); + if (!obj) + return sc->F; + + return (obj->getLayer() == field_layer) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_obj_is_being) +{ + Object *obj; + + obj = unpack_obj(sc, &args, "kern-obj-is-being?"); + if (!obj) + return sc->F; + + return (obj->getLayer() == being_layer) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_obj_is_mech) +{ + Object *obj; + + obj = unpack_obj(sc, &args, "kern-obj-is-mech?"); + if (!obj) + return sc->F; + + return (obj->getLayer() == mech_layer) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_obj_is_visible) +{ + Object *obj; + + obj = unpack_obj(sc, &args, "kern-obj-is-visible?"); + if (!obj) + return sc->F; + + return obj->isVisible() ? sc->T : sc->F; +} + +KERN_API_CALL(kern_obj_is_submerged) +{ + Object *obj; + + obj = unpack_obj(sc, &args, "kern-obj-is-submerged?"); + if (!obj) + return sc->F; + + return obj->isSubmerged() ? sc->T : sc->F; +} + +KERN_API_CALL(kern_char_set_fleeing) +{ + int val; + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-set-fleeing"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "b", &val)) { + rt_err("kern-char-set-fleeing: bad args"); + return sc->NIL; + } + + ch->setFleeing(val); + + return sc->NIL; + +} + +KERN_API_CALL(kern_char_set_player_controlled) +{ + int val; + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-set-player-controlled"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "b", &val)) { + rt_err("kern-char-set-player-controlled: bad args"); + return sc->NIL; + } + + ch->setPlayerControlled(val); + + return sc->NIL; + +} + +KERN_API_CALL(kern_char_get_species) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-get-species"); + if (!ch) + return sc->NIL; + + return scm_mk_ptr(sc, ch->species); +} + +KERN_API_CALL(kern_char_get_occ) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-get-occ"); + if (!ch || ! ch->occ) + return sc->NIL; + + return scm_mk_ptr(sc, ch->occ); +} + +KERN_API_CALL(kern_char_get_mana) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-get-mana"); + if (!ch) + return sc->NIL; + + return scm_mk_integer(sc, ch->getMana()); +} + +KERN_API_CALL(kern_place_get_beings) +{ + struct place *place; + + /* unpack the place */ + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-get-beings: bad args"); + return sc->NIL; + } + if (! place) { + rt_err("kern-place-get-beings: null place"); + return sc->NIL; + } + + return kern_place_for_each_object(sc, place, kern_filter_being, NULL); +} + +KERN_API_CALL(kern_being_get_visible_hostiles) +{ + Object *subj; + + /* Unpack the subject */ + subj = unpack_obj(sc, &args, "kern-place-get-visible-hostiles"); + if (!subj) + return sc->NIL; + + if (! subj->getPlace()) { + rt_err("kern-place-get-visible-hostiles: null place"); + return sc->NIL; + } + + return kern_place_for_each_object(sc, subj->getPlace(), + kern_filter_visible_hostile, + subj); +} + +KERN_API_CALL(kern_being_get_visible_allies) +{ + Object *subj; + + /* Unpack the subject */ + subj = unpack_obj(sc, &args, "kern-place-get-visible-allies"); + if (!subj) + return sc->NIL; + + if (! subj->getPlace()) { + rt_err("kern-place-get-visible-allies: null place"); + return sc->NIL; + } + + return kern_place_for_each_object(sc, subj->getPlace(), + kern_filter_visible_allies, + subj); +} + +KERN_API_CALL(kern_being_get_visible_tiles) +{ + Object *subj; + struct place *place; + int ox, oy, vr; + pointer head = sc->NIL; + pointer tail = sc->NIL; + pointer cell; + + /* Unpack the subject */ + subj = unpack_obj(sc, &args, "kern-being-get-visible-tiles"); + if (!subj) + return sc->NIL; + + place = subj->getPlace(); + if (! place) { + rt_err("kern-being-get-visible-tiles: null place"); + return sc->NIL; + } + + ox = subj->getX(); + oy = subj->getY(); + vr = subj->getVisionRadius(); + + for (int y = 0; y < place_h(place); y++) { + for (int x = 0; x < place_w(place); x++) { + + /* Filter out tiles not in los of the subject */ + if (! place_in_los(place, ox, oy, place, x, y)) + continue; + + /* Filter out tiles not in the vision radius of the + * subject */ + if (place_flying_distance(place, ox, oy, x, y) > vr) + continue; + + /* else append this location to the list */ + cell = scm_mk_loc(sc, place, x, y); + cell = _cons(sc, cell, sc->NIL, 0); + + if (head == sc->NIL) { + head = cell; + tail = cell; + scm_protect(sc, cell); + } else { + tail->_object._cons._cdr = cell; + tail = cell; + } + } + } + + /* unprotect the list prior to returning */ + if (head != sc->NIL) + scm_unprotect(sc, head); + + return head; +} + +KERN_API_CALL(kern_place_get_objects) +{ + struct place *place; + + /* unpack the place */ + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-get-objects: bad args"); + return sc->NIL; + } + if (! place) { + rt_err("kern-place-get-objects: null place"); + return sc->NIL; + } + + return kern_place_for_each_object(sc, place, NULL, NULL); +} + + +/* struct kern_place_get_objects_in_los_info { */ +/* struct kern_append_info ap_info; */ +/* struct place *place; */ +/* int ox; /\* looker's x *\/ */ +/* int oy; /\* looker's y *\/ */ +/* int rad; /\* looke r's rad *\/ */ +/* int vx; /\* vmask ulc x *\/ */ +/* int vy; /\* vmask ulc y *\/ */ +/* char *vmask; */ +/* }; */ + +/* static void kern_place_get_objects_in_los_cb(Object *obj, void *data) */ +/* { */ +/* struct kern_place_get_objects_in_los_info *info; */ +/* int x, y; */ + +/* info = (struct kern_place_get_objects_in_los_info *)data; */ + +/* /\* check if the object is within vision radius *\/ */ +/* if (place_flying_distance(info->place, */ +/* info->ox, */ +/* info->oy, */ +/* obj->getX(), */ +/* obj->getY()) */ +/* > info->rad) { */ +/* return; */ +/* } */ + +/* /\* translate the object's coordinates into coordinates offset from the */ +/* * upper left corner of the vmask region *\/ */ +/* x = obj->getX() - info->vx; */ +/* y = obj->getY() - info->vy; */ + +/* /\* check if the object is outside the vmask *\/ */ +/* if (x < 0 || */ +/* y < 0 || */ +/* x >= VMASK_W || */ +/* y >= VMASK_H) */ +/* return; */ + +/* /\* if the object's tile is marked as visible then add it to the list *\/ */ +/* if (info->vmask[y * VMASK_W + x]) */ +/* kern_append_object(obj, &info->ap_info); */ +/* } */ + +/* KERN_API_CALL(kern_place_get_objects_in_los) */ +/* { */ +/* class Object *obj; */ +/* struct kern_place_get_objects_in_los_info info; */ + +/* obj = unpack_obj(sc, &args, "kern-place-get-objects-in-los"); */ +/* if (! obj) */ +/* return sc->NIL; */ + +/* if (! obj->getPlace()) { */ +/* rt_err("kern-place-get-object-in-los: obj has null place"); */ +/* return sc->NIL; */ +/* } */ + +/* /\* initialize the context used by the callback to append objects *\/ */ +/* info.ap_info.sc = sc; */ +/* info.ap_info.head = sc->NIL; */ +/* info.ap_info.tail = sc->NIL; */ +/* info.place = obj->getPlace(); */ +/* info.ox = obj->getX(); */ +/* info.oy = obj->getY(); */ +/* info.rad = obj->getVisionRadius(); */ +/* info.vx = obj->getX() - VMASK_W / 2; */ +/* info.vy = obj->getY() - VMASK_H / 2; */ +/* info.vmask = vmask_get(obj->getPlace(), */ +/* obj->getX(), */ +/* obj->getY()); */ + +/* /\* build a scheme list of the objects *\/ */ +/* place_for_each_object(obj->getPlace(), */ +/* kern_place_get_objects_in_los_cb, &info); */ + +/* /\* return the scheme list *\/ */ +/* return info.ap_info.head; */ +/* } */ + +KERN_API_CALL(kern_place_get_name) +{ + struct place *place; + + /* unpack the place */ + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-get-name: bad args"); + return sc->NIL; + } + if (! place) { + rt_err("kern-place-get-name: null place"); + return sc->NIL; + } + + return scm_mk_string(sc, place->name); +} + +KERN_API_CALL(kern_place_is_passable) +{ + struct place *place; + int x, y; + class Object *obj; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-place-is-passable")) + return sc->F; + + obj = unpack_obj(sc, &args, "kern-place-is-passable"); + if (!obj) + return sc->F; + + return place_is_passable(place, x, y, obj, 0) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_place_move_is_passable) +{ + struct place *fplace, *tplace; + int fx, fy, tx, ty; + class Object *obj; + + if (unpack_loc(sc, &args, &fplace, &fx, &fy, + "kern-place-move-is-passable")) + return sc->F; + + if (unpack_loc(sc, &args, &tplace, &tx, &ty, + "kern-place-move-is-passable")) + return sc->F; + + obj = unpack_obj(sc, &args, "kern-place-move-is-passable"); + if (!obj) + return sc->F; + + return place_move_is_passable(fplace, fx, fy, tx, ty, obj, 0) ? sc->T + : sc->F; +} + +KERN_API_CALL(kern_place_is_hazardous) +{ + struct place *place; + int x, y; + class Object *obj; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-place-is-hazardous")) + return sc->F; + + obj = unpack_obj(sc, &args, "kern-place-is-hazardous"); + if (!obj) + return sc->F; + + return place_is_hazardous(place, x, y) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_place_set_terrain) +{ + struct place *place; + int x, y; + struct terrain *terrain; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-place-set-terrain")) + return sc->F; + + if (unpack(sc, &args, "p", &terrain)) { + rt_err("kern-place-set-terrain: bad args"); + return sc->F; + } + + if (! terrain) { + rt_err("kern-place-set-terrain: nil terrain"); + return sc->F; + } + + place_set_terrain(place, x, y, terrain); + + /* Often changing the terrain requires us to recalculate LOS in the + * surrounding area. */ + vmask_invalidate(place, x, y, 1, 1); + + /* And that means the map usually needs repainting, too */ + mapSetDirty(); + + return sc->T; +} + +KERN_API_CALL(kern_place_set_subplace) +{ + struct place *place, *subplace; + int x, y; + + if (unpack(sc, &args, "p", &subplace)) { + rt_err("kern-place-set-subplace: bad args"); + return sc->NIL; + } + + if (! subplace) { + rt_err("kern-place-set-subplace: nil subplace"); + return sc->NIL; + } + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-place-set-subplace")) + return sc->NIL; + + + place_add_subplace(place, subplace, x, y); + + return scm_mk_ptr(sc, subplace); +} + +KERN_API_CALL(kern_place_get_terrain) +{ + struct place *place; + int x, y; + struct terrain *terrain; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-place-get-terrain")) + return sc->F; + + terrain = place_get_terrain(place, x, y); + + return terrain ? scm_mk_ptr(sc, terrain) : sc->NIL; +} + +KERN_API_CALL(kern_place_get_movement_cost) +{ + struct place *place; + int x, y, cost=0; + class Object *obj; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-place-get-movement-cost")) + goto done; + + obj = unpack_obj(sc, &args, "kern-place-get-movement-cost"); + if (!obj) + goto done; + + cost = place_get_movement_cost(place, x, y, obj,0); + + done: + return scm_mk_integer(sc, cost); +} + +KERN_API_CALL(kern_place_get_light) +{ + struct place *place; + int x, y; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-place-get-light")) + return sc->F; + + return scm_mk_integer(sc, place_get_light(place, x, y)); +} + +KERN_API_CALL(kern_place_get_terrain_map) +{ + struct place *place; + struct terrain_map *map; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-get-terrain-map: bad args"); + return sc->NIL; + } + + map = place_get_terrain_map(place); + if (!map) + return sc->NIL; + return scm_mk_ptr(sc, map); +} + +KERN_API_CALL(kern_place_set_terrain_map) +{ + struct place *place; + struct terrain_map *map; + + if (unpack(sc, &args, "pp", &place, &map)) { + rt_err("kern-place-set-terrain-map: bad args"); + return sc->NIL; + } + + place_set_terrain_map(place, map); + return scm_mk_ptr(sc, place); +} + +KERN_API_CALL(kern_place_blocks_los) +{ + struct place *place; + int x, y; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-place-blocks-los?")) + return sc->F; + + return place_visibility(place, x, y) ? sc->F : sc->T; +} + +KERN_API_CALL(kern_obj_set_temporary) +{ + class Object *obj; + int val; + + obj = unpack_obj(sc, &args, "kern-obj-set-temporary"); + if (!obj) + return sc->NIL; + + if (unpack(sc, &args, "b", &val)) { + rt_err("kern-obj-set-temporary: bad value arg"); + return scm_mk_ptr(sc, obj); + } + + obj->setTemporary(val); + + return scm_mk_ptr(sc, obj); +} + +KERN_API_CALL(kern_obj_set_ignore_time_stop) +{ + class Object *obj; + int val; + + obj = unpack_obj(sc, &args, "kern-obj-set-ignore-time-stop"); + if (!obj) + return sc->NIL; + + if (unpack(sc, &args, "b", &val)) { + rt_err("kern-obj-set-ignore-time-stop: bad value arg"); + return scm_mk_ptr(sc, obj); + } + + obj->setIgnoreTimeStop(val); + + return scm_mk_ptr(sc, obj); +} + +KERN_API_CALL(kern_obj_wander) +{ + class Object *obj; + + obj = unpack_obj(sc, &args, "kern-obj-wander"); + if (!obj) + return sc->NIL; + + //moves can have nasty consequences, + //so keep our own ref to the object for a bit + obj_inc_ref(obj); + ctrl_wander(obj); + obj_dec_ref(obj); + + return sc->NIL; +} + +KERN_API_CALL(kern_obj_clone) +{ + class Object *obj, *clone; + + obj = unpack_obj(sc, &args, "kern-char-clone"); + if (!obj) + return sc->NIL; + + clone = obj->clone(); + assert(clone); + clone->setTemporary(1); + + return scm_mk_ptr(sc, clone); +} + +KERN_API_CALL(kern_obj_freeze) +{ + class Object *obj; + char* key; + int x,y; + + obj = unpack_obj(sc, &args, "kern-obj-freeze"); + if (!obj) + return sc->NIL; + + if (unpack(sc, &args, "sdd", &key, &x, &y)) { + rt_err("kern-obj-freeze: bad args"); + return sc->NIL; + } + + obj_inc_ref(obj); + freezer_freezeObject(key, x, y, obj); + + return sc->NIL; +} + +KERN_API_CALL(kern_obj_thaw) +{ + class Object *obj; + struct place *place; + char* key; + int x,y; + + if (unpack(sc, &args, "sp", &key, &place)) { + rt_err("kern-obj-thaw-at: bad args"); + return sc->NIL; + } + + obj = freezer_thawObject(key, &x, &y); + + if (obj) + { + obj->relocate(place, x, y, REL_NOTRIG); + scm_mk_ptr(sc, obj); + obj_dec_ref(obj); + return scm_mk_ptr(sc, obj); + } + + return sc->NIL; +} + +KERN_API_CALL(kern_set_wind) +{ + int dur, dir; + + if (unpack(sc, &args, "dd", &dir, &dur)) { + rt_err("kern-set-wind: bad args"); + return sc->F; + } + + windSetDirection(dir, dur); + return sc->T; +} + +KERN_API_CALL(kern_get_wind) +{ + return scm_mk_integer(sc, windGetDirection()); +} + +KERN_API_CALL(kern_ui_direction) +{ + int dir = ui_get_direction(); + + if (dir == CANCEL) + return sc->NIL; + + return scm_mk_integer(sc, dir); +} + +KERN_API_CALL(kern_place_get_neighbor) +{ + struct place *place; + struct place *neighbor; + int dir; + + if (unpack(sc, &args, "pd", &place, &dir)) { + rt_err("kern-place-get-neighbor: bad args"); + return sc->NIL; + } + + /* lookup neighbor */ + neighbor = place_get_neighbor(place, dir); + if (neighbor) + return scm_mk_ptr(sc, neighbor); + else + return sc->NIL; +} + +KERN_API_CALL(kern_char_get_party) +{ + class Character *ch; + class Party *party; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-get-party"); + if (!ch) + return sc->NIL; + + party = ch->getParty(); + if (party) + return scm_mk_ptr(sc, party); + else + return sc->NIL; +} + +KERN_API_CALL(kern_char_add_defense) +{ + int val; + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-add-defense"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-add-defense: bad args"); + return sc->NIL; + } + + ch->addDefense(val); + + return sc->NIL; +} + +KERN_API_CALL(kern_char_add_experience) +{ + int val; + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, + "kern-char-add-experience"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-add-experience: bad args"); + goto done; + } + + ch->addExperience(val); + done: + return scm_mk_ptr(sc, ch); +} + +KERN_API_CALL(kern_add_magic_negated) +{ + int val; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-add-magic-negated: bad args"); + return sc->F; + } + + add_magic_negated(val); + foogodRepaint(); + return sc->T; +} + +KERN_API_CALL(kern_get_magic_negated) +{ + return scm_mk_integer(sc, MagicNegated); +} + +KERN_API_CALL(kern_add_quicken) +{ + int val; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-add-quicken: bad args"); + return sc->F; + } + + add_quicken(val); + foogodRepaint(); + return sc->T; +} + +KERN_API_CALL(kern_set_time_accel) +{ + float val; + + if (unpack(sc, &args, "f", &val)) { + rt_err("kern-set-time-accel: bad args"); + return sc->F; + } + + session_set_time_accel(val); + foogodRepaint(); + return sc->T; +} + +KERN_API_CALL(kern_set_turn_count) +{ + int val; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-set-turn-count: bad args"); + return sc->F; + } + + session_set_turn_count(val); + return sc->T; +} + +KERN_API_CALL(kern_add_reveal) +{ + int val; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-add-reveal: bad args"); + return sc->F; + } + + add_reveal(val); + foogodRepaint(); + return sc->T; +} + +KERN_API_CALL(kern_add_time_stop) +{ + int val; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-add-time-stop: bad args"); + return sc->F; + } + + add_time_stop(val); + foogodRepaint(); + return sc->T; +} + +KERN_API_CALL(kern_being_is_hostile) +{ + class Being *one, *another; + + if (unpack(sc, &args, "pp", &one, &another)) { + rt_err("kern-being-is-hostile: bad args"); + return sc->F; + } + + if (! one || ! another) { + rt_err("kern-being-is-hostile: null character"); + return sc->F; + } + + return are_hostile(one, another) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_being_is_ally) +{ + class Being *one, *another; + + if (unpack(sc, &args, "pp", &one, &another)) { + rt_err("kern-being-is-ally: bad args"); + return sc->F; + } + + if (! one || ! another) { + rt_err("kern-being-is-ally: null character"); + return sc->F; + } + + return are_allies(one, another) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_add_xray_vision) +{ + int val; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-add-xray-vision: bad args"); + return sc->F; + } + + add_xray(val); + return sc->T; +} + +KERN_API_CALL(kern_char_charm) +{ + int val; + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-charm"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-charm: bad args"); + return sc->NIL; + } + + ch->charm(val); + + return sc->NIL; +} + +KERN_API_CALL(kern_char_uncharm) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-charm"); + if (!ch) + return sc->NIL; + + ch->unCharm(); + + return sc->NIL; +} + +KERN_API_CALL(kern_map_set_jitter) +{ + int val; + + if (unpack(sc, &args, "b", &val)) { + rt_err("kern-map-set-jitter: bad args"); + return sc->F; + } + + mapJitter(val); + return sc->T; +} + +KERN_API_CALL(kern_image_load) +{ + char *fname, *path; + SDL_Surface *image = 0; + + if (unpack(sc, &args, "s", &fname)) { + rt_err("kern-image-load: bad args"); + return sc->NIL; + } + + path = file_mkpath(cfg_get("include-dirname"), fname); + if (! path) { + rt_err("kern-image-load: %s", file_get_error()); + return sc->NIL; + } + + image = IMG_Load(path); + if (! image) { + rt_err("kern-image-load: %s", SDL_GetError()); + } + free(path); + + return scm_mk_ptr(sc, image); +} + +KERN_API_CALL(kern_image_free) +{ + SDL_Surface *image; + + if (unpack(sc, &args, "p", &image)) { + rt_err("kern-image-free: bad args"); + return sc->NIL; + } + + SDL_FreeSurface(image); + return sc->NIL; +} + +KERN_API_CALL(kern_map_set_image) +{ + SDL_Surface *image; + + if (unpack(sc, &args, "p", &image)) { + rt_err("kern-map-set-image: bad args"); + return sc->NIL; + } + + if (!image) { + mapClearImage(); + mapUpdate(0); + return sc->NIL; + } + + mapSetImage(image); + return sc->NIL; +} + +KERN_API_CALL(kern_map_blit_image) +{ + SDL_Surface *image; + Uint32 x, y; + + if (unpack(sc, &args, "pdd", &image, &x, &y)) { + rt_err("kern-map-blit-image: bad args"); + return sc->NIL; + } + + if (!image) { + return sc->NIL; + } + + mapBlitImage(image, x, y); + return sc->NIL; +} + +KERN_API_CALL(kern_map_get_width) +{ + struct terrain_map *map; + + if (unpack(sc, &args, "p", &map)) { + rt_err("kern-map-get-width: bad args"); + return sc->NIL; + } + + if (!map) { + rt_err("kern-map-get-width: null map"); + return sc->NIL; + } + + return scm_mk_integer(sc, map->w); +} + + +KERN_API_CALL(kern_map_get_height) +{ + struct terrain_map *map; + + if (unpack(sc, &args, "p", &map)) { + rt_err("kern-map-get-width: bad args"); + return sc->NIL; + } + + if (!map) { + rt_err("kern-map-get-width: null map"); + return sc->NIL; + } + + return scm_mk_integer(sc, map->h); +} + +KERN_API_CALL(kern_char_kill) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-kill"); + if (!ch) + return sc->NIL; + + ch->kill(); + + return sc->NIL; +} + +KERN_API_CALL(kern_char_resurrect) +{ + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-resurrect"); + if (!ch) + return sc->NIL; + + ch->resurrect(); + + return scm_mk_ptr(sc, ch); +} + +KERN_API_CALL(kern_is_valid_location) +{ + struct place *place; + int x, y; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-is-valid-location?")) + return sc->F; + + if (place->wraps) + return sc->T; + + if (x < 0 || x >= place_w(place) || + y < 0 || y >= place_h(place)) + return sc->F; + + return sc->T; +} + +KERN_API_CALL(kern_terrain_blocks_los) +{ + struct terrain *terrain; + + if (unpack(sc, &args, "p", &terrain)) { + rt_err("kern-terrain-blocks-los?: bad args"); + return sc->NIL; + } + + if(! terrain) { + rt_err("kern-terrain-blocks-los?: null terrain"); + return sc->NIL; + } + + return terrain->alpha ? sc->T : sc->F; +} + +KERN_API_CALL(kern_terrain_get_pclass) +{ + struct terrain *terrain; + + if (unpack(sc, &args, "p", &terrain)) { + rt_err("kern-terrain-get-pclass: bad args"); + return sc->NIL; + } + + if(! terrain) { + rt_err("kern-terrain-get-pclass: null terrain"); + return sc->NIL; + } + + return scm_mk_integer(sc, terrain_pclass(terrain)); +} + +KERN_API_CALL(kern_terrain_set_combat_map) +{ + struct terrain *terrain; + struct terrain_map *map; + + if (unpack(sc, &args, "pp", &terrain, &map)) { + rt_err("kern-terrain-set-combat-map: bad args"); + return sc->NIL; + } + + if(! terrain) { + rt_err("kern-terrain-set-combat-map: null terrain"); + return sc->NIL; + } + + terrain->combat_map = map; + + return scm_mk_ptr(sc, terrain); +} + +KERN_API_CALL(kern_terrain_set_combat_handler) +{ + struct terrain *terrain; + pointer proc; + + if (unpack(sc, &args, "po", &terrain, &proc)) { + rt_err("kern-terrain-set-combat-handler: bad args"); + return sc->NIL; + } + + if(!terrain) { + rt_err("kern-terrain-set-combat-handler: null terrain"); + return sc->NIL; + } + + if (proc != sc->NIL) { + terrain->renderCombat = closure_new(sc, proc); + closure_ref(terrain->renderCombat); //TODO clean up this nasty leaky hack + } + + return scm_mk_ptr(sc, terrain); +} + +KERN_API_CALL(kern_terrain_map_inc_ref) +{ + struct terrain_map *map; + + if (unpack(sc, &args, "p", &map)) { + rt_err("kern-terrain-map-inc-ref: bad args"); + return sc->NIL; + } + + terrain_map_ref(map); + return scm_mk_ptr(sc, map); +} + +KERN_API_CALL(kern_terrain_map_dec_ref) +{ + struct terrain_map *map; + + if (unpack(sc, &args, "p", &map)) { + rt_err("kern-terrain-map-dec-ref: bad args"); + return sc->NIL; + } + + terrain_map_ref(map); + return sc->NIL; +} + +KERN_API_CALL(kern_mk_blender) +{ + blender_t *blender; + pointer rlist; + int i = 0; + + blender = (blender_t*)calloc(1, sizeof(*blender)); + list_init(&blender->list); + + if (unpack(sc, &args, "p", &blender->inf)) { + rt_err("kern-terrain-map-blend: bad args"); + goto abort; + } + + /* list of not-superior terrains */ + rlist = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (! scm_is_pair(sc, rlist)) { + rt_err("kern-terrain-map-blend: missing non-superior list"); + goto abort; + } + + while (scm_is_pair(sc, rlist) + && blender->n_nonsup < BLENDER_MAX_NONSUP) { + if (unpack(sc, &rlist, "p", &blender->nonsup[blender->n_nonsup])) { + rt_err("kern-terrain-map-blend: non-superior terrain %d bad", i); + goto abort; + } + blender->n_nonsup++; + } + + if (scm_is_pair(sc, rlist)) { + warn("kern-terrain-map-blend: at most %d non-superior "\ + "terrains may be used, the rest will be ignored", + BLENDER_MAX_NONSUP); + } + + /* list of target (range) terrains */ + i = 0; + rlist = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (! scm_is_pair(sc, rlist)) { + rt_err("kern-terrain-map-blend: missing range list"); + goto abort; + } + + while (scm_is_pair(sc, rlist) + && i < BLENDER_N_RANGE) { + + if (unpack(sc, &rlist, "p", &blender->range[i])) { + rt_err("kern-terrain-map-blend: range %d bad", i); + return sc->NIL; + } + + i++; + } + + if (i < BLENDER_N_RANGE) { + rt_err("kern-terrain-map-blend: expected %d ranges, got %d", + BLENDER_N_RANGE, i); + goto abort; + } + + session_add(Session, blender, blender_dtor, NULL, NULL); + list_add(&Session->blenders, &blender->list); + + return sc->T; + + abort: + free(blender); + return sc->F; +} + +KERN_API_CALL(kern_terrain_map_blend) +{ + struct terrain_map *map; + struct terrain *inf, *nonsup[32], *range[16]; + pointer rlist; + int i = 0; + int n_nonsup = 0; + + if (unpack(sc, &args, "pp", &map, &inf)) { + rt_err("kern-terrain-map-blend: bad args"); + return sc->NIL; + } + + /* list of not-superior terrains */ + rlist = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (! scm_is_pair(sc, rlist)) { + rt_err("kern-terrain-map-blend: missing non-superior list"); + return sc->NIL; + } + + while (scm_is_pair(sc, rlist) && n_nonsup < array_sz(nonsup)) { + + if (unpack(sc, &rlist, "p", &nonsup[n_nonsup])) { + rt_err("kern-terrain-map-blend: non-superior terrain %d bad", i); + return sc->NIL; + } + + n_nonsup++; + } + + if (scm_is_pair(sc, rlist)) { + warn("kern-terrain-map-blend: at most %d non-superior "\ + "terrains may be used, the rest will be ignored", + array_sz(nonsup)); + } + + /* list of target (range) terrains */ + i = 0; + rlist = scm_car(sc, args); + args = scm_cdr(sc, args); + + if (! scm_is_pair(sc, rlist)) { + rt_err("kern-terrain-map-blend: missing range list"); + return sc->NIL; + } + + while (scm_is_pair(sc, rlist) && i < 16) { + + if (unpack(sc, &rlist, "p", &range[i])) { + rt_err("kern-terrain-map-blend: range %d bad", i); + return sc->NIL; + } + + i++; + } + + if (i < 16) { + rt_err("kern-terrain-map-blend: expected 16 ranges, got %d", i); + return sc->NIL; + } + + terrain_map_blend(map, inf, n_nonsup, nonsup, range); + + return scm_mk_ptr(sc, map); +} + +KERN_API_CALL(kern_place_get_width) +{ + struct place *place; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-get-width: bad args"); + return sc->NIL; + } + + if (!place) { + rt_err("kern-place-get-width: null place"); + return sc->NIL; + } + + return scm_mk_integer(sc, place_w(place)); +} + +KERN_API_CALL(kern_place_get_vehicle) +{ + struct place *place; + int x, y; + class Vehicle *veh; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-place-get-vehicle")) + return sc->NIL; + + if (!place) { + rt_err("kern-place-get-vehicle: null place"); + return sc->NIL; + } + + veh = place_get_vehicle(place, x, y); + + return veh ? scm_mk_ptr(sc, veh) : sc->NIL; +} + +KERN_API_CALL(kern_place_get_height) +{ + struct place *place; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-place-get-height: bad args"); + return sc->NIL; + } + + if (!place) { + rt_err("kern-place-get-height: null place"); + return sc->NIL; + } + + return scm_mk_integer(sc, place_h(place)); +} + +KERN_API_CALL(kern_get_distance) +{ + struct place *p1, *p2; + int x1, x2, y1, y2; + + if (unpack_loc(sc, &args, &p1, &x1, &y1, "kern-get-distance") || + unpack_loc(sc, &args, &p2, &x2, &y2, "kern-get-distance")) + return sc->NIL; + + /* warn("p1=%s x1=%d y1=%d x2=%d y2=%d\n", p1->name, x1, y1, x2, y2); */ + + if (p1 != p2) { + rt_err("kern-get-distance: place %s different from %s", + p1->tag, p2->tag); + return sc->NIL; + } + + return scm_mk_integer(sc, place_flying_distance(p1, x1, y1, x2, y2)); +} + +KERN_API_CALL(kern_in_los) +{ + struct place *p1, *p2; + int x1, x2, y1, y2; + + if (unpack_loc(sc, &args, &p1, &x1, &y1, "kern-in-los?") || + unpack_loc(sc, &args, &p2, &x2, &y2, "kern-in-los?")) + return sc->F; + + if (p1 != p2) { + /* happens sometimes when player exits a place and NPC's + * looking for him in the same round */ + warn("kern-in-los?: place %s different from %s\n", + p1->tag, p2->tag); + return sc->F; + } + + return place_in_los(p1, x1, y1, p2, x2, y2) ? sc->T : sc->F; +} + +KERN_API_CALL(kern_map_set_peering) +{ + int val; + if (unpack(sc, &args, "b", &val)) { + rt_err("kern-map-set-peering: bad args"); + return sc->NIL; + } + mapPeer(val); + return sc->NIL; +} + +KERN_API_CALL(kern_ui_waitkey) +{ + int key; + getkey(&key, anykey); + return scm_mk_integer(sc, key); +} + +KERN_API_CALL(kern_char_dec_mana) +{ + int val; + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-char-dec-mana"); + if (!ch) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-dec-mana: bad args"); + return sc->NIL; + } + + ch->addMana(0 - val); + + return sc->NIL; +} + +KERN_API_CALL(kern_test_recursion) +{ + pointer func; + + if (unpack(sc, &args, "o", &func)) { + rt_err("kern-test-recursion: bad args"); + return sc->NIL; + } + + scheme_call(sc, func, sc->NIL); + + return sc->NIL; +} + +KERN_API_CALL(kern_ui_select_from_list) +{ + struct KeyHandler kh; + struct ScrollerContext data; + const char **strings; + int list_sz; + int i = 0; + enum StatusMode omode; + char *selection = NULL; + + list_sz = scm_len(sc, args); + if (! list_sz) + return sc->NIL; + + strings = (const char**)calloc(list_sz, sizeof(strings[0])); + assert(strings); + + while (scm_is_pair(sc, args)) { + if (unpack(sc, &args, "s", &strings[i])) { + rt_err("kern-ui-select-from-list: bad args"); + goto done; + } + i++; + } + + foogodSetHintText(SCROLLER_HINT); + foogodSetMode(FOOGOD_HINT); + omode = statusGetMode(); + statusSetStringList("Select", list_sz, strings); + statusSetMode(StringList); + + data.selection = NULL; + data.selector = String; + kh.fx = scroller; + kh.data = &data; + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + + statusSetMode(omode); + foogodSetMode(FOOGOD_DEFAULT); + + selection = (char*)data.selection; + + done: + if (strings) + free(strings); + + if (selection) + return scm_mk_string(sc, selection); + + return sc->NIL; + +} + +KERN_API_CALL(kern_ui_select_item) +{ + enum StatusMode omode; + struct inv_entry *ie; + class Character *ch; + + ch = (class Character*)unpack_obj(sc, &args, "kern-ui-select-item"); + if (!ch || !ch->getInventoryContainer()) + return sc->NIL; + + omode = statusGetMode(); + statusBrowseContainer(ch->getInventoryContainer(), "Select"); + ie = ui_select_item(); + statusSetMode(omode); + + if (!ie) { + return sc->NIL; + } + + return scm_mk_ptr(sc, ie->type); +} + +KERN_API_CALL(kern_ui_page_text) +{ + struct KeyHandler kh; + char *title; + char *text = NULL; + int len = 0; + int lines = 0; + + if (unpack(sc, &args, "s", &title)) { + rt_err("kern-ui-status-page-text: bad title"); + return sc->NIL; + } + + while (scm_is_pair(sc, args)) { + + char *line; + + if (unpack(sc, &args, "s", &line)) { + rt_err("kern-ui-status-page-text: bad text line"); + goto done; + } + + len += strlen(line); + len++; /* for \n */ + text = (char*)realloc(text, len + 1 /* for \0 */); + if (lines == 0) { + text[0] = 0; + } + strcat(text, line); + strcat(text, "\n"); + lines++; + } + + foogodSetHintText(PAGER_HINT); + foogodSetMode(FOOGOD_HINT); + statusSetPageText(title, text); + statusSetMode(Page); + consolePrint("[Hit ESC to continue]\n"); + + kh.fx = scroller; + kh.data = NULL; + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + + statusSetMode(ShowParty); + foogodSetMode(FOOGOD_DEFAULT); + + done: + if (text) + free(text); + + return sc->NIL; +} + +KERN_API_CALL(kern_obj_remove_from_inventory) +{ + class Object *obj; + class ObjectType *type; + int amount; + + if (unpack(sc, &args, "ppd", &obj, &type, &amount)) { + rt_err("kern-obj-remove-from-inventory: bad args"); + return sc->NIL; + } + + if (! obj->takeOut(type, amount)) { + rt_err("kern-obj-remove-from-inventory: failed! "\ + "(is quantity > amount available to take out?)"); + } + return sc->NIL; +} + +KERN_API_CALL(kern_obj_add_to_inventory) +{ + class Object *obj; + class ObjectType *type; + int amount; + + if (unpack(sc, &args, "ppd", &obj, &type, &amount)) { + rt_err("kern-obj-add-to-inventory: bad args"); + return sc->NIL; + } + + obj->add(type, amount); + return sc->NIL; +} + +KERN_API_CALL(kern_mk_ptable) +{ + int n_mmode; + int n_pclass; + int pclass; + struct ptable *ptable; + pointer row; + pointer col; + + /* The ptable table is a list of lists. Each row corresponds to a + * passability class (a property of terrain, and objects which affect + * passability onto a tile). Each column corresponds to a movement + * mode. */ + + if (! scm_is_pair(sc, args)) { + load_err("kern-mk-ptable: arg 0 not a list"); + return sc->NIL; + } + + /* count the number of passability classes and movement modes given in + * the table */ + row = args; + col = scm_car(sc, args); + + n_pclass = scm_len(sc, row); + n_mmode = scm_len(sc, col); + + if (n_pclass <= 0) { + load_err("kern-mk-ptable: 0 rows given"); + return sc->NIL; + } + + if (n_mmode <= 0) { + load_err("kern-mk-ptable: row 0 has no columns"); + return sc->NIL; + } + + /* allocate the kernel passability table */ + ptable = ptable_new(n_mmode, n_pclass); + + /* for each row (passability class) */ + for (pclass = 0; pclass < n_pclass; pclass++) { + + int mmode; + + col = scm_car(sc, row); + row = scm_cdr(sc, row); + + if (scm_len(sc, col) < n_mmode) { + load_err("kern-mk-ptable: row %d has only %d columns", + pclass, scm_len(sc, col)); + goto abort; + } + + /* for each column (movement mode) */ + for (mmode = 0; mmode < n_mmode; mmode++) { + + int mcost; + + /* get the movement cost */ + if (unpack(sc, &col, "d", &mcost)) { + load_err("kern-mk-ptable: row %d col %d bad arg", + pclass, mmode); + goto abort; + } + + /* insert it into the passability table */ + ptable_set(ptable, mmode, pclass, mcost); + } + } + + + /* associate the session with the new table */ + if (Session->ptable) { + ptable_del(Session->ptable); + } + Session->ptable = ptable; + + return sc->NIL; + + abort: + ptable_del(ptable); + return sc->NIL; +} + +KERN_API_CALL(kern_mk_dtable) +{ + int n_factions; + int r_faction; + struct dtable *dtable; + pointer rows; + pointer row; + + /* The dtable table is a list of lists. Each row corresponds to a + * passability class (a property of terrain, and objects which affect + * passability onto a tile). Each column corresponds to a movement + * mode. */ + + if (! scm_is_pair(sc, args)) { + load_err("kern-mk-dtable: arg 0 not a list"); + return sc->NIL; + } + + /* count the number of factions given in the table */ + rows = args; + row = scm_car(sc, rows); + n_factions = scm_len(sc, rows); + if (n_factions != scm_len(sc, row)) { + load_err("kern-mk-dtable: # of rows and columns must be same"); + return sc->NIL; + } + if (n_factions <= 0) { + load_err("kern-mk-dtable: 0 factions given"); + return sc->NIL; + } + + /* allocate the kernel table */ + dtable = dtable_new(n_factions); + + /* for each row */ + for (r_faction = 0; r_faction < n_factions; r_faction++) { + + int c_faction; + + row = scm_car(sc, rows); + rows = scm_cdr(sc, rows); + + if (scm_len(sc, row) < n_factions) { + load_err("kern-mk-dtable: row %d has only %d columns " + "(expected %d)", + r_faction, scm_len(sc, row), + n_factions); + goto abort; + } + + /* for each column up to the limit */ + for (c_faction = 0; c_faction < n_factions; c_faction++) { + + int val; + + /* unpack the value */ + if (unpack(sc, &row, "d", &val)) { + load_err("kern-mk-dtable: row %d column %d " + "is a bad entry", r_faction, + c_faction); + goto abort; + } + + /* poke it into the table */ + dtable_set(dtable, r_faction, c_faction, val); + } + } + + /* associate the session with the new table */ + if (Session->dtable) { + dtable_del(Session->dtable); + } + Session->dtable = dtable; + + return scm_mk_ptr(sc, dtable); + + abort: + dtable_del(dtable); + return sc->NIL; +} + +#define DTABLE_SET 0x81 +#define DTABLE_GET 0x05 +#define DTABLE_INC 0x06 +#define DTABLE_DEC 0x07 + +#define DTABLE_FX_USES_LEVEL(fx) ((fx) & 0x80) + +static pointer kern_dtable_aux(scheme *sc, pointer args, const char *name, int fx) +{ + int f1, f2, level; + const char *errstr = NULL; + + if (! session_dtable()) { + errstr = "no dtable"; + goto abort; + } + + if (unpack(sc, &args, "dd", &f1, &f2)) { + errstr = "bad faction args"; + goto abort; + } + + if (DTABLE_FX_USES_LEVEL(fx)) { + if (unpack(sc, &args, "d", &level)) { + errstr = "bad level arg"; + goto abort; + } + } + + switch (fx) { + case DTABLE_SET: + dtable_set(session_dtable(), f1, f2, level); + break; + case DTABLE_GET: + level = dtable_get(session_dtable(), f1, f2); + return scm_mk_integer(sc, level); + break; + case DTABLE_INC: + dtable_inc(session_dtable(), f1, f2); + break; + case DTABLE_DEC: + dtable_dec(session_dtable(), f1, f2); + break; + default: + assert(0); + break; + } + + return sc->T; +abort: + rt_err("%s: %s", name, errstr); + return sc->F; + +} + +KERN_API_CALL(kern_dtable_set) +{ + return kern_dtable_aux(sc, args, "kern_dtable_set", DTABLE_SET); +} + +KERN_API_CALL(kern_dtable_get) +{ + return kern_dtable_aux(sc, args, "kern_dtable_get", DTABLE_GET); +} + +KERN_API_CALL(kern_dtable_inc) +{ + return kern_dtable_aux(sc, args, "kern_dtable_inc", DTABLE_INC); +} + +KERN_API_CALL(kern_dtable_dec) +{ + return kern_dtable_aux(sc, args, "kern_dtable_dec", DTABLE_DEC); +} + +KERN_API_CALL(kern_party_add_member) +{ + class Party *party; + class Character *new_member; + + party = (Party*)unpack_obj(sc, &args, "kern_party_add_member:"); + if (!party) + return sc->NIL; + + new_member = (class Character*)unpack_obj(sc, &args, + "kern_party_add_member:"); + if (!new_member) + return sc->NIL; + + if (party->addMember(new_member)) + return sc->T; + + return sc->F; +} + +KERN_API_CALL(kern_party_set_vehicle) +{ + class Party *party; + class Vehicle *vehicle; + + party = (Party*)unpack_obj(sc, &args, "kern-party-set-vehicle"); + if (!party) + return sc->NIL; + + vehicle = (Vehicle*)unpack_obj(sc, &args, "kern-party-set-vehicle"); + party->setVehicle(vehicle); + + return scm_mk_ptr(sc, party); +} + +KERN_API_CALL(kern_party_get_vehicle) +{ + class Party *party; + class Vehicle *vehicle; + + party = (Party*)unpack_obj(sc, &args, "kern-party-get-vehicle"); + if (!party) + return sc->NIL; + + vehicle = party->getVehicle(); + if (vehicle) + return scm_mk_ptr(sc, vehicle); + return sc->NIL; +} + +static bool wrap_kern_append_obj(class Character *c, void *v) +{ + kern_append_object(c, v); + return false; +} + +KERN_API_CALL(kern_get_time) +{ + pointer head, tail, cell; + + /* have to do everything in forward order so that our cells remain + * protected from gc until the list is built */ + head = _cons(sc, scm_mk_integer(sc, clock_year()), sc->NIL, 0); + tail = head; + scm_protect(sc, head); + + cell = _cons(sc, scm_mk_integer(sc, clock_month()), sc->NIL, 0); + tail->_object._cons._cdr = cell; + tail = cell; + + cell = _cons(sc, scm_mk_integer(sc, clock_week()), sc->NIL, 0); + tail->_object._cons._cdr = cell; + tail = cell; + + cell = _cons(sc, scm_mk_integer(sc, clock_day()), sc->NIL, 0); + tail->_object._cons._cdr = cell; + tail = cell; + + cell = _cons(sc, scm_mk_integer(sc, clock_hour()), sc->NIL, 0); + tail->_object._cons._cdr = cell; + tail = cell; + + cell = _cons(sc, scm_mk_integer(sc, clock_minute()), sc->NIL, 0); + tail->_object._cons._cdr = cell; + tail = cell; + + scm_unprotect(sc, head); + return head; +} + +KERN_API_CALL(kern_get_time_remainder) +{ + return scm_mk_integer(sc, clock_tick()); +} + + +KERN_API_CALL(kern_get_total_minutes) +{ + return scm_mk_integer(sc, clock_time()); +} + + +KERN_API_CALL(kern_party_get_members) +{ + class Party *party; + struct kern_append_info info; + + if (unpack(sc, &args, "p", &party)) { + rt_err("kern-party-get-members: bad args"); + return sc->NIL; + } + + /* initialize the context used by the callback to append objects */ + info.sc = sc; + info.head = sc->NIL; + info.tail = sc->NIL; + info.filter = NULL; + info.data = NULL; + + /* build a scheme list of the objects at that location */ + party->forEachMember(wrap_kern_append_obj, &info); + + /* unprotect the list prior to return */ + if (info.head != sc->NIL) + scm_unprotect(sc, info.head); + + /* return the scheme list */ + return info.head; +} + +KERN_API_CALL(kern_being_set_base_faction) +{ + class Being *being; + int faction; + + being = (class Being*)unpack_obj(sc, &args, "kern-being-set-base-faction"); + if (!being) + goto done; + + if (unpack(sc, &args, "d", &faction)) { + rt_err("kern-being-set-base-faction: bad arg"); + goto done; + } + + being->setBaseFaction(faction); + done: + return scm_mk_ptr(sc, being); + +} + +KERN_API_CALL(kern_being_set_current_faction) +{ + class Being *being; + int faction; + + being = (class Being*)unpack_obj(sc, &args, "kern-being-set-current-faction"); + if (!being) + goto done; + + if (unpack(sc, &args, "d", &faction)) { + rt_err("kern-being-set-current-faction: bad arg"); + goto done; + } + + being->setCurrentFaction(faction); + done: + return scm_mk_ptr(sc, being); + +} + +KERN_API_CALL(kern_being_set_name) +{ + class Being *being; + char *val; + + being = (class Being*)unpack_obj(sc, &args, "kern-being-set-name"); + if (!being) + goto done; + + if (unpack(sc, &args, "s", &val)) { + rt_err("kern-being-set-name: bad arg"); + goto done; + } + + being->setName(val); + done: + return scm_mk_ptr(sc, being); + +} + +KERN_API_CALL(kern_vehicle_set_name) +{ + class Vehicle *vehicle; + char *val; + + vehicle = (class Vehicle*)unpack_obj(sc, &args, "kern-vehicle-set-name"); + if (!vehicle) + goto done; + + if (unpack(sc, &args, "s", &val)) { + rt_err("kern-vehicle-set-name: bad arg"); + goto done; + } + + vehicle->setName(val); + done: + return scm_mk_ptr(sc, vehicle); + +} + +KERN_API_CALL(kern_harm_relations) +{ + class Character *cha; + class Character *chb; + + if (unpack(sc, &args, "pp", &cha, &chb)) { + rt_err("kern-harm-relations: bad args"); + return sc->NIL; + } + + harm_relations(cha,chb); + + return sc->NIL; +} + +KERN_API_CALL(kern_being_get_current_faction) +{ + class Being *being; + int faction = INVALID_FACTION; + + being = (Being*)unpack_obj(sc, &args, "kern-being-get-current-faction"); + if (!being) + goto done; + + faction = being->getCurrentFaction(); + done: + return scm_mk_integer(sc, faction); +} + +KERN_API_CALL(kern_being_get_base_faction) +{ + class Being *being; + int faction = INVALID_FACTION; + + being = (Being*)unpack_obj(sc, &args, "kern-being-get-base-faction"); + if (!being) + goto done; + + faction = being->getBaseFaction(); + done: + return scm_mk_integer(sc, faction); +} + +KERN_API_CALL(kern_add_hook) +{ + pointer pproc; + char *hookstr; + + if(unpack(sc, &args, "yc", &hookstr, &pproc)) { + load_err("%s: bad args", __FUNCTION__); + return sc->NIL; + } + +//// printf("%s() %s: ", __FUNCTION__, hookstr); +//// if (scm_is_sym(sc, pproc)) { +//// printf("%s\n", scm_sym_val(sc, pproc)); +//// } else { +//// printf("\n"); +//// } + + session_hook_id_t id = session_str_to_hook_id(hookstr); + if (id >= NUM_HOOKS) { + load_err("%s: bad hook id=%d (%s)", __FUNCTION__, id, hookstr); + return sc->NIL; + } + + pointer pargs = sc->NIL; + if (scm_is_pair(sc, args)) { + pargs = scm_car(sc, args); + } + void *ret = session_add_hook(Session, (session_hook_id_t)id, closure_new(sc, pproc), pargs); + return ret ? scm_mk_ptr(sc, ret) : sc->NIL; +} + +KERN_API_CALL(kern_rm_hook) +{ + pointer pproc; + char *hookstr; + + if(unpack(sc, &args, "yc", &hookstr, &pproc)) { + load_err("%s: bad args", __FUNCTION__); + return sc->NIL; + } + + session_hook_id_t id = session_str_to_hook_id(hookstr); + if (id < NUM_HOOKS) { + session_rm_hook(Session, (session_hook_id_t)id, pproc); + } + + return sc->NIL; +} + +KERN_API_CALL(kern_add_query) +{ + pointer pproc; + char *str; + int id = 0; + + if(unpack(sc, &args, "yo", &str, &pproc)) { + load_err("%s: bad args", __FUNCTION__); + return sc->F; + } + + for (id = 0; id < NUM_HOOKS; id++) { + if (! strcmp(query_to_id[id], str)) { + session_add_query(Session, (session_query_id_t)id, closure_new(sc, pproc)); + return pproc; + } + } + + return sc->F; +} + +KERN_API_CALL(kern_player_set_follow_mode) +{ + player_party->enableFollowMode(); + return sc->NIL; +} + +KERN_API_CALL(kern_obj_has) +{ + class Object *object; + class ObjectType *type; + int has = 0; + + object = (Object*)unpack_obj(sc, &args, "kern-obj-has"); + if (!object) + goto done; + + if (unpack(sc, &args, "p", &type)) { + rt_err("kern-obj-has?"); + goto done; + } + + has = object->hasInInventory(type); + done: + return has ? sc->T : sc->F; +} + +static pointer kern_astar_path_to_scheme_list(scheme *sc, struct astar_node *path) +{ + pointer head; + pointer cell; + + /* base case - end of path */ + if (!path) + return sc->NIL; + + /* create a scheme pair (x, y) */ + cell = _cons(sc, + scm_mk_integer(sc, path->x), + scm_mk_integer(sc, path->y), + 0); + + /* recursively build a scheme list of pairs */ + head = _cons(sc, + cell, + kern_astar_path_to_scheme_list(sc, path->next), + 0); + + /* cleanup the node */ + astar_node_destroy(path); + + return head; +} + +KERN_API_CALL(kern_obj_find_path) +{ + class Object *object; + struct place *place; + struct astar_node *path = NULL; + struct astar_search_info as_info; + pointer sc_path; + + memset(&as_info, 0, sizeof (as_info)); + + object = (Object*)unpack_obj(sc, &args, "kern-obj-find-path"); + if (!object) + return sc->NIL; + + if (unpack_loc(sc, &args, &place, &as_info.x1, &as_info.y1, + "kern-obj-find-path")) { + return sc->NIL; + } + + /* can't pathfind between places */ + if (object->getPlace() != place) + return sc->NIL; + + /* find the path */ + as_info.x0 = object->getX(); + as_info.y0 = object->getY(); + path = place_find_path(place, &as_info, object); + if (! path) + return sc->NIL; + + /* convert the path to a scheme list */ + sc_path = kern_astar_path_to_scheme_list(sc, path); + return sc_path; +} + +static pointer kern_build_weapon_list(scheme *sc, + class Character *character, + class ArmsType *weapon, + int *armsIndex) +{ + /* base case */ + if (! weapon) + return sc->NIL; + + /* recursive case */ + return _cons(sc, + scm_mk_ptr(sc, weapon), + kern_build_weapon_list(sc, + character, + character->getNextWeapon(armsIndex), + armsIndex), + 0); +} + +KERN_API_CALL(kern_char_get_weapons) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, + "kern-char-get-weapons"); + if (!character) + return sc->NIL; + + /* recursively enumerate the character's available weapons into a + * scheme list */ + int armsIndex = 0; + return kern_build_weapon_list(sc, + character, + character->enumerateWeapons(&armsIndex), + &armsIndex); +} + +/** + * A generic append-to-scheme-list function. + */ +static void kern_list_append(struct kern_append_info *info, void *data) +{ + /* alloc a cell */ + pointer cell = scm_mk_ptr(info->sc, data); + + /* make it a list element */ + cell = _cons(info->sc, cell, info->sc->NIL, 0); + + /* add it to the list */ + if (info->head == info->sc->NIL) { + info->head = cell; + info->tail = cell; + + /* Protect the head from garbage collection. As long as the + * head is protected the entire list is protected. The caller + * must unprotect the head just before returning the list back + * to scheme, so the collector will clean it up when the script + * no longer needs it. */ + scm_protect(info->sc, cell); + + } else { + info->tail->_object._cons._cdr = cell; + info->tail = cell; + } +} + +/** + * Used by kern-char-get-skills to add all the skills in a skill set to the + * list. + */ +static void kern_add_skill_set(struct kern_append_info *info, int pclvl, + struct skill_set *skset) +{ + struct list *elem; + + /* for each skill in the skill set */ + list_for_each(&skset->skills, elem) { + + struct skill_set_entry *ssent; + ssent = list_entry(elem, struct skill_set_entry, list); + + /* is the character of sufficient level? */ + if (pclvl < ssent->level) { + continue; + } + + kern_list_append(info, ssent->skill); + } +} + +/** + * A generic append-to-scheme-list function. + */ +static void kern_list_append_pointer(struct kern_append_info *info, pointer cell) +{ + /* make it a list element */ + cell = _cons(info->sc, cell, info->sc->NIL, 0); + + /* add it to the list */ + if (info->head == info->sc->NIL) { + info->head = cell; + info->tail = cell; + + /* Protect the head from garbage collection. As long as the + * head is protected the entire list is protected. The caller + * must unprotect the head just before returning the list back + * to scheme, so the collector will clean it up when the script + * no longer needs it. */ + scm_protect(info->sc, cell); + + } else { + info->tail->_object._cons._cdr = cell; + info->tail = cell; + } +} + +/** + * A generic pagination function. + * Copies one line of text to output. + * output should be pre-allocated, and large enough to glom all of input if necessary + * returns a pointer offset to the location the search finished at + */ +static char* kern_paginate_text(char *input, char *output) +{ + int curlength = 0; + char* endinput = NULL; + char* endoutput = output; + while (*input != 0) + { + if (isspace(*input)) + { + endinput = input; + endoutput = output; + //printf("[ ]"); + } + else if (*input == '^') // handle colour codes + { + //printf("[col:"); + *output=*input; + input++; + output++; + if (*input == 0) break; + if (*input != 'c') + { + //printf("?%c]",*input); + *output=*input; + input++; + output++; + continue; + } + *output=*input; + input++; + output++; + if (*input == 0) break; + if (*input == '+') + { + //printf("+"); + *output=*input; + input++; + output++; + if (*input == 0) break; + } + //printf("%c]",*input); + *output=*input; + input++; + output++; + continue; + } + else + { + //printf("%c",*input); + } + if (curlength >= STAT_CHARS_PER_LINE) + { + //printf("[LEN]\n"); + if (endinput != NULL) + { + *endoutput = '\0'; + return (endinput + 1); + } + else + { + *output = '\0'; + return input; + } + } + *output=*input; + curlength++; + input++; + output++; + } + //printf("[EOS]\n"); + *output='\0'; + return input; +} + +KERN_API_CALL(kern_ui_paginate_text) +{ + struct kern_append_info info; + + /* initialize the context used by the callback to append objects */ + info.sc = sc; + info.head = sc->NIL; + info.tail = sc->NIL; + info.filter = NULL; + info.data = NULL; + + while (scm_is_pair(sc, args)) + { + char *line; + if (unpack(sc, &args, "s", &line)) + { + rt_err("kern-ui-paginate-text: bad text line"); + break; + } + // shortcut empty strings + if (*line == '\0') + { + pointer paginated_string_element=scm_mk_string(sc,line); + kern_list_append_pointer(&info, paginated_string_element); + continue; + } + + char *buffer; + int totallen = strlen(line); + buffer = (char *)malloc((1+totallen)*sizeof(char)); + assert(buffer); + assert(line[totallen]==0); + + char* seek=line; + while (*seek != 0) + { + *buffer='\0'; + seek = kern_paginate_text(seek,buffer); + pointer paginated_string_element=scm_mk_string(sc,buffer); + kern_list_append_pointer(&info, paginated_string_element); + } + + free(buffer); + } + + /* unprotect the list prior to return */ + if (info.head != sc->NIL) + scm_unprotect(sc, info.head); + + return info.head; +} + + +KERN_API_CALL(kern_char_get_skills) +{ + class Character *subj; + struct kern_append_info info; + + /* unpack the character */ + subj = (class Character*)unpack_obj(sc, &args, + "kern-char-get-skills"); + if (!subj) { + return sc->NIL; + } + + /* initialize the relevant list-building info */ + memset(&info, 0, sizeof(info)); + info.sc = sc; + info.head = sc->NIL; + info.tail = sc->NIL; + + /* add species skills */ + if (subj->species + && subj->species->skills) { + kern_add_skill_set(&info, subj->getLevel(), + subj->species->skills); + } + + /* add occupation skills */ + if (subj->occ + && subj->occ->skills) { + kern_add_skill_set(&info, subj->getLevel(), + subj->occ->skills); + } + + /* allow the list to be gc'd when the script is done with it */ + if (info.head != sc->NIL) { + scm_unprotect(sc, info.head); + } + + return info.head; +} + +static pointer kern_build_arm_list(scheme *sc, + class Character *character, + class ArmsType *arm, + int *armsIndex) +{ + /* base case */ + if (! arm) + return sc->NIL; + + /* recursive case */ + return _cons(sc, + scm_mk_ptr(sc, arm), + kern_build_arm_list(sc, + character, + character->getNextArms(armsIndex), + armsIndex), + 0); +} + +KERN_API_CALL(kern_char_get_arms) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, + "kern-char-get-arms"); + if (!character) + return sc->NIL; + + /* recursively enumerate the character's available arms into a + * scheme list */ + int armsIndex=0; + return kern_build_arm_list(sc, + character, + character->enumerateArms(&armsIndex), + &armsIndex); +} + +KERN_API_CALL(kern_char_arm_self) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, + "kern-char-get-weapons"); + if (!character) + return sc->NIL; + + /* recursively enumerate the character's available weapons into a + * scheme list */ + character->armThyself(); + + return scm_mk_ptr(sc, character); +} + +static pointer kern_build_container_list(scheme *sc, + class Container *container, + struct inv_entry *ie) +{ + pointer cell; + + /* base case */ + if (! ie) + return sc->NIL; + + /* make a type/count pair */ + cell = _cons(sc, + scm_mk_ptr(sc, ie->type), + scm_mk_integer(sc, ie->count), + 0); + + /* recursively build a list of such pairs */ + return _cons(sc, + cell, + kern_build_container_list(sc, + container, + container->next(ie, NULL)), + 0); +} + +KERN_API_CALL(kern_char_get_inventory) +{ + class Container *container; + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, + "kern-char-get-inventory"); + if (!character) + return sc->NIL; + + /* grab it's inventory container */ + container = character->getInventoryContainer(); + if (!container) + return sc->NIL; + + /* enumerate its contents into a scheme list */ + return kern_build_container_list(sc, container, container->first(NULL)); +} + +KERN_API_CALL(kern_char_get_hp) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, + "kern-char-get-hp"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getHp()); +} + +KERN_API_CALL(kern_obj_get_hp) +{ + class Object *kobj; + + /* unpack the character */ + kobj = (class Object*)unpack_obj(sc, &args, + "kern-obj-get-hp"); + if (!kobj) + return sc->NIL; + + return scm_mk_integer(sc, kobj->getHp()); +} + +KERN_API_CALL(kern_char_get_max_hp) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, + "kern-char-get-max-hp"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getMaxHp()); +} + +KERN_API_CALL(kern_char_get_max_mana) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, + "kern-char-get-max-mana"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getMaxMana()); +} + +KERN_API_CALL(kern_char_get_level) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-get-level"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getLevel()); +} + + +KERN_API_CALL(kern_char_get_experience_value) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-get-level"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getExperienceValue()); +} + +KERN_API_CALL(kern_char_set_level) +{ + class Character *character; + int val = 0; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-set-level"); + if (!character) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-set-level: bad args"); + return sc->NIL; + } + + character->setLevel(val); + return scm_mk_ptr(sc, character); +} + +KERN_API_CALL(kern_char_get_strength) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-get-strength"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getStrength()); +} + +KERN_API_CALL(kern_char_get_dexterity) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-get-dexterity"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getDexterity()); +} + +KERN_API_CALL(kern_char_get_intelligence) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-get-intelligence"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getIntelligence()); + +} + +KERN_API_CALL(kern_char_get_base_strength) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-get-strength"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getBaseStrength()); +} + +KERN_API_CALL(kern_char_get_base_dexterity) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-get-dexterity"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getBaseDexterity()); +} + +KERN_API_CALL(kern_char_get_base_intelligence) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-get-intelligence"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getBaseIntelligence()); + +} + +KERN_API_CALL(kern_char_set_strength) +{ + class Character *character; + int val = 0; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-set-strength"); + if (!character) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-set-strength: bad args"); + return sc->NIL; + } + + character->setStrength(val); + return scm_mk_ptr(sc, character); +} + +KERN_API_CALL(kern_char_set_dexterity) +{ + class Character *character; + int val = 0; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-set-dexterity"); + if (!character) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-set-dexterity: bad args"); + return sc->NIL; + } + + character->setDexterity(val); + return scm_mk_ptr(sc, character); +} + +KERN_API_CALL(kern_char_set_intelligence) +{ + class Character *character; + int val = 0; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-set-intelligence"); + if (!character) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-set-intelligence: bad args"); + return sc->NIL; + } + + character->setIntelligence(val); + return scm_mk_ptr(sc, character); +} + +KERN_API_CALL(kern_char_get_speed) +{ + class Character *character; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-get-speed"); + if (!character) + return sc->NIL; + + return scm_mk_integer(sc, character->getSpeed()); +} + +KERN_API_CALL(kern_char_set_speed) +{ + class Character *character; + int val = 0; + + /* unpack the character */ + character = (class Character*)unpack_obj(sc, &args, "kern-char-set-speed"); + if (!character) + return sc->NIL; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-char-set-speed: bad args"); + return sc->NIL; + } + + character->setSpeed(val); + return scm_mk_ptr(sc, character); +} + +KERN_API_CALL(kern_obj_get_ap) +{ + class Object *object; + + /* unpack the object */ + object = (class Object*)unpack_obj(sc, &args, "kern-obj-get-ap"); + if (!object) + return sc->NIL; + + return scm_mk_integer(sc, object->getActionPoints()); +} + +KERN_API_CALL(kern_obj_get_count) +{ + class Object *object; + + /* unpack the object */ + object = (class Object*)unpack_obj(sc, &args, "kern-obj-get-count"); + if (!object) + return sc->NIL; + + return scm_mk_integer(sc, object->getCount()); +} + +KERN_API_CALL(kern_arms_type_get_range) +{ + class ArmsType *type; + + /* unpack the type (should be an arms type, but no way to safely + * tell) */ + if (unpack(sc, &args, "p", &type)) { + rt_err("kern-arms-type-get-range"); + return scm_mk_integer(sc, 0); + } + + if (! type) { + rt_err("kern-arms-type-get-range: null type"); + return scm_mk_integer(sc, 0); + } + + /* get the range */ + return scm_mk_integer(sc, type->getRange()); +} + +KERN_API_CALL(kern_arms_type_get_ammo_type) +{ + class ArmsType *type; + class ObjectType *ammo; + + /* unpack the type (should be an arms type, but no way to safely + * tell) */ + if (unpack(sc, &args, "p", &type)) { + rt_err("kern-char-arms-type"); + return sc->NIL; + } + + /* get the ammo type */ + ammo = type->getAmmoType(); + + /* return it, if any */ + return ammo ? scm_mk_ptr(sc, ammo) : sc->NIL; +} + +KERN_API_CALL(kern_arms_type_set_mmode) +{ + class ArmsType *type; + struct mmode *mmode; + + /* unpack the type (should be an arms type, but no way to safely + * tell) */ + if (unpack(sc, &args, "pp", &type, &mmode)) { + rt_err("kern-arms-type-set-mmode"); + return sc->NIL; + } + + if (! type) { + rt_err("kern-arms-type-set-mmode: null type"); + return sc->NIL; + } + + type->setMovementMode(mmode); + + return sc->NIL; +} + + +KERN_API_CALL(kern_arms_type_fire_in_direction) +{ + class ArmsType *type; + struct place *place; + int startx, starty; + int dx,dy; + + /* unpack the type (should be an arms type, but no way to safely + * tell) */ + if (unpack(sc, &args, "p", &type)) { + rt_err("kern_arms_type_fire_in_direction"); + return sc->NIL; + } + + if (unpack_loc(sc, &args, &place, &startx,&starty, "kern_arms_type_fire_in_direction")) + return sc->NIL; + + if (unpack(sc, &args, "dd", &dx,&dy)) { + rt_err("kern_arms_type_fire_in_direction"); + return sc->NIL; + } + + if (! type) { + rt_err("kern_arms_type_fire_in_direction: null type"); + return sc->NIL; + } + + if (! place) { + rt_err("kern_arms_type_fire_in_direction: null place"); + return sc->NIL; + } + + type->fireInDirection(place, startx, starty, dx, dy, NULL); + + return sc->NIL; +} + +KERN_API_CALL(kern_obj_move) +{ + class Object *object; + int dx, dy; + enum MoveResult result; + + object = (Object*)unpack_obj(sc, &args, "kern-obj-move"); + if (!object) + return sc->F; + + if (unpack(sc, &args, "dd", &dx, &dy)) + { + rt_err("kern-obj-move: bad args"); + return sc->F; + } + + //moves can have nasty consequences, + //so keep our own ref to the object for a bit + obj_inc_ref(object); + result = object->move(dx, dy); + obj_dec_ref(object); + + switch (result) + { + case MovedOk: + case ExitedMap: + case SwitchedOccupants: + return sc->T; + break; + default: + return sc->F; + } +} + +KERN_API_CALL(kern_get_ticks) +{ + return scm_mk_integer(sc, SDL_GetTicks()); +} + +KERN_API_CALL(kern_ticks_per_turn) +{ + return scm_mk_integer(sc, session_ticks_per_turn()); +} + +static int kern_obj_is_type(class Object *obj, struct kern_append_info *info) +{ + return (obj->getObjectType() == (class ObjectType*)info->data); +} + +static void kern_append_loc(Object *obj, void *data) +{ + pointer cell; + struct kern_append_info *info; + + info = (struct kern_append_info *)data; + + /* If there is a filter then use it */ + if (info->filter != NULL) + + /* If the filter rejects the object then don't append it */ + if (! info->filter(obj, info)) + return; + + cell = scm_mk_loc(info->sc, obj->getPlace(), obj->getX(), obj->getY()); + cell = _cons(info->sc, cell, info->sc->NIL, 0); + + if (info->head == info->sc->NIL) { + info->head = cell; + info->tail = cell; + scm_protect(info->sc, cell); + } else { + info->tail->_object._cons._cdr = cell; + info->tail = cell; + } +} + +KERN_API_CALL(kern_search_rect) +{ + struct place *place; + int ulc_x, ulc_y, w, h, lrc_x, lrc_y, x, y; + struct terrain *ter; + class ObjectType *objtype; + struct kern_append_info info; + + /* unpack the args */ + if (unpack(sc, &args, "pddddpp", &place, &ulc_x, &ulc_y, &w, &h, + &ter, &objtype)) { + rt_err("kern-search-rect: bad args"); + return sc->NIL; + } + + /* check the place */ + if (! place) { + rt_err("kern-search-rect: null place"); + return sc->NIL; + } + + /* clip the rectangle */ + lrc_x = ulc_x + w; + lrc_y = ulc_y + h; + place_clip_to_map(place, &ulc_x, &ulc_y); + place_clip_to_map(place, &lrc_x, &lrc_y); + + /* prepare to search */ + info.sc = sc; + info.head = sc->NIL; + info.tail = sc->NIL; + info.filter = kern_obj_is_type; + info.data = objtype; + + /* iterate over the tiles */ + for (y = ulc_y; y < lrc_y; y++) { + for (x = ulc_x; x < lrc_x; x++) { + + /* check if terrain matches */ + if (place_get_terrain(place, x, y) == ter) { + + pointer cell = scm_mk_loc(info.sc, + place, x, y); + cell = _cons(info.sc, cell, info.sc->NIL, 0); + + if (info.head == info.sc->NIL) { + info.head = cell; + info.tail = cell; + scm_protect(sc, cell); + } else { + info.tail->_object._cons._cdr = cell; + info.tail = cell; + } + + + } else { + + /* check for an object match */ + place_for_each_object_at(place, x, y, + kern_append_loc, + &info); + } + } + } + + /* unprotect the list prior to returning */ + if (info.head != sc->NIL) + scm_unprotect(sc, info.head); + + return info.head; +} + +KERN_API_CALL(kern_search_rect_for_obj_type) +{ + struct place *place; + int ulc_x, ulc_y, w, h, lrc_x, lrc_y, x, y; + class ObjectType *objtype; + struct kern_append_info info; + + /* unpack the args */ + if (unpack(sc, &args, "pddddp", &place, &ulc_x, &ulc_y, &w, &h, + &objtype)) { + rt_err("kern-search-rect-for-obj-type: bad args"); + return sc->NIL; + } + + /* check the place */ + if (! place) { + rt_err("kern-search-rect-for-obj-type: null place"); + return sc->NIL; + } + + /* clip the rectangle */ + lrc_x = ulc_x + w; + lrc_y = ulc_y + h; + place_clip_to_map(place, &ulc_x, &ulc_y); + place_clip_to_map(place, &lrc_x, &lrc_y); + + /* prepare to search */ + info.sc = sc; + info.head = sc->NIL; + info.tail = sc->NIL; + info.filter = kern_obj_is_type; + info.data = objtype; + + /* iterate over the tiles */ + for (y = ulc_y; y < lrc_y; y++) { + for (x = ulc_x; x < lrc_x; x++) { + + /* check for an object match */ + place_for_each_object_at(place, x, y, + kern_append_loc, + &info); + } + } + + /* unprotect the list prior to returning */ + if (info.head != sc->NIL) + scm_unprotect(sc, info.head); + + return info.head; +} + +KERN_API_CALL(kern_search_rect_for_terrain) +{ + struct place *place; + int ulc_x, ulc_y, w, h, lrc_x, lrc_y, x, y; + struct terrain *ter; + pointer cell; + struct kern_append_info info; + + /* unpack the args */ + if (unpack(sc, &args, "pddddp", &place, &ulc_x, &ulc_y, &w, &h, + &ter)) { + rt_err("kern-search-rect-for-terrain: bad args"); + return sc->NIL; + } + + /* check the place */ + if (! place) { + rt_err("kern-search-rect-for-terrain: null place"); + return sc->NIL; + } + + /* clip the rectangle */ + lrc_x = ulc_x + w; + lrc_y = ulc_y + h; + place_clip_to_map(place, &ulc_x, &ulc_y); + place_clip_to_map(place, &lrc_x, &lrc_y); + + /* prepare to search */ + info.sc = sc; + info.head = sc->NIL; + info.tail = sc->NIL; + info.filter = NULL; + + /* iterate over the tiles */ + for (y = ulc_y; y < lrc_y; y++) { + for (x = ulc_x; x < lrc_x; x++) { + + /* check if terrain matches */ + if (place_get_terrain(place, x, y) != ter) + continue; + + /* make a scheme-style loc */ + cell = scm_mk_loc(info.sc, place, x, y); + + /* make it a list element */ + cell = _cons(info.sc, cell, info.sc->NIL, 0); + + /* append it to the list */ + if (info.head == info.sc->NIL) { + info.head = cell; + info.tail = cell; + } else { + info.tail->_object._cons._cdr = cell; + info.tail = cell; + } + } + } + + /* unprotect the list prior to returning */ + if (info.head != sc->NIL) + scm_unprotect(sc, info.head); + + /* return the list of locations */ + return info.head; +} + + +KERN_API_CALL(kern_fold_rect) +{ + struct place *place; + int ulc_x, ulc_y, w, h, lrc_x, lrc_y, x, y; + pointer proc; + pointer val; + + /* unpack the args */ + if (unpack(sc, &args, "pdddd", &place, &ulc_x, &ulc_y, &w, &h)) { + rt_err("kern-fold-rect: bad args"); + return sc->NIL; + } + + /* check the place */ + if (! place) { + rt_err("kern-fold-rect: null place"); + return sc->NIL; + } + + /* get a ptr to the procedure */ + if (! scm_is_pair(sc, args)) { + rt_err("kern-fold-rect: no proc arg"); + return sc->NIL; + } + proc = scm_car(sc, args); + args = scm_cdr(sc, args); + + /* get a ptr to the initial value */ + if (! scm_is_pair(sc, args)) { + rt_err("kern-fold-rect: no proc arg"); + return sc->NIL; + } + val = scm_car(sc, args); + args = scm_cdr(sc, args); + + /* clip the rectangle */ + lrc_x = ulc_x + w; + lrc_y = ulc_y + h; + place_clip_to_map(place, &ulc_x, &ulc_y); + place_clip_to_map(place, &lrc_x, &lrc_y); + + /* iterate over the tiles */ + for (y = ulc_y; y < lrc_y; y++) { + for (x = ulc_x; x < lrc_x; x++) { + + /* val may be unreferenced by the script, so protect it + * while we allocate cells (I don't think it matters if + * val is immutable, but we could always test that) */ + scm_protect(sc, val); + + /* make the location for the closure callback */ + pointer loc = scm_mk_loc(sc, place, x, y); + + /* NOTE: don't need to protect the loc, the args to + * _cons are always protected within it */ + + /* make the arg list (val, loc) */ + pointer pargs = _cons(sc, val, + _cons(sc, loc, sc->NIL, 0), 0); + + /* done with allocations, so val does not need + * protection any more */ + scm_unprotect(sc, val); + + /* call the procedure, storing the return val for + * later */ + val = scheme_call(sc, proc, pargs); + } + } + + return val; +} + +KERN_API_CALL(kern_player_get_gold) +{ + return scm_mk_integer(sc, player_party->gold); +} + +KERN_API_CALL(kern_player_set_gold) +{ + int val; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-player-set-gold: bad args"); + return sc->F; + } + + player_party->gold = val; + foogodRepaint(); + return sc->T; +} + +KERN_API_CALL(kern_player_get_food) +{ + return scm_mk_integer(sc, player_party->food); +} + +KERN_API_CALL(kern_player_set_food) +{ + int val; + + if (unpack(sc, &args, "d", &val)) { + rt_err("kern-player-set-food: bad args"); + return sc->F; + } + + player_party->food = val; + foogodRepaint(); + return sc->T; +} + +KERN_API_CALL(kern_begin_combat) +{ + struct move_info info; + struct combat_info cinfo; + class Party *party; + struct place *place; + int x, y; + + if (unpack_loc(sc, &args, &place, &x, &y, "kern-begin-combat")) { + return sc->NIL; + } + + party = (class Party*)unpack_obj(sc, &args, "kern-begin-combat"); + if (!party) + return sc->NIL; + + /* Combat expects the npc party to have valid coords, whereas I don't + * expect the script to always put the npc party on the map before + * calling this function, so force the location of the npc party to the + * location specified. */ + party->setPlace(place); + party->setX(x); + party->setY(y); + + memset(&info, 0, sizeof(info)); + info.place = place; + info.x = x; + info.y = y; + info.dx = party->getDx(); + info.dy = party->getDy(); + info.px = player_party->getX(); + info.py = player_party->getY(); + info.npc_party = party; + + /* If the npc party has a null or invalid direction vector (this is the + * case with an ambush) then use the opposite of the player's direction + * vector. */ + if ((!info.dx && !info.dy) || + (info.dx && info.dy)) { + info.dx = - player_party->getDx(); + info.dy = - player_party->getDy(); + } + + memset(&cinfo, 0, sizeof(cinfo)); + cinfo.defend = true; + cinfo.move = &info; + + combat_enter(&cinfo); + return sc->T; +} + +KERN_API_CALL(kern_ambush_while_camping) +{ + class Party *party; + int dx, dy; + struct place *place; + + /* we need to be in town or wilderness combat for this to work; this + * will leak memory if it fails and the caller does not destroy the + * party */ + if (place_is_wilderness(Place)) { + rt_err("kern-ambush-while-camping: not in combat"); + return sc->F; + } + + /* unpack the npc party */ + party = (class Party*)unpack_obj(sc, &args, "kern-ambush-while-camping"); + if (!party) + return sc->F; + + if (unpack(sc, &args, "p", &place)) { + rt_err("kern-ambush-while-camping: bad args"); + return sc->F; + } + + if (! place) { + rt_err("kern-ambush-while-camping: null place"); + return sc->F; + } + + /* Workaround for 1808708: if both the player and npc party are in + * vehicles then don't do the normal ambush routine (the combat map + * will be wrong). Instead, let's just wake the player up. */ + if (party->getVehicle() + && player_party->getVehicle()) { + + log_begin(0); + Session->subject = player_party; + party->describe(); + log_continue(" approaches!"); + log_end(0); + + player_party->endCamping(); + player_party->removeMembers(); + return sc->T; + } + + /* If the npc party has a null or invalid direction vector then + * generate a random one. */ + dx = party->getDx(); + dy = party->getDy(); + while (! dx && ! dy) { + /* gmcnutt: the following is not random. Was there a reason for + * it? */ + //dx = - player_party->getDx(); + //dy = - player_party->getDy(); + dx = (rand() % 3) - 1; + dy = (rand() % 3) - 1; + } + + /* Partial bugfix for 1612006: If the player is on impassable terrain, + * and the npc is in a vehicle, disembark first, and move them directly + * over the player's location. This prevents ships from coming ashore + * onto your camping map (and bringing part of the ocean with them). */ + if (! place_is_passable(player_party->getPlace(), + player_party->getX(), + player_party->getY(), + party, 0) + && party->getVehicle()) { + int newx = player_party->getX(); + int newy = player_party->getY(); + party->disembark(); + place_move_object(party->getPlace(), party, newx, newy); + party->setX(newx); + party->setY(newy); + } + + if (combat_add_party(party, dx, dy, 0, place, 0, 0)) { + player_party->ambushWhileCamping(); + return sc->T; + } + return sc->F; +} + +/* + * kern_being_pathfind_to -- wrapper for Being::pathfindTo + */ +KERN_API_CALL(kern_being_pathfind_to) +{ + class Being *being; + struct place *place; + int x, y; + + /* unpack being */ + being = (class Being*)unpack_obj(sc, &args, "kern-being-pathfind-to"); + if (! being) + return sc->F; + + /* unpack destination */ + if (unpack_loc(sc, &args, &place, &x, &y, "kern-being-pathfind-to")) + return sc->F; + + //moves can have nasty consequences, + //so keep our own ref to the object for a bit + obj_inc_ref(being); + + + /* pathfind */ + if (being->pathfindTo(place, x, y)) + { + obj_dec_ref(being); + return sc->T; + } + obj_dec_ref(being); + return sc->F; +} + +KERN_API_CALL(kern_get_player) +{ + return scm_mk_ptr(sc, player_party); +} + +KERN_API_CALL(kern_species_get_hp_mod) +{ + struct species *species; + + if (unpack(sc, &args, "p", &species)) { + rt_err("kern-species-get-hp-mod: bad args"); + return scm_mk_integer(sc, 0); + } + + if (! species) { + rt_err("kern-species-get-hp-mod: null species"); + return scm_mk_integer(sc, 0); + } + + return scm_mk_integer(sc, species->hp_mod); +} + +KERN_API_CALL(kern_species_get_hp_mult) +{ + struct species *species; + + if (unpack(sc, &args, "p", &species)) { + rt_err("kern-species-get-hp-mult: bad args"); + return scm_mk_integer(sc, 0); + } + + if (! species) { + rt_err("kern-species-get-hp-mult: null species"); + return scm_mk_integer(sc, 0); + } + + return scm_mk_integer(sc, species->hp_mult); +} + +KERN_API_CALL(kern_species_get_mp_mod) +{ + struct species *species; + + if (unpack(sc, &args, "p", &species)) { + rt_err("kern-species-get-mp-mod: bad args"); + return scm_mk_integer(sc, 0); + } + + if (! species) { + rt_err("kern-species-get-mp-mod: null species"); + return scm_mk_integer(sc, 0); + } + + return scm_mk_integer(sc, species->mp_mod); +} + +KERN_API_CALL(kern_species_get_mp_mult) +{ + struct species *species; + + if (unpack(sc, &args, "p", &species)) { + rt_err("kern-species-get-mp-mult: bad args"); + return scm_mk_integer(sc, 0); + } + + if (! species) { + rt_err("kern-species-get-mp-mult: null species"); + return scm_mk_integer(sc, 0); + } + + return scm_mk_integer(sc, species->mp_mult); +} + +KERN_API_CALL(kern_occ_get_hp_mod) +{ + struct occ *occ; + + if (unpack(sc, &args, "p", &occ)) { + rt_err("kern-occ-get-hp-mod: bad args"); + return scm_mk_integer(sc, 0); + } + + if (! occ) { + rt_err("kern-occ-get-hp-mod: null occ"); + return scm_mk_integer(sc, 0); + } + + return scm_mk_integer(sc, occ->hp_mod); +} + +KERN_API_CALL(kern_occ_get_hp_mult) +{ + struct occ *occ; + + if (unpack(sc, &args, "p", &occ)) { + rt_err("kern-occ-get-hp-mult: bad args"); + return scm_mk_integer(sc, 0); + } + + if (! occ) { + rt_err("kern-occ-get-hp-mult: null occ"); + return scm_mk_integer(sc, 0); + } + + return scm_mk_integer(sc, occ->hp_mult); +} + +KERN_API_CALL(kern_occ_get_mp_mod) +{ + struct occ *occ; + + if (unpack(sc, &args, "p", &occ)) { + rt_err("kern-occ-get-mp-mod: bad args"); + return scm_mk_integer(sc, 0); + } + + if (! occ) { + rt_err("kern-occ-get-mp-mod: null occ"); + return scm_mk_integer(sc, 0); + } + + return scm_mk_integer(sc, occ->mp_mod); +} + +KERN_API_CALL(kern_occ_get_mp_mult) +{ + struct occ *occ; + + if (unpack(sc, &args, "p", &occ)) { + rt_err("kern-occ-get-mp-mult: bad args"); + return scm_mk_integer(sc, 0); + } + + if (! occ) { + rt_err("kern-occ-get-mp-mult: null occ"); + return scm_mk_integer(sc, 0); + } + + return scm_mk_integer(sc, occ->mp_mult); +} + +KERN_API_CALL(kern_occ_get_gob) +{ + struct occ *occ; + + if (unpack(sc, &args, "p", &occ)) { + rt_err("kern-occ-get-gob: bad args"); + return sc->NIL; + } + + if (! occ) { + rt_err("kern-occ-get-gob: null occ"); + return sc->NIL; + } + + if (occ->gob == NULL) + { + return sc->NIL; + } + + // It's already a scheme pointer so just return it directly + return occ->gob->p; +} + +KERN_API_CALL(kern_occ_set_gob) +{ + + struct occ *occ; + + if (unpack(sc, &args, "p", &occ)) { + rt_err("kern-occ-set-gob: bad args"); + return sc->NIL; + } + + if (! scm_is_pair(sc, args)) { + rt_err("kern-occ-set-gob: no gob specified"); + return sc->NIL; + } + + occ->gob = gob_new(sc, scm_car(sc, args)); + + return sc->NIL; +} + +KERN_API_CALL(kern_end_game) +{ + Quit = true; + return sc->NIL; +} + +KERN_API_CALL(kern_sprite_clone) +{ + struct sprite *orig, *clone; + char *tag; + + if (unpack(sc, &args, "py", &orig, &tag)) { + rt_err("kern-sprite-clone: bad args"); + return sc->NIL; + } + clone = sprite_clone(orig, tag); + if (clone) { + pointer ret = scm_mk_ptr(sc, clone); + session_add(Session, clone, sprite_dtor, NULL, NULL); + + /* Tags are optional on clones, but only clones with tags will + * be assigned to scheme variables. */ + if (tag) { + scm_define(sc, tag, ret); + } + return ret; + } + return sc->NIL; +} + +KERN_API_CALL(kern_sprite_append_decoration) +{ + struct sprite *orig, *decor; + + if (unpack(sc, &args, "pp", &orig, &decor)) { + rt_err("kern-sprite-append-decoration: bad args"); + return sc->NIL; + } + if (!orig || ! decor) { + rt_err("kern-sprite-append-decoration: null arg"); + return sc->NIL; + } + sprite_append_decoration(orig, decor); + return scm_mk_ptr(sc, orig); +} + +KERN_API_CALL(kern_sprite_blit_over) +{ + struct sprite *orig, *decor; + + if (unpack(sc, &args, "pp", &orig, &decor)) { + rt_err("kern-sprite-append-decoration: bad args"); + return sc->NIL; + } + if (!orig || ! decor) { + rt_err("kern-sprite-append-decoration: null arg"); + return sc->NIL; + } + sprite_blit_over(orig, decor); + return scm_mk_ptr(sc, orig); +} + +KERN_API_CALL(kern_sprite_strip_decorations) +{ + struct sprite *orig; + + if (unpack(sc, &args, "p", &orig)) { + rt_err("kern-sprite-strip-decoration: bad args"); + return sc->NIL; + } + sprite_strip_decorations(orig); + return scm_mk_ptr(sc, orig); +} + +KERN_API_CALL(kern_sprite_apply_matrix) +{ + struct sprite *sprite; + float matrix[4][3]; + int row; + pointer pcol; + + /* unpack the sprite */ + if (unpack(sc, &args, "p", &sprite)) { + load_err("kern-sprite-apply-matrix: bad args"); + return sc->NIL; + } + + if (!scm_is_pair(sc, args)) { + load_err("kern-sprite-apply-matrix: no matrix!"); + goto abort; + } + args = scm_car(sc, args); + + /* unpack the matrix */ + for (row = 0; row < 4; row++) { + if (! scm_is_pair(sc, args)) { + load_err("kern-sprite-apply-matrix: only %d of 4 rows!", row); + goto abort; + } + pcol = scm_car(sc, args); + args = scm_cdr(sc, args); + if (unpack(sc, &pcol, "fff", &matrix[row][0], + &matrix[row][1], + &matrix[row][2])) { + load_err("kern-sprite-apply-matrix: bad args in row %d!", row); + goto abort; + } + } + + sprite_apply_matrix(sprite, matrix); + abort: + return scm_mk_ptr(sc, sprite); +} + + +KERN_API_CALL(kern_los_invalidate) +{ + vmask_flush_all(); + return sc->T; +} + +KERN_API_CALL(kern_cfg_set) +{ + char *key, *val; + + while (scm_is_pair(sc, args)) { + if (unpack(sc, &args, "ss", &key, &val)) { + rt_err("kern-cfg-set: bad args"); + return sc->NIL; + } + cfg_set(key, val); + } + return sc->NIL; +} + +KERN_API_CALL(kern_cfg_get) +{ + char *key, *val; + + if (unpack(sc, &args, "s", &key)) { + rt_err("kern-cfg-get: bad args"); + return sc->NIL; + } + val = cfg_get(key); + if (!val) + return sc->NIL; + return scm_mk_string(sc, cfg_get(key)); +} + +KERN_API_CALL(kern_set_kern_intvar) +{ + char *key; + int value; + + while (scm_is_pair(sc, args)) { + if (unpack(sc, &args, "sd", &key, &value)) { + rt_err("kern-set-kern-intvar: bad args"); + return sc->NIL; + } + kern_intvar_set(key, value); + } + return sc->NIL; +} + +KERN_API_CALL(kern_get_kern_intvar) +{ + char *key; + int value; + + if (unpack(sc, &args, "s", &key)) { + rt_err("kern_get_kern_intvar: bad args"); + return sc->NIL; + } + value = kern_intvar_get(key); + + return scm_mk_integer(sc, value); +} + +KERN_API_CALL(kern_add_save_game) +{ + char *fname; + + while (scm_is_pair(sc, args)) { + if (unpack(sc, &args, "s", &fname)) { + rt_err("kern-add-save-game: bad args"); + } + menu_add_saved_game(fname); + } + + return sc->NIL; +} + +KERN_API_CALL(kern_type_set_gob) +{ + ObjectType *type = 0; + + if (unpack(sc, &args, "p", &type)) { + rt_err("kern-type-set-gob: bad args"); + return sc->NIL; + } + + if (! scm_is_pair(sc, args)) { + rt_err("kern-type-set-gob: no gob specified"); + } else { + type->setGob(gob_new(sc, scm_car(sc, args))); + } + + return scm_mk_ptr(sc, type); +} + +KERN_API_CALL(kern_type_set_quest_item_flag) +{ + ObjectType *type = 0; + int val = 0; + + if (unpack(sc, &args, "pb", &type, &val)) { + rt_err("kern-type-set-quest-item-flag: bad args"); + return sc->NIL; + } + + type->setQuestItemFlag(val); + return sc->NIL; +} + +KERN_API_CALL(kern_type_get_gob) +{ + ObjectType *type = 0; + + if (unpack(sc, &args, "p", &type)) { + rt_err("kern-type-get-gob: bad args"); + return sc->NIL; + } + + if (!type) { + rt_err("kern-type-get-gob: null obj"); + return sc->NIL; + } + + if (! type->getGob()) { + return sc->NIL; + } + + return type->getGob()->p; +} + +KERN_API_CALL(kern_set_quicken_sprite) +{ + struct sprite *sprite; + if (unpack(sc, &args, "p", &sprite)) { + load_err("kern-set-quicken-sprite: bad args"); + return sc->F; + } + quicken_effect_sprite() = sprite; + return sc->T; +} + +KERN_API_CALL(kern_set_magic_negated_sprite) +{ + struct sprite *sprite; + if (unpack(sc, &args, "p", &sprite)) { + load_err("kern-set-magic-negated-sprite: bad args"); + return sc->F; + } + magic_negated_effect_sprite() = sprite; + return sc->T; +} + +KERN_API_CALL(kern_set_reveal_sprite) +{ + struct sprite *sprite; + if (unpack(sc, &args, "p", &sprite)) { + load_err("kern-set-reveal-sprite: bad args"); + return sc->F; + } + reveal_effect_sprite() = sprite; + return sc->T; +} + +KERN_API_CALL(kern_set_xray_vision_sprite) +{ + struct sprite *sprite; + if (unpack(sc, &args, "p", &sprite)) { + load_err("kern-set-xray-vision-sprite: bad args"); + return sc->F; + } + xray_vision_effect_sprite() = sprite; + return sc->T; +} + +KERN_API_CALL(kern_set_time_stop_sprite) +{ + struct sprite *sprite; + if (unpack(sc, &args, "p", &sprite)) { + load_err("kern-set-time_stop-sprite: bad args"); + return sc->F; + } + time_stop_effect_sprite() = sprite; + return sc->T; +} + +KERN_API_CALL(kern_obj_set_mmode) +{ + Object *obj; + struct mmode *mmode; + + if (!(obj = unpack_obj(sc, &args, "kern-obj-set-mmode"))) + return sc->NIL; + + if (unpack(sc, &args, "p", &mmode)) { + rt_err("kern-obj-set-mmode: bad args"); + return sc->NIL; + } + + obj->setMovementMode(mmode); + + return scm_mk_ptr(sc, obj); + +} + +KERN_API_CALL(kern_progress_bar_start) +{ + char *title = 0; + unsigned int max_steps = 0; + + if (unpack(sc, &args, "sd", &title, &max_steps)) { + load_err("kern-progress-bar-start: bad args"); + return sc->NIL; + } + + foogod_progress_bar_set_title(title); + foogod_progress_bar_set_max_steps(max_steps); + foogodSetMode(FOOGOD_PROGRESS_BAR); + + return sc->NIL; +} + +KERN_API_CALL(kern_progress_bar_advance) +{ + unsigned int steps = 0; + + if (unpack(sc, &args, "d", &steps)) { + load_err("kern-progress-bar-advance: bad args"); + return sc->NIL; + } + + foogod_progress_bar_advance(steps); + foogodRepaint(); + + return sc->NIL; +} + +KERN_API_CALL(kern_progress_bar_finish) +{ + foogod_progress_bar_finish(); + foogodRepaint(); + + return sc->NIL; +} + +/** + * (kern-ztats-add-pane ) + * + * is (enter ) + * is (scroll ), returning #t iff the scroll was handled + * is (paint ) + * is script info + */ +struct kern_ztats_pane { + struct ztats_pane base; + struct closure *enter, *scroll, *paint, *select; + struct gob *gob; + scheme *sc; + unsigned char added:1; +}; + +static pointer pack_rect(scheme *sc, SDL_Rect *rect) +{ + return pack(sc, "dddd", rect->x, rect->y, rect->w, rect->h); +} + +static void kern_ztats_pane_enter(struct ztats_pane *pane, class Party *party, enum StatusScrollDir via, + SDL_Rect *dims) +{ + struct kern_ztats_pane *kzp = (struct kern_ztats_pane*)pane; + pointer prect = pack_rect(kzp->sc, dims); + scm_protect(kzp->sc, prect); + closure_exec(kzp->enter, "lpdl", kzp->gob->p, party, via, prect); + scm_unprotect(kzp->sc, prect); +} + +static int kern_ztats_pane_scroll(struct ztats_pane *pane, enum StatusScrollDir dir) +{ + struct kern_ztats_pane *kzp = (struct kern_ztats_pane*)pane; + return closure_exec(kzp->scroll, "ld", kzp->gob->p, dir); +} + +static void kern_ztats_pane_paint(struct ztats_pane *pane) +{ + struct kern_ztats_pane *kzp = (struct kern_ztats_pane*)pane; + closure_exec(kzp->paint, "l", kzp->gob->p); +} + +static void kern_ztats_pane_select(struct ztats_pane *pane) +{ + struct kern_ztats_pane *kzp = (struct kern_ztats_pane*)pane; + closure_exec(kzp->select, "l", kzp->gob->p); +} + +static void kern_ztats_pane_dtor(void *val) +{ + struct kern_ztats_pane *kzp = (struct kern_ztats_pane*)val; + + if (kzp->added) { + ztats_rm_pane(&kzp->base); + } + + if (kzp->gob) { + gob_unref(kzp->gob); + } + if (kzp->paint) { + closure_unref(kzp->paint); + } + if (kzp->scroll) { + closure_unref(kzp->scroll); + } + if (kzp->enter) { + closure_unref(kzp->enter); + } + if (kzp->select) { + closure_unref(kzp->select); + } + free(kzp); +} + +static struct ztats_pane_ops kern_ztats_pane_ops = { + kern_ztats_pane_enter, + kern_ztats_pane_scroll, + kern_ztats_pane_paint, + kern_ztats_pane_select +}; + +KERN_API_CALL(kern_ztats_add_pane) +{ + pointer penter, pscroll, ppaint, pselect, pgob; + struct kern_ztats_pane *kzp; + +#ifndef USE_QUESTS + return sc->F; +#endif + + if (unpack(sc, &args, "ooool", &penter, &pscroll, &ppaint, &pselect, &pgob)) { + load_err("kern-ztats-add-pane: bad args"); + return sc->NIL; + } + + if (!(kzp = (struct kern_ztats_pane*)calloc(1, sizeof(*kzp)))) { + load_err("alloc failed"); + return sc->NIL; + } + + kzp->base.ops = &kern_ztats_pane_ops; + kzp->sc = sc; + if (! (kzp->enter = closure_new_ref(sc, penter))) { + goto fail; + } + if (! (kzp->scroll = closure_new_ref(sc, pscroll))) { + goto fail; + } + if (! (kzp->paint = closure_new_ref(sc, ppaint))) { + goto fail; + } + if (! (kzp->select = closure_new_ref(sc, pselect))) { + goto fail; + } + if (! (kzp->gob = gob_new(sc, pgob))) { + goto fail; + } + gob_ref(kzp->gob); + + ztats_add_pane(&kzp->base); + + /* Mark that we've added it so that we remember to remove it in the + * dtor. */ + kzp->added = 1; + + session_add(Session, kzp, kern_ztats_pane_dtor, NULL, NULL); + return sc->T; + + fail: + kern_ztats_pane_dtor(kzp); + return sc->F; +} + +KERN_API_CALL(kern_status_set_title) +{ + char *title; + if (unpack(sc, &args, "s", &title)) { + load_err("%s: bad args", __FUNCTION__); + return sc->NIL; + } + + status_set_title(title); + return sc->T; +} + +/** + * (kern-screen-print ( ) <...>) + * + * are the rect (absolute screen coords) to print to + * are the SP_* #defines in screen.h + * is std printf format plus the color tag extensions of ascii.h + * <...> are the varargs + */ +KERN_API_CALL(kern_screen_print) +{ + static char buf[256]; + int room = sizeof(buf); + char *ptr = buf; + SDL_Rect rect; + int flags = 0; + + if (unpack_rect(sc, &args, &rect)) { + load_err("%s: error unpacking rect", __FUNCTION__); + return sc->NIL; + } + + if (unpack(sc, &args, "d", &flags)) { + load_err("%s: error unpacking flags", __FUNCTION__); + return sc->NIL; + } + + while (scm_is_pair(sc, args) && (room > 1)) { + + pointer val = scm_car(sc, args); + args = scm_cdr(sc, args); + int n = 0; + + if (scm_is_str(sc, val)) { + n = snprintf(ptr, room, scm_str_val(sc, val)); + } else if (scm_is_int(sc, val)) { + n = snprintf(ptr, room, "%ld", scm_int_val(sc, val)); + } else if (scm_is_real(sc, val)) { + n = snprintf(ptr, room, "%f", scm_real_val(sc, val)); + } else { + rt_err("%s: unknown type", __FUNCTION__); + } + + ptr += n; + room -= n; + } + + screenPrint(&rect, flags, buf); + + return sc->NIL; +} + +/** + * (kern-screen-draw-sprite ( ) ) + * + * are the rect (absolute screen coords) to print to + * are the SP_* #defines in screen.h + * is std printf format plus the color tag extensions of ascii.h + * is the sprite to draw + */ +KERN_API_CALL(kern_screen_draw_sprite) +{ + SDL_Rect rect; + int flags = 0; + struct sprite *toblit; + + if (unpack_rect(sc, &args, &rect)) { + load_err("%s: error unpacking rect", __FUNCTION__); + return sc->NIL; + } + + if (unpack(sc, &args, "d", &flags)) { + load_err("%s: error unpacking flags", __FUNCTION__); + return sc->NIL; + } + + if (unpack(sc, &args, "p", &toblit)) { + rt_err("kern-sprite-clone: bad args"); + return sc->NIL; + } + + sprite_paint_direct(toblit, 0, &rect); + + //screenBlit(toblit->rsurf->surf, &toblit->frames[0], &rect); + + return sc->NIL; +} + +/** + * (kern-screen-shade ) + * + * specifies the area of the screen to shade + * is a value from 0 (transparent) to 255 (opaque black) + */ +KERN_API_CALL(kern_screen_shade) +{ + SDL_Rect rect; + int amount; + + if (unpack_rect(sc, &args, &rect)) { + load_err("%s: error unpacking 'screenrect' arg", __FUNCTION__); + return sc->NIL; + } + + if (unpack(sc, &args, "d", &amount)) { + load_err("%s: error unpacking 'amount' arg", __FUNCTION__); + return sc->NIL; + } + + screenShade(&rect, amount); + return sc->NIL; +} + +KERN_API_CALL(kern_screen_erase) +{ + SDL_Rect rect; + + if (unpack_rect(sc, &args, &rect)) { + load_err("%s: error unpacking 'screenrect' arg", __FUNCTION__); + return sc->NIL; + } + + screenErase(&rect); + return sc->T; +} + +KERN_API_CALL(kern_screen_update) +{ + SDL_Rect rect; + + if (unpack_rect(sc, &args, &rect)) { + load_err("%s: error unpacking 'screenrect' arg", __FUNCTION__); + return sc->NIL; + } + + screenUpdate(&rect); + return sc->T; +} + + + +/** + * (kern-event-push-keyhandler ) + * + * is a proc of the form (keyh key keymod) + */ +static int kern_keyh_fx(struct KeyHandler *keyh, int key, int keymod) +{ + DECL_CAST(struct closure, proc, keyh->data); + return closure_exec(proc, "dd", key, keymod) ? 1 : 0; +} + +KERN_API_CALL(kern_event_run_keyhandler) +{ + pointer pclos; + struct closure *proc; + + if (unpack(sc, &args, "o", &pclos)) { + load_err("%s: error in arg", __FUNCTION__); + return sc->F; + } + + if (sc->NIL == pclos) { + load_err("%s: NIL closure arg", __FUNCTION__); + return sc->F; + } + + if (! (proc =closure_new_ref(sc, pclos))) { + load_err("%s: closure_new failed", __FUNCTION__); + return sc->F; + } + + eventRunKeyHandler(kern_keyh_fx, proc); + closure_unref(proc); + return sc->T; +} + +/** + * (kern-applet-run ) + * + * is a proc of form (run ), dims being the screen rect. + * is a proc of form (paint) + */ +struct kern_applet { + struct applet base; + struct closure *run, *paint; + struct gob *gob; + scheme *sc; +}; + +static void kern_applet_run(struct applet *applet, SDL_Rect *dims, struct session *session) +{ + DECL_CAST(struct kern_applet, ka, applet); + pointer prect = pack_rect(ka->sc, dims); + closure_exec(ka->run, "ll", ka->gob->p, prect); +} + +static void kern_applet_paint(struct applet *applet) +{ + DECL_CAST(struct kern_applet, ka, applet); + closure_exec(ka->paint, "l", ka->gob->p); +} + +static void kern_applet_dtor(void *val) +{ + struct kern_applet *ka = (struct kern_applet*)val; + if (ka->gob) { + gob_unref(ka->gob); + } + if (ka->paint) { + closure_unref(ka->paint); + } + if (ka->run) { + closure_unref(ka->run); + } + KERN_FREE(ka); +} + +static struct applet_ops kern_applet_ops = { + kern_applet_run, + kern_applet_paint +}; + +KERN_API_CALL(kern_applet_run) +{ + pointer prun, ppaint, pgob; + struct kern_applet *ka; + + if (unpack(sc, &args, "ool", &prun, &ppaint, &pgob)) { + load_err("%s: bad args", __FUNCTION__); + return sc->NIL; + } + + if (!(ka = KERN_ALLOC(struct kern_applet))) { + load_err("%s: alloc failed", __FUNCTION__); + return sc->NIL; + } + + ka->base.ops = &kern_applet_ops; + ka->sc = sc; + if (! (ka->run = closure_new_ref(sc, prun))) { + goto fail; + } + if (! (ka->paint = closure_new_ref(sc, ppaint))) { + goto fail; + } + if (! (ka->gob = gob_new(sc, pgob))) { + goto fail; + } + gob_ref(ka->gob); + + statusRunApplet(&ka->base); + kern_applet_dtor(ka); + + return sc->T; + + fail: + kern_applet_dtor(ka); + return sc->F; + + +} + +/** + * (kern-define ) + * + * This is a way to define mutable scheme variables that persist across + * sessions. In other words, you can declare a variable in scheme, change + * something about it during the game, and rest assured that when the game + * reloads the value will be the same. By way of contrast, normal statements + * like (define foo (list 'a 6)) define variables for the current session only. + */ + +struct kern_define_data { + scheme *sc; + char *sym; + pointer cell; +}; + +static void kern_define_dtor(void *val) +{ + DECL_CAST(struct kern_define_data, data, val); + free(data->sym); + KERN_FREE(val); +} + +static void kern_define_save(save_t *save, void *val) +{ + DECL_CAST(struct kern_define_data, data, val); + save->write(save, "(kern-define '%s ", data->sym); + scheme_serialize(data->sc, data->cell, save); + save->write(save, ")\n"); +} + +KERN_API_CALL(kern_define) +{ + char *str; + pointer pcell; + struct kern_define_data *data; + + if (unpack(sc, &args, "yl", &str, &pcell)) { + load_err("%s: bad args", __FUNCTION__); + return sc->NIL; + } + + if (!(data = KERN_ALLOC(struct kern_define_data))) { + load_err("%s: alloc failed", __FUNCTION__); + return sc->NIL; + } + + if (!(data->sym = strdup(str))) { + KERN_FREE(data); + load_err("%s: strdup failed", __FUNCTION__); + return sc->NIL; + } + + data->sc = sc; + data->cell = pcell; + session_add(Session, data, kern_define_dtor, kern_define_save, NULL); + scm_define(sc, str, pcell); + return sc->NIL; +} + +KERN_API_CALL(kern_obj_set_portrait) +{ + class Object *obj; + struct sprite *sprite; + + if (unpack(sc, &args, "pp", &obj, &sprite)) { + rt_err("%s: bad args", __FUNCTION__); + return sc->NIL; + } + + if (!obj) { + rt_err("%s: null object", __FUNCTION__); + return sc->NIL; + } + + obj->setPortrait(sprite); + + return scm_mk_ptr(sc, obj); + +} + +KERN_API_CALL(kern_script_version) +{ + char *verstr = NULL; + + if (unpack(sc, &args, "s", &verstr)) { + char buffer[40]; // max length of unsigned int = 10 digits + sprintf(buffer,"%u.%u.%u",Session->major, Session->minor,Session->release); + return scm_mk_string(sc, buffer); + } + + if (sscanf(verstr, "%u.%u.%u", &Session->major, &Session->minor, + &Session->release) != 3) { + load_err("%s: bad version string '%s'", __FUNCTION__, verstr); + return sc->NIL; + } + + return sc->NIL; +} + +KERN_OBSOLETE_CALL(kern_set_ascii); +KERN_OBSOLETE_CALL(kern_set_frame); +KERN_OBSOLETE_CALL(kern_set_cursor); + +static int fincount=0; /* for debug */ +static void kern_finalize(scheme *sc, pointer pp) +{ + class Object *obj = (class Object*)pp; + obj_dec_ref(obj); + fincount++; +} + +scheme *kern_init(void) +{ + scheme *sc; + + sc = (scheme*)malloc(sizeof(*sc)); + if (!sc) { + warn("error: could not allocate interpreter"); + return 0; + } + + if(!scheme_init(sc)) { + warn("load error: could not initialize script interpreter\n"); + free(sc); + return 0; + } + + fincount=0; + scheme_set_custom_finalize(sc, kern_finalize); + + /* Setup the script-to-kernel API */ + + /* kern-arms-type api */ + API_DECL(sc, "kern-arms-type-get-ammo-type", kern_arms_type_get_ammo_type); + API_DECL(sc, "kern-arms-type-get-range", kern_arms_type_get_range); + API_DECL(sc, "kern-arms-type-set-mmode", kern_arms_type_set_mmode); + API_DECL(sc, "kern-arms-type-fire-in-direction", kern_arms_type_fire_in_direction); + + /* kern-astral-body api */ + API_DECL(sc, "kern-astral-body-get-gob", kern_astral_body_get_gob); + API_DECL(sc, "kern-astral-body-get-phase", kern_astral_body_get_phase); + API_DECL(sc, "kern-astral-body-set-gob", kern_astral_body_set_gob); + + /* kern-being-api */ + API_DECL(sc, "kern-being-get-base-faction", kern_being_get_base_faction); + API_DECL(sc, "kern-being-get-current-faction", kern_being_get_current_faction); + API_DECL(sc, "kern-being-get-visible-hostiles", kern_being_get_visible_hostiles); + API_DECL(sc, "kern-being-get-visible-allies", kern_being_get_visible_allies); + API_DECL(sc, "kern-being-get-visible-tiles", kern_being_get_visible_tiles); + API_DECL(sc, "kern-being-is-hostile?", kern_being_is_hostile); + API_DECL(sc, "kern-being-is-ally?", kern_being_is_ally); + API_DECL(sc, "kern-being-set-name", kern_being_set_name); + API_DECL(sc, "kern-being-pathfind-to", kern_being_pathfind_to); + API_DECL(sc, "kern-being-set-base-faction", kern_being_set_base_faction); + API_DECL(sc, "kern-being-set-current-faction", kern_being_set_current_faction); + + /* kern-char api */ + API_DECL(sc, "kern-char-add-defense", kern_char_add_defense); + API_DECL(sc, "kern-char-add-experience", kern_char_add_experience); + API_DECL(sc, "kern-char-arm-self", kern_char_arm_self); + API_DECL(sc, "kern-char-attack", kern_char_attack); + API_DECL(sc, "kern-char-dec-mana", kern_char_dec_mana); + API_DECL(sc, "kern-char-charm", kern_char_charm); + API_DECL(sc, "kern-char-force-drop", kern_char_force_drop); + API_DECL(sc, "kern-char-get-arms", kern_char_get_arms); + API_DECL(sc, "kern-char-get-experience-value", kern_char_get_experience_value); + API_DECL(sc, "kern-char-get-hp", kern_char_get_hp); + API_DECL(sc, "kern-char-get-inventory", kern_char_get_inventory); + API_DECL(sc, "kern-char-get-level", kern_char_get_level); + API_DECL(sc, "kern-char-get-mana", kern_char_get_mana); + API_DECL(sc, "kern-char-get-occ", kern_char_get_occ); + API_DECL(sc, "kern-char-get-max-hp", kern_char_get_max_hp); + API_DECL(sc, "kern-char-get-max-mana", kern_char_get_max_mana); + API_DECL(sc, "kern-char-get-party", kern_char_get_party); + API_DECL(sc, "kern-char-get-readied-weapons", kern_char_get_readied_weapons); + API_DECL(sc, "kern-char-get-species", kern_char_get_species); + API_DECL(sc, "kern-char-get-strength", kern_char_get_strength); + API_DECL(sc, "kern-char-get-dexterity", kern_char_get_dexterity); + API_DECL(sc, "kern-char-get-intelligence", kern_char_get_intelligence); + API_DECL(sc, "kern-char-get-base-strength", kern_char_get_base_strength); + API_DECL(sc, "kern-char-get-base-dexterity", kern_char_get_base_dexterity); + API_DECL(sc, "kern-char-get-base-intelligence", kern_char_get_base_intelligence); + API_DECL(sc, "kern-char-set-sched", kern_char_set_sched); + API_DECL(sc, "kern-char-set-speed", kern_char_set_speed); + API_DECL(sc, "kern-char-get-speed", kern_char_get_speed); + API_DECL(sc, "kern-char-set-strength", kern_char_set_strength); + API_DECL(sc, "kern-char-set-dexterity", kern_char_set_dexterity); + API_DECL(sc, "kern-char-set-intelligence", kern_char_set_intelligence); + API_DECL(sc, "kern-char-task-abort", kern_char_task_abort); + API_DECL(sc, "kern-char-task-begin", kern_char_task_begin); + API_DECL(sc, "kern-char-task-continue", kern_char_task_continue); + API_DECL(sc, "kern-char-task-end", kern_char_task_end); + API_DECL(sc, "kern-char-get-skills", kern_char_get_skills); + API_DECL(sc, "kern-char-get-weapons", kern_char_get_weapons); + API_DECL(sc, "kern-char-is-asleep?", kern_char_is_asleep); + API_DECL(sc, "kern-char-is-dead?", kern_char_is_dead); + API_DECL(sc, "kern-char-is-known?", kern_char_is_known); + API_DECL(sc, "kern-char-join-player", kern_char_join_player); + API_DECL(sc, "kern-char-kill", kern_char_kill); + API_DECL(sc, "kern-char-leave-player", kern_char_leave_player); + API_DECL(sc, "kern-char-resurrect", kern_char_resurrect); + API_DECL(sc, "kern-char-set-ai", kern_char_set_ai); + API_DECL(sc, "kern-char-set-control-mode", kern_char_set_control_mode); + API_DECL(sc, "kern-char-set-fleeing", kern_char_set_fleeing); + API_DECL(sc, "kern-char-set-hp", kern_char_set_hp); + API_DECL(sc, "kern-char-set-known", kern_char_set_known); + API_DECL(sc, "kern-char-set-level", kern_char_set_level); + API_DECL(sc, "kern-char-set-mana", kern_char_set_mana); + API_DECL(sc, "kern-char-set-player-controlled", kern_char_set_player_controlled); + API_DECL(sc, "kern-char-set-schedule", kern_char_set_schedule); + API_DECL(sc, "kern-char-set-sleep", kern_char_set_sleep); + API_DECL(sc, "kern-char-uncharm", kern_char_uncharm); + API_DECL(sc, "kern-char-unready", kern_char_unready); + + /* kern-event api */ + API_DECL(sc, "kern-event-run-keyhandler", kern_event_run_keyhandler); + + /* kern-map api */ + API_DECL(sc, "kern-map-rotate", kern_map_rotate); + + /* kern-mk api */ + API_DECL(sc, "kern-mk-arms-type", kern_mk_arms_type); + API_DECL(sc, "kern-mk-astral-body", kern_mk_astral_body); + API_DECL(sc, "kern-mk-blender", kern_mk_blender); + API_DECL(sc, "kern-mk-char", kern_mk_char); + API_DECL(sc, "kern-mk-inventory", kern_mk_inventory); + API_DECL(sc, "kern-mk-effect", kern_mk_effect); + API_DECL(sc, "kern-mk-field", kern_mk_field); + API_DECL(sc, "kern-mk-field-type", kern_mk_field_type); + API_DECL(sc, "kern-mk-map", kern_mk_map); + API_DECL(sc, "kern-mk-missile-type", kern_mk_missile_type); + API_DECL(sc, "kern-mk-composite-map", kern_mk_composite_map); + API_DECL(sc, "kern-mk-mmode", kern_mk_mmode); + API_DECL(sc, "kern-mk-obj", kern_mk_obj); + API_DECL(sc, "kern-mk-obj-type", kern_mk_obj_type); + API_DECL(sc, "kern-mk-occ", kern_mk_occ); + API_DECL(sc, "kern-mk-palette", kern_mk_palette); + API_DECL(sc, "kern-mk-party", kern_mk_party); + API_DECL(sc, "kern-mk-place", kern_mk_place); + API_DECL(sc, "kern-mk-player", kern_mk_player); + API_DECL(sc, "kern-mk-ptable", kern_mk_ptable); + API_DECL(sc, "kern-mk-sched", kern_mk_sched); + API_DECL(sc, "kern-mk-skill", kern_mk_skill); + API_DECL(sc, "kern-mk-skill-set", kern_mk_skill_set); + API_DECL(sc, "kern-mk-sound", kern_mk_sound); + API_DECL(sc, "kern-mk-species", kern_mk_species); + API_DECL(sc, "kern-mk-sprite", kern_mk_sprite); + API_DECL(sc, "kern-mk-sprite-set", kern_mk_sprite_set); + API_DECL(sc, "kern-mk-templ", kern_mk_templ); + API_DECL(sc, "kern-mk-terrain", kern_mk_terrain); + API_DECL(sc, "kern-mk-vehicle", kern_mk_vehicle); + API_DECL(sc, "kern-mk-vehicle-type", kern_mk_vehicle_type); + + /* kern-obj api */ + API_DECL(sc, "kern-obj-add-food", kern_obj_add_food); + API_DECL(sc, "kern-obj-add-gold", kern_obj_add_gold); + API_DECL(sc, "kern-obj-add-effect", kern_obj_add_effect); + API_DECL(sc, "kern-obj-add-to-inventory", kern_obj_add_to_inventory); + API_DECL(sc, "kern-obj-apply-damage", kern_obj_apply_damage); + API_DECL(sc, "kern-obj-inflict-damage", kern_obj_inflict_damage); + API_DECL(sc, "kern-obj-clone", kern_obj_clone); + API_DECL(sc, "kern-obj-dec-ap", kern_obj_dec_ap); + API_DECL(sc, "kern-obj-dec-light", kern_obj_dec_light); + API_DECL(sc, "kern-obj-dec-ref", kern_obj_dec_ref); + /*API_DECL(sc, "kern-obj-destroy", kern_obj_destroy);*/ + API_DECL(sc, "kern-obj-find-path", kern_obj_find_path); + API_DECL(sc, "kern-obj-get-activity", kern_obj_get_activity); + API_DECL(sc, "kern-obj-get-ap", kern_obj_get_ap); + API_DECL(sc, "kern-obj-get-count", kern_obj_get_count); + API_DECL(sc, "kern-obj-get-dir", kern_obj_get_dir); + API_DECL(sc, "kern-obj-get-hp", kern_obj_get_hp); + API_DECL(sc, "kern-obj-get-effects", kern_obj_get_effects); + API_DECL(sc, "kern-obj-get-facing", kern_obj_get_facing); + API_DECL(sc, "kern-obj-get-gob", kern_obj_get_gob); + API_DECL(sc, "kern-obj-get-light", kern_obj_get_light); + API_DECL(sc, "kern-obj-get-location", kern_obj_get_location); + API_DECL(sc, "kern-obj-get-mmode", kern_obj_get_mmode); + API_DECL(sc, "kern-obj-get-movecost", kern_obj_get_movecost); + API_DECL(sc, "kern-obj-get-name", kern_obj_get_name); + API_DECL(sc, "kern-obj-get-sprite", kern_obj_get_sprite); + API_DECL(sc, "kern-obj-get-type", kern_obj_get_type); + API_DECL(sc, "kern-obj-get-vision-radius", kern_obj_get_vision_radius); + API_DECL(sc, "kern-obj-has?", kern_obj_has); + API_DECL(sc, "kern-obj-heal", kern_obj_heal); + API_DECL(sc, "kern-obj-inc-light", kern_obj_inc_light); + API_DECL(sc, "kern-obj-inc-ref", kern_obj_inc_ref); + API_DECL(sc, "kern-obj-is-being?", kern_obj_is_being); + API_DECL(sc, "kern-obj-is-char?", kern_obj_is_char); + API_DECL(sc, "kern-obj-is-container?", kern_obj_is_container); + API_DECL(sc, "kern-obj-is-field?", kern_obj_is_field); + API_DECL(sc, "kern-obj-is-mech?", kern_obj_is_mech); + API_DECL(sc, "kern-obj-is-submerged?", kern_obj_is_submerged); + API_DECL(sc, "kern-obj-is-visible?", kern_obj_is_visible); + API_DECL(sc, "kern-obj-move", kern_obj_move); + API_DECL(sc, "kern-obj-put-at", kern_obj_put_at); + API_DECL(sc, "kern-obj-put-into", kern_obj_put_into); + API_DECL(sc, "kern-obj-relocate", kern_obj_relocate); + API_DECL(sc, "kern-obj-remove", kern_obj_remove); + API_DECL(sc, "kern-obj-remove-effect", kern_obj_remove_effect); + API_DECL(sc, "kern-obj-remove-from-inventory", kern_obj_remove_from_inventory); + API_DECL(sc, "kern-obj-set-ap", kern_obj_set_ap); + API_DECL(sc, "kern-obj-set-conv", kern_obj_set_conv); + API_DECL(sc, "kern-obj-set-facing", kern_obj_set_facing); + API_DECL(sc, "kern-obj-set-gob", kern_obj_set_gob); + API_DECL(sc, "kern-obj-set-ignore-time-stop", kern_obj_set_ignore_time_stop); + API_DECL(sc, "kern-obj-set-light", kern_obj_set_light); + API_DECL(sc, "kern-obj-set-opacity", kern_obj_set_opacity); + API_DECL(sc, "kern-obj-set-pclass", kern_obj_set_pclass); + API_DECL(sc, "kern-obj-set-mmode", kern_obj_set_mmode); + API_DECL(sc, "kern-obj-set-portrait", kern_obj_set_portrait); + API_DECL(sc, "kern-obj-set-sprite", kern_obj_set_sprite); + API_DECL(sc, "kern-obj-set-submerged", kern_obj_set_submerged); + API_DECL(sc, "kern-obj-set-temporary", kern_obj_set_temporary); + API_DECL(sc, "kern-obj-set-ttl", kern_obj_set_ttl); + API_DECL(sc, "kern-obj-set-visible", kern_obj_set_visible); + API_DECL(sc, "kern-obj-wander", kern_obj_wander); + API_DECL(sc, "kern-obj-freeze", kern_obj_freeze); + API_DECL(sc, "kern-obj-thaw", kern_obj_thaw); + + /* kern-occ api */ + API_DECL(sc, "kern-occ-get-hp-mod", kern_occ_get_hp_mod); + API_DECL(sc, "kern-occ-get-hp-mult", kern_occ_get_hp_mult); + API_DECL(sc, "kern-occ-get-mp-mod", kern_occ_get_mp_mod); + API_DECL(sc, "kern-occ-get-mp-mult", kern_occ_get_mp_mult); + API_DECL(sc, "kern-occ-get-gob", kern_occ_get_gob); + API_DECL(sc, "kern-occ-set-gob", kern_occ_set_gob); + + /* kern-place api */ + API_DECL(sc, "kern-place-add-on-entry-hook", kern_place_add_on_entry_hook); + API_DECL(sc, "kern-place-apply-tile-effects", kern_place_apply_tile_effects); + API_DECL(sc, "kern-place-set-subplace", kern_place_set_subplace); + API_DECL(sc, "kern-place-get-beings", kern_place_get_beings); + API_DECL(sc, "kern-place-get-height", kern_place_get_height); + API_DECL(sc, "kern-place-get-light", kern_place_get_light); + API_DECL(sc, "kern-place-get-location", kern_place_get_location); + API_DECL(sc, "kern-place-get-movement-cost", kern_place_get_movement_cost); + API_DECL(sc, "kern-place-get-name", kern_place_get_name); + API_DECL(sc, "kern-place-get-neighbor", kern_place_get_neighbor); + API_DECL(sc, "kern-place-get-objects", kern_place_get_objects); + API_DECL(sc, "kern-place-get-terrain", kern_place_get_terrain); + API_DECL(sc, "kern-place-get-terrain-map", kern_place_get_terrain_map); + API_DECL(sc, "kern-place-get-vehicle", kern_place_get_vehicle); + API_DECL(sc, "kern-place-get-width", kern_place_get_width); + API_DECL(sc, "kern-place-is-passable", kern_place_is_passable); + API_DECL(sc, "kern-place-is-hazardous", kern_place_is_hazardous); + API_DECL(sc, "kern-place-is-wrapping?", kern_place_is_wrapping); + API_DECL(sc, "kern-place-is-wilderness?", kern_place_is_wilderness); + API_DECL(sc, "kern-place-blocks-los?", kern_place_blocks_los); + API_DECL(sc, "kern-place-map", kern_place_map); + API_DECL(sc, "kern-place-move-is-passable?", kern_place_move_is_passable); + API_DECL(sc, "kern-place-set-neighbor", kern_place_set_neighbor); + API_DECL(sc, "kern-place-set-terrain", kern_place_set_terrain); + API_DECL(sc, "kern-place-set-terrain-map", kern_place_set_terrain_map); + API_DECL(sc, "kern-place-synch", kern_place_synch); + API_DECL(sc, "kern-place-is-visible?", kern_place_is_visible); + API_DECL(sc, "kern-place-is-combat-map?", kern_place_is_combat_map); + + /* player api */ + API_DECL(sc, "kern-player-get-food", kern_player_get_food); + API_DECL(sc, "kern-player-get-gold", kern_player_get_gold); + API_DECL(sc, "kern-player-set-follow-mode", kern_player_set_follow_mode); + API_DECL(sc, "kern-player-set-food", kern_player_set_food); + API_DECL(sc, "kern-player-set-gold", kern_player_set_gold); + + /* screen api */ + API_DECL(sc, "kern-screen-erase", kern_screen_erase); + API_DECL(sc, "kern-screen-print", kern_screen_print); + API_DECL(sc, "kern-screen-shade", kern_screen_shade); + API_DECL(sc, "kern-screen-update", kern_screen_update); + API_DECL(sc, "kern-screen-draw-sprite", kern_screen_draw_sprite); + + /* kern-set api */ + API_DECL(sc, "kern-set-crosshair", kern_set_crosshair); + API_DECL(sc, "kern-set-damage-sprite", kern_set_damage_sprite); + API_DECL(sc, "kern-set-clock", kern_set_clock); + + /* kern-species api */ + API_DECL(sc, "kern-species-get-hp-mod", kern_species_get_hp_mod); + API_DECL(sc, "kern-species-get-hp-mult", kern_species_get_hp_mult); + API_DECL(sc, "kern-species-get-mp-mod", kern_species_get_mp_mod); + API_DECL(sc, "kern-species-get-mp-mult", kern_species_get_mp_mult); + + /* kern-terrain api */ + API_DECL(sc, "kern-terrain-blocks-los?", kern_terrain_blocks_los); + API_DECL(sc, "kern-terrain-get-pclass", kern_terrain_get_pclass); + API_DECL(sc, "kern-terrain-set-combat-map", kern_terrain_set_combat_map); + API_DECL(sc, "kern-terrain-set-combat-handler", kern_terrain_set_combat_handler); + API_DECL(sc, "kern-terrain-map-inc-ref", kern_terrain_map_inc_ref); + API_DECL(sc, "kern-terrain-map-dec-ref", kern_terrain_map_dec_ref); + API_DECL(sc, "kern-terrain-map-blend", kern_terrain_map_blend); + API_DECL(sc, "kern-terrainmap-get-width", kern_map_get_width); + API_DECL(sc, "kern-terrainmap-get-height", kern_map_get_height); + + /* kern-type api */ + API_DECL(sc, "kern-type-describe", kern_type_describe); + API_DECL(sc, "kern-type-get-gifc", kern_type_get_gifc); + API_DECL(sc, "kern-type-get-gob", kern_type_get_gob); + API_DECL(sc, "kern-type-get-name", kern_type_get_name); + API_DECL(sc, "kern-type-set-gob", kern_type_set_gob); + API_DECL(sc, "kern-type-set-quest-item-flag", kern_type_set_quest_item_flag); + + /* misc api */ + API_DECL(sc, "kern-add-magic-negated", kern_add_magic_negated); + API_DECL(sc, "kern-add-quicken", kern_add_quicken); + API_DECL(sc, "kern-add-reveal", kern_add_reveal); + API_DECL(sc, "kern-add-save-game", kern_add_save_game); + API_DECL(sc, "kern-add-spell", kern_add_spell); + API_DECL(sc, "kern-add-tick-job", kern_add_tick_job); + API_DECL(sc, "kern-add-time-stop", kern_add_time_stop); + API_DECL(sc, "kern-ambush-while-camping", kern_ambush_while_camping); + API_DECL(sc, "kern-add-xray-vision", kern_add_xray_vision); + API_DECL(sc, "kern-begin-combat", kern_begin_combat); + API_DECL(sc, "kern-blit-map", kern_blit_map); + API_DECL(sc, "kern-init-random", kern_init_random); + API_DECL(sc, "kern-define", kern_define); + API_DECL(sc, "kern-dice-roll", kern_dice_roll); + API_DECL(sc, "kern-end-game" , kern_end_game); + API_DECL(sc, "kern-fire-missile", kern_fire_missile); + API_DECL(sc, "kern-fire-missile-to-max", kern_fire_missile_to_max); + API_DECL(sc, "kern-fold-rect", kern_fold_rect); + API_DECL(sc, "kern-get-distance", kern_get_distance); + API_DECL(sc, "kern-get-objects-at", kern_get_objects_at); + API_DECL(sc, "kern-get-magic-negated", kern_get_magic_negated); + API_DECL(sc, "kern-get-player", kern_get_player); + API_DECL(sc, "kern-get-ticks", kern_get_ticks); + API_DECL(sc, "kern-get-time", kern_get_time); + API_DECL(sc, "kern-time-get-remainder", kern_get_time_remainder); + API_DECL(sc, "kern-get-total-minutes", kern_get_total_minutes); + API_DECL(sc, "kern-harm-relations", kern_harm_relations); + API_DECL(sc, "kern-in-los?", kern_in_los); + API_DECL(sc, "kern-los-invalidate", kern_los_invalidate); + API_DECL(sc, "kern-include", kern_include); + API_DECL(sc, "kern-interp-error", kern_interp_error); + API_DECL(sc, "kern-is-valid-location?", kern_is_valid_location); + API_DECL(sc, "kern-print", kern_print); + API_DECL(sc, "kern-search-rect", kern_search_rect); + API_DECL(sc, "kern-search-rect-for-terrain", + kern_search_rect_for_terrain); + API_DECL(sc, "kern-search-rect-for-obj-type", + kern_search_rect_for_obj_type); + API_DECL(sc, "kern-add-hook", kern_add_hook); + API_DECL(sc, "kern-add-query", kern_add_query); + API_DECL(sc, "kern-rm-hook", kern_rm_hook); + API_DECL(sc, "kern-set-quicken-sprite", kern_set_quicken_sprite); + API_DECL(sc, "kern-set-time-stop-sprite", kern_set_time_stop_sprite); + API_DECL(sc, "kern-set-magic-negated-sprite", kern_set_magic_negated_sprite); + API_DECL(sc, "kern-set-reveal-sprite", kern_set_reveal_sprite); + API_DECL(sc, "kern-set-xray-vision-sprite", kern_set_xray_vision_sprite); + API_DECL(sc, "kern-set-spell-words", kern_set_spell_words); + API_DECL(sc, "kern-set-wind", kern_set_wind); + API_DECL(sc, "kern-get-wind", kern_get_wind); + API_DECL(sc, "kern-set-time-accel", kern_set_time_accel); + API_DECL(sc, "kern-sleep", kern_sleep); + API_DECL(sc, "kern-music-play", kern_music_play); + API_DECL(sc, "kern-sound-play", kern_sound_play); + API_DECL(sc, "kern-sound-play-at", kern_sound_play_at); + API_DECL(sc, "kern-sound-play-ambient", kern_sound_play_ambient); + API_DECL(sc, "kern-tag", kern_tag); + API_DECL(sc, "kern-test-recursion", kern_test_recursion); + API_DECL(sc, "kern-ticks-per-turn", kern_ticks_per_turn); + API_DECL(sc, "kern-set-turn-count", kern_set_turn_count); + API_DECL(sc, "kern-map-flash-sprite", kern_map_flash_sprite); + API_DECL(sc, "kern-script-version", kern_script_version); + + /* ui api */ + API_DECL(sc, "kern-ui-direction", kern_ui_direction); + API_DECL(sc, "kern-ui-paginate-text", kern_ui_paginate_text); + API_DECL(sc, "kern-ui-page-text", kern_ui_page_text); + API_DECL(sc, "kern-ui-select-from-list", kern_ui_select_from_list); + API_DECL(sc, "kern-ui-select-item", kern_ui_select_item); + API_DECL(sc, "kern-ui-select-party-member", kern_ui_select_party_member); + API_DECL(sc, "kern-ui-target", kern_ui_target); + API_DECL(sc, "kern-ui-target-generic", kern_ui_target_generic); + API_DECL(sc, "kern-ui-waitkey", kern_ui_waitkey); + API_DECL(sc, "kern-applet-run", kern_applet_run); + + /* conv api */ + API_DECL(sc, "kern-conv-begin", kern_conv_begin); + API_DECL(sc, "kern-conv-end", kern_conv_end); + API_DECL(sc, "kern-conv-say", kern_conv_say); + API_DECL(sc, "kern-conv-get-amount", kern_conv_get_amount); + API_DECL(sc, "kern-conv-get-yes-no?", kern_conv_get_yes_no); + API_DECL(sc, "kern-conv-trade", kern_conv_trade); + API_DECL(sc, "kern-conv-get-reply", kern_conv_get_reply); + API_DECL(sc, "kern-conv-get-string", kern_conv_get_string); + + /* kern-map api */ + API_DECL(sc, "kern-map-blit-image", kern_map_blit_image); + API_DECL(sc, "kern-map-center-camera", kern_map_center_camera); + API_DECL(sc, "kern-map-flash", kern_map_flash); + API_DECL(sc, "kern-map-repaint", kern_map_repaint); + API_DECL(sc, "kern-map-set-dirty", kern_map_set_dirty); + API_DECL(sc, "kern-map-set-image", kern_map_set_image); + API_DECL(sc, "kern-map-set-jitter", kern_map_set_jitter); + API_DECL(sc, "kern-map-set-peering", kern_map_set_peering); + API_DECL(sc, "kern-map-view-create", kern_map_view_create); + API_DECL(sc, "kern-map-view-destroy", kern_map_view_destroy); + API_DECL(sc, "kern-map-view-center", kern_map_view_center); + API_DECL(sc, "kern-map-view-add", kern_map_view_add); + API_DECL(sc, "kern-map-view-rm", kern_map_view_rm); + API_DECL(sc, "kern-map-view-add", kern_map_view_add); + API_DECL(sc, "kern-map-view-rm", kern_map_view_rm); + + /* kern-log api */ + API_DECL(sc, "kern-log-begin", kern_log_begin); + API_DECL(sc, "kern-log-continue", kern_log_continue); + API_DECL(sc, "kern-log-end", kern_log_end); + API_DECL(sc, "kern-log-enable", kern_log_enable); + API_DECL(sc, "kern-log-flush", kern_log_flush); + API_DECL(sc, "kern-log-msg", kern_log_msg); + API_DECL(sc, "kern-stdout-msg", kern_stdout_msg); + + /* kern-dtable api */ + API_DECL(sc, "kern-mk-dtable", kern_mk_dtable); + API_DECL(sc, "kern-dtable-get", kern_dtable_get); + API_DECL(sc, "kern-dtable-set", kern_dtable_set); + API_DECL(sc, "kern-dtable-inc", kern_dtable_inc); + API_DECL(sc, "kern-dtable-dec", kern_dtable_dec); + + /* kern-party-api */ + API_DECL(sc, "kern-party-add-member", kern_party_add_member); + API_DECL(sc, "kern-party-get-members", kern_party_get_members); + API_DECL(sc, "kern-party-get-vehicle", kern_party_get_vehicle); + API_DECL(sc, "kern-party-set-vehicle", kern_party_set_vehicle); + + /* kern-sprite api */ + API_DECL(sc, "kern-sprite-clone", kern_sprite_clone); + API_DECL(sc, "kern-sprite-append-decoration", kern_sprite_append_decoration); + API_DECL(sc, "kern-sprite-apply-matrix", kern_sprite_apply_matrix); + API_DECL(sc, "kern-sprite-blit-over", kern_sprite_blit_over); + API_DECL(sc, "kern-sprite-strip-decorations", kern_sprite_strip_decorations); + + + /* kern-vehicle-api */ + API_DECL(sc, "kern-vehicle-set-name", kern_vehicle_set_name); + + /* kern-cfg api */ + API_DECL(sc, "kern-cfg-set", kern_cfg_set); + API_DECL(sc, "kern-cfg-get", kern_cfg_get); + + API_DECL(sc, "kern-set-kern-intvar", kern_set_kern_intvar); + API_DECL(sc, "kern-get-kern-intvar", kern_get_kern_intvar); + + + /* kern-image api */ + API_DECL(sc, "kern-image-load", kern_image_load); + API_DECL(sc, "kern-image-free", kern_image_free); + + /* kern-progress-bar api */ + API_DECL(sc, "kern-progress-bar-start", kern_progress_bar_start); + API_DECL(sc, "kern-progress-bar-advance", kern_progress_bar_advance); + API_DECL(sc, "kern-progress-bar-finish", kern_progress_bar_finish); + + /* kern-ztats api */ + API_DECL(sc, "kern-ztats-add-pane", kern_ztats_add_pane); + API_DECL(sc, "kern-status-set-title", kern_status_set_title); + + /* obsolete (keep these until old save games are unlikely to use + * them) */ + API_DECL(sc, "kern-set-frame", kern_set_frame); + API_DECL(sc, "kern-set-cursor", kern_set_cursor); + API_DECL(sc, "kern-set-ascii", kern_set_ascii); + + + /* Revisit: probably want to provide some kind of custom port here. */ + scheme_set_output_port_file(sc, stderr); + + /* Shared constants */ + scm_define_int(sc, "kern-key-esc", SDLK_ESCAPE); + scm_define_int(sc, "kern-key-space", SDLK_SPACE); + scm_define_int(sc, "kern-key-return", '\n'); // remapped in event.c::mapKey + scm_define_int(sc, "kern-key-enter", SDLK_KP_ENTER); + scm_define_int(sc, "kern-key-up", SDLK_KP8); // also handles arrowkeys + scm_define_int(sc, "kern-key-down", SDLK_KP2); // also handles arrowkeys + scm_define_int(sc, "kern-key-kp-pgup", SDLK_KP9); + scm_define_int(sc, "kern-key-kp-pgdn", SDLK_KP3); + scm_define_int(sc, "kern-key-pgup", SDLK_PAGEUP); + scm_define_int(sc, "kern-key-pgdn", SDLK_PAGEDOWN); + scm_define_int(sc, "kern-sp-centered", SP_CENTERED); + scm_define_int(sc, "kern-ascii-h", ASCII_H); + return sc; +} diff --git a/src/kern.h b/src/kern.h new file mode 100644 index 0000000..0b17f59 --- /dev/null +++ b/src/kern.h @@ -0,0 +1,30 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#ifndef kern_h +#define kern_h + +#include "scheme.h" + +scheme * kern_init(void); + +#endif diff --git a/src/kern_intvar.c b/src/kern_intvar.c new file mode 100644 index 0000000..343b15f --- /dev/null +++ b/src/kern_intvar.c @@ -0,0 +1,117 @@ +/* $Id: kern_intvar.c,v 1.3 2010/08/26 05:56:20 gmcnutt Exp $ + * + * Copyright (C) 2006 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + */ + +#include "kern_intvar.h" +// #include "repstr.h" + +#include +#include +#include + +#include + +#define KERN_INTVAR_HASH_SIZE 31 + +struct kern_intvar_entry { + struct kern_intvar_entry *next; + char *key; + int value; +} *kern_intvar_hash[KERN_INTVAR_HASH_SIZE]; + +static struct kern_intvar_entry *kern_intvar_entry_new(const char *key, const int value) +{ + struct kern_intvar_entry *entry = (struct kern_intvar_entry*) malloc(sizeof(*entry)); + assert(entry); + + entry->next = 0; + + entry->key = strdup(key); + assert(entry->key); + + entry->value = value; + + return entry; +} + +static int hashfn(const char *key) +{ + unsigned int hashed = 0; + const char *c; + static const int bits_per_int = sizeof(unsigned int)*8; + + for (c = key; *c; c++) { + /* letters have about 5 bits in them */ + hashed = (hashed<<5) | (hashed>>(bits_per_int-5)); + hashed ^= *c; + } + return hashed % KERN_INTVAR_HASH_SIZE; +} + +int kern_intvar_init() +{ + memset(kern_intvar_hash, 0, sizeof(kern_intvar_hash)); + return 0; +} + +void kern_intvar_set(const char *key, int value) +{ + int hashkey = hashfn(key); + struct kern_intvar_entry *entry = kern_intvar_hash[hashkey]; + if (! entry) { + kern_intvar_hash[hashkey] = kern_intvar_entry_new(key, value); + } + else { + int match = !strcmp(entry->key, key); + while (! match + && entry->next) { + entry = entry->next; + match = !strcmp(entry->key, key); + } + if (match) { + entry->value = value; + } else { + entry->next = kern_intvar_entry_new(key, value); + } + } +} + +int kern_intvar_get(const char *key) +{ + int hashkey = hashfn(key); + struct kern_intvar_entry *entry = kern_intvar_hash[hashkey]; + if (! entry) { + return 0; + } + else { + int match = !strcmp(entry->key, key); + while (! match + && entry->next) { + entry = entry->next; + match = !strcmp(entry->key, key); + } + if (match) { + return entry->value; + } else { + return 0; // SAM: Perhaps -1 or MAXINT would be a useful return for this case? + } + } +} + + +// eof diff --git a/src/kern_intvar.h b/src/kern_intvar.h new file mode 100644 index 0000000..a7ebad7 --- /dev/null +++ b/src/kern_intvar.h @@ -0,0 +1,27 @@ +/* $Id: kern_intvar.h,v 1.2 2010/08/26 05:56:20 gmcnutt Exp $ + * + * Copyright (C) 2006 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef kern_intvar_h +#define kern_intvar_h + +int kern_intvar_init(); +void kern_intvar_set(const char *key, int value); +int kern_intvar_get(const char *key); + +#endif diff --git a/src/knapsack.c b/src/knapsack.c new file mode 100644 index 0000000..7869216 --- /dev/null +++ b/src/knapsack.c @@ -0,0 +1,118 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "knapsack.h" + +//#define DEBUG +#ifdef DEBUG +#include +#endif + +static unsigned char cur_in[MAX_N_ITEMS]; +static int max; +static int cur_max; + +#ifdef DEBUG +static void dump_problem(struct knapsack *prob) +{ + int i; + printf("-------------------------\n"); + printf("max=%d\n", max); + for (i = 0; i < prob->n_items; i++) { + printf("%d %d %d\n", i, prob->value[i], prob->solution[i]); + } +} +#endif + +static int ks_solve(struct knapsack *prob) +{ + int i; + +#ifdef DEBUG + dump_problem(prob); +#endif + + /* For each item... */ + for (i = 0; i < prob->n_items; i++) { + + if (cur_in[i]) + /* The item is already in the knapsack */ + continue; + + if (prob->put(prob->item[i], prob->context)) { + + /* The item fits. To decide if the item belongs in the + * * final solution consider two subproblems: one where + * * the item is included in the solution, and one where + * * the item is not. */ + + cur_in[i] = 1; + cur_max += prob->value[i]; + + if (max < cur_max) { + /* This solution is better than the old * one. + * Make a copy. */ + int j; + max = cur_max; + for (j = 0; j < prob->n_items; j++) + prob->solution[j] = cur_in[j]; + } + + /* Consider the subproblem where the item is included */ + ks_solve(prob); + + /* Consider the subproblem where the item is NOT * + * included (by continuing at this level without it) */ + cur_in[i] = 0; + cur_max -= prob->value[i]; + prob->remove(prob->item[i], prob->context); + } + } + +#if 0 + /* remove any remaining items */ + for (i = 0; i < prob->n_items; i++) { + if (cur_in[i]) + prob->remove(prob->item[i], prob->context); + } +#endif + + return 0; +} + +int knapsack_solve(struct knapsack *prob) +{ + int i; + + /* Sanity checks */ + if (!prob || prob->n_items < 0 || prob->n_items > MAX_N_ITEMS) + return -1; + + /* Initialize */ + for (i = 0; i < prob->n_items; i++) { + prob->solution[i] = 0; + cur_in[i] = 0; + } + max = 0; + cur_max = 0; + + return ks_solve(prob); +} diff --git a/src/knapsack.h b/src/knapsack.h new file mode 100644 index 0000000..bbba6f0 --- /dev/null +++ b/src/knapsack.h @@ -0,0 +1,58 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef knapsack_h +#define knapsack_h + +#define MAX_N_ITEMS 100 + +struct knapsack { + + int n_items; /* The number of items to consider */ + + void **item; /* Array of pointers to the items under + * consideration. Memory managed by caller. */ + + int *value; /* Array of values of the items (in the same + * order as the items). Memory managed by * + * caller. */ + + unsigned char *solution; /* Array representing the set of items + * chosen. If and only if the value of + * * solution[i] is * nonzero, then * + * item[i] was chosen. Memory managed * + * by * caller. */ + + int (*put) (void *context, void *item); /* Attempt to put the item in + * the 'knapsack' and return + * nonzero if successful or + * zero if it failed. */ + + void (*remove) (void *context, void *item); /* Remove an item from + * the knapsack. */ + + void *context; /* Used as the 'context' parameter to the 'put' + * callback */ +}; + +extern int knapsack_solve(struct knapsack *problem); + +#endif diff --git a/src/list.h b/src/list.h new file mode 100644 index 0000000..806ded7 --- /dev/null +++ b/src/list.h @@ -0,0 +1,128 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +/* + * From-scratch impl inspired by the Linux kernel source's list.h + */ + +#ifndef list_h +#define list_h + +#include "macros.h" + +BEGIN_DECL + +#define list_for_each(head,ptr) \ + for ((ptr) = (head)->next; (ptr) != (head); (ptr) = (ptr)->next) +#define list_init(list) { (list)->next = (list); (list)->prev = (list); } +#define list_empty(list) ((list)->next == (list) && (list)->prev == (list)) +#define list_entry(ptr,type,field) \ + ((type*)((char*)(ptr)-(unsigned long)(&((type *)0)->field))) + +struct list { + struct list *next; + struct list *prev; +}; + +static inline void list_add_aux(struct list *before, struct list *after, + struct list *between) +{ + between->next = after; + between->prev = before; + before->next = between; + after->prev = between; +} + +static inline void list_add(struct list *head, struct list *ptr) +{ + list_add_aux(head, head->next, ptr); +} + +static inline void list_add_tail(struct list *head, struct list *ptr) +{ + list_add_aux(head->prev, head, ptr); +} + +static inline void list_remove(struct list *list) +{ + list->prev->next = list->next; + list->next->prev = list->prev; + list_init(list); +} + +static inline void list_switch_adjacent(struct list *first, + struct list *second) +{ + first->prev->next = second; + second->prev = first->prev; + first->prev = second; + first->next = second->next; + second->next->prev = first; + second->next = first; +} + +static inline void list_replace(struct list *orig, struct list *repl) +{ + if (orig ==repl) + return; + + *repl = *orig; + orig->next->prev = repl; + orig->prev->next = repl; +} + +static inline void list_switch(struct list *e1, struct list *e2) +{ + struct list tmp; + + list_replace(e1, &tmp); + list_replace(e2, e1); + list_replace(&tmp, e2); +} + +static inline int list_len(struct list *head) +{ + struct list *list = head->next; + int n = 0; + while (list != head) { + list = list->next; + n++; + } + return n; +} + +static inline void list_move(struct list *new_head, struct list *old_head) +{ + if (list_empty(old_head)) { + list_init(new_head); + return; + } + + *new_head = *old_head; + new_head->next->prev = new_head; + new_head->prev->next = new_head; + + list_init(old_head); +} + +END_DECL + +#endif diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..c5d3a47 --- /dev/null +++ b/src/log.c @@ -0,0 +1,262 @@ +#include "log.h" +#include "list.h" +#include "common.h" +#include "console.h" + +#include +#include +#include +#include + +#define LOG_ENTRY_BUF_SZ 512 + +static struct list log_q; +static struct list log_stk; +static int log_group; +static int log_disabled; + +struct log_entry { + struct list q_hook; + struct list stk_hook; + char buf[LOG_ENTRY_BUF_SZ]; + char *ptr; + int room; +}; + +struct log_entry *log_entry_new() +{ + struct log_entry *entry = (struct log_entry*)calloc(1, sizeof(*entry)); + assert(entry); + entry->ptr = entry->buf; + entry->room = sizeof(entry->buf); + return entry; +} + +static void log_entry_del(struct log_entry *entry) +{ + free(entry); +} + +static void log_entry_print(struct log_entry *entry, const char *fmt, va_list args) +{ + /* If fmt is NULL experimentation shows that vsnprintf returns -1, + * which is also the indication that we attempted to overflow the + * buffer. To prevent the ambiguity (we want to handle 'nothing + * written' differently than 'overflow') check for NULL here. */ + if (!fmt) { + return; + } + + int wrote = vsnprintf(entry->ptr, entry->room, fmt, args); + if (wrote >= 0) { + entry->room -= wrote; + entry->ptr += wrote; + } else { + entry->room = 0; + } +} + +void log_flush() +{ + struct log_entry *entry; + + if (list_empty(&log_q)) + return; + + entry = outcast(log_q.next, struct log_entry, q_hook); + + if (entry->ptr != entry->buf) { + consolePrint(entry->buf); + consoleRepaint(); + memset(entry->buf, 0, sizeof(entry->buf)); + entry->ptr = entry->buf; + entry->room = sizeof(entry->buf); + } +} + +static inline void log_print_queued_msgs() +{ + struct list *elem; + + elem = log_q.next; + + while (elem != &log_q) { + + struct log_entry *entry; + + entry = outcast(elem, struct log_entry, q_hook); + elem = elem->next; + consolePrint("%s\n", entry->buf); + list_remove(&entry->q_hook); + log_entry_del(entry); + } +} + +static inline void log_flush_queued_msgs(struct log_entry *entry) +{ + struct list *elem; + + elem = &entry->q_hook; + + while (elem != &log_q) { + entry = outcast(elem, struct log_entry, q_hook); + elem = elem->next; + list_remove(&entry->q_hook); + log_entry_del(entry); + } +} + +static inline void log_push(struct log_entry *entry) +{ + list_add_tail(&log_q, &entry->q_hook); + list_add(&log_stk, &entry->stk_hook); + log_begin_group(); +} + +static inline void log_pop() +{ + assert(! list_empty(&log_stk)); + + /* Pop the topmost entry from the msg stack */ + list_remove(log_stk.next); + + /* If the msg stack is now empty then log all msgs on the queue */ + if (list_empty(&log_stk)) + log_print_queued_msgs(); + log_end_group(); +} + +void log_abort(void) +{ + struct log_entry *entry; + + if (log_disabled) + return; + + assert(! list_empty(&log_stk)); + entry = outcast(log_stk.next, struct log_entry, stk_hook); + + list_remove(log_stk.next); + log_flush_queued_msgs(entry); + log_end_group(); +} + +void log_init(void) +{ + list_init(&log_q); + list_init(&log_stk); + log_group = 0; + log_disabled = 0; +} + +void log_begin(const char *fmt, ...) +{ + va_list args; + + if (log_disabled) + return; + + struct log_entry *entry = log_entry_new(); + log_push(entry); + va_start(args, fmt); + log_entry_print(entry, fmt, args); + va_end(args); +} + +void log_continue(const char *fmt, ...) +{ + va_list args; + struct log_entry *entry; + + if (log_disabled) + return; + + assert(! list_empty(&log_stk)); + entry = outcast(log_stk.next, struct log_entry, stk_hook); + va_start(args, fmt); + log_entry_print(entry, fmt, args); + va_end(args); +} + +void log_end(const char *fmt, ...) +{ + va_list args; + struct log_entry *entry; + + if (log_disabled) + return; + + assert(! list_empty(&log_stk)); + entry = outcast(log_stk.next, struct log_entry, stk_hook); + va_start(args, fmt); + log_entry_print(entry, fmt, args); + va_end(args); + log_pop(); +} + +void log_msg(const char *fmt, ...) +{ + va_list args; + struct log_entry *entry = log_entry_new(); + + if (log_disabled) + return; + + log_push(entry); + va_start(args, fmt); + log_entry_print(entry, fmt, args); + va_end(args); + log_pop(); +} + +void log_banner(const char *fmt, ...) +{ + struct log_entry *entry; + va_list args; + + if (log_disabled) { + return; + } + + log_begin_group(); + log_msg("^c+y*********************************^c-"); + log_begin("^c+y*^c- "); + + + entry = outcast(log_stk.next, struct log_entry, stk_hook); + va_start(args, fmt); + log_entry_print(entry, fmt, args); + va_end(args); + + log_end(""); + log_msg("^c+y*********************************^c-"); + log_end_group(); +} + +void log_begin_group() +{ + if (log_disabled) + return; + + log_group++; +} + +void log_end_group() +{ + if (log_disabled) + return; + + log_group--; + if (log_group == 0) + consolePrint("\n"); +} + +void log_disable() +{ + log_disabled++; +} + +void log_enable() +{ + log_disabled--; +} diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..a87e461 --- /dev/null +++ b/src/log.h @@ -0,0 +1,57 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +#ifndef log_h +#define log_h + +/* Called on startup */ +extern void log_init(void); + +/* A group of messages are all printed with no blank line between them. Blank + * lines appear between top-level groups. */ +extern void log_begin_group(); +extern void log_end_group(); + +/* Begin a message that will start a group and prevent members of the group + * from printing until it finishes. This is to de-interleave messages. */ +extern void log_begin(const char *fmt, ...); +extern void log_continue(const char *fmt, ...); +extern void log_end(const char *fmt, ...); +extern void log_abort(); + +/* log_flush - force a partial entry started with log_begin() to print now + * rather than waiting for log_end(). Warning: calling log_abort() after this + * will not erase what was written to the console. Normally you don't need to + * use log_flush(). + */ +extern void log_flush(); + +/* Log a single message as its own group. */ +extern void log_msg(const char *fmt, ...); + +extern void log_disable(); +extern void log_enable(); + +/* Like log_msg, but with fancy borders. */ +extern void log_banner(const char *fmt, ...); + +#endif diff --git a/src/los.c b/src/los.c new file mode 100644 index 0000000..ac933b3 --- /dev/null +++ b/src/los.c @@ -0,0 +1,104 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "los.h" + +#include +#include + +#define los_NUMALGS sizeof(algs)/sizeof(algs[0]) + +extern int FLOODFILL_Init(struct los *los); +extern int ANGBAND_Init(struct los *los); + +#ifdef __cplusplus +extern "C" { +#endif +#ifdef __cplusplus +} +#endif + +struct alg_list_entry { + const char *name; + int (*init) (struct los * los); +} algs[] = { + { + "floodfill", FLOODFILL_Init}, { + "angband", ANGBAND_Init},}; + +struct los *los_create(const char *name, int w, int h, int r) +{ + struct los *los; + unsigned int i; + + /* Check if alg is supported */ + for (i = 0; i < los_NUMALGS; i++) { + if (!strcmp(algs[i].name, name)) + break; + } + + /* Check if alg was not found */ + if (i == los_NUMALGS) + return 0; + + /* Allocate the "base class" */ + los = (struct los *) malloc(sizeof(struct los)); + if (!los) + return 0; + + memset(los, 0, sizeof(struct los)); + + los->w = w; + los->h = h; + los->r = r; + + /* Allocate the visibility buffer */ + los->vmask = (unsigned char *) malloc(w * h); + if (!los->vmask) + goto fail; + + /* Allocate the alpha buffer */ + los->alpha = (unsigned char *) malloc(w * h); + if (!los->alpha) + goto fail; + + /* Initialize the specific algorithm */ + if (algs[i].init(los) < 0) + goto fail; + + return los; + + fail: + los_destroy(los); + return 0; + +} + +void los_destroy(struct los *los) +{ + if (los->destroy) + los->destroy(los); + if (los->vmask) + free(los->vmask); + if (los->alpha) + free(los->alpha); + free(los); +} diff --git a/src/los.h b/src/los.h new file mode 100644 index 0000000..aa47c0c --- /dev/null +++ b/src/los.h @@ -0,0 +1,122 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef los_h +#define los_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define ALPHA_TRANSPARENT 0 +#define ALPHA_OPAQUE 12 + + struct los { + + /*** Public ***/ + + /** + * Width and height specify the maximum area over which an + * algorithm will compute line of sight. + */ + int w; + int h; + + /** + * Radius is an optional parameter. Use it to limit the max + * visible range from the center of the vmask. No matter how + * large you make this, the width and height parameters (above) + * still enforce a max limit on visible range. But you can use + * it to shrink the visible range below what the width and + * height allow. + */ + int r; + + /** + * 'alpha' points to a 2d array. Each element in the array + * corresponds to a tile on the visible map. The value in each + * element indicates how transparent the corresponding tile + * is. For example, a value of 0 indicates that the tile is + * perfectly opaque and blocks all visibility beyond it, + * whereas a value of 1 indicates that the tile is perfectly + * transparent and does not hamper visibility at all. + * + * Although the los engine is responsible for allocating and + * freeing this buffer, the caller is responsible for filling + * it in before calling the compute() routine. + */ + unsigned char *alpha; + + /** + * 'vmask' also points to a 2d array. Again, each element + * corresponds to a tile. However, this array stores the result + * of the last los computation. It's value give the relative + * visibility of a tile. For example, 0 means the tile is + * completely obscured, whereas 1 means the tile is completely + * visible. + * + * The los engine is responsible for allocating and freeing + * this buffer, and also filling it. The caller should consider + * it read-only (but it doesn't really matter). + */ + unsigned char *vmask; + + /** + * Run the los algorithm and return the results in + * 'vmask'. Note that both 'alpha' and 'vmask' must refer to + * valid pointers. + */ + void (*compute) (struct los * los); + + /*** Private ***/ + + /** + * Free the resources associated with an los engine. This is + * for internal use only -- clients should use los_destroy() + * below instead. + */ + void (*destroy) (struct los * los); + + void *data; + + }; + + /** + * Create an los object. 'algorithm' specifies the name of the los + * algorithm to use (e.g., "angband" or "floodfill"). 'width' and + * 'height' are used to size the alpha and vmask buffers. 'radius' is + * used by some algorithms to limit line-of-sight to something less + * than 'width' or 'height' (angband uses it, floodfill currently does + * not). Returns an los struct or null if one can't be created to meet + * the request. + */ + extern struct los *los_create(const char *algorithm, int width, int height, + int radius); + + /** + * Free the resources used by an los object. + */ + extern void los_destroy(struct los *los); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/macros.h b/src/macros.h new file mode 100644 index 0000000..5d93f8f --- /dev/null +++ b/src/macros.h @@ -0,0 +1,50 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// + +// This file needs to be safe for both c and c++ compilation. It should also +// contain only the most generic types of macros, stuff not really specific to +// nazghul. + +#ifndef macros_h +#define macros_h + +#ifdef __cplusplus +#define BEGIN_DECL extern "C" { +#define END_DECL } +#else +#define BEGIN_DECL +#define END_DECL +#endif + +#define maxstrlen(array) (sizeof((array)) - 1) + +#ifndef clamp +#define clamp(v,a,b) ((v) = (v) < (a) ? (a) : ((v) > (b) ? (b) : (v))) +#endif + +#ifndef normalize +#define normalize(dv) ((dv)>1?1:((dv)<-1?-1:0)) +#endif + +#define DECL_CAST(type,var,ptr) type * var = (type *)(ptr) + +#endif diff --git a/src/magic.c b/src/magic.c new file mode 100644 index 0000000..81a3ad0 --- /dev/null +++ b/src/magic.c @@ -0,0 +1,326 @@ +/* + * nazghul - an old-school RPG engine + * Copyright (C) 2004 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * Gordon McNutt + * gmcnutt@users.sourceforge.net + * + */ + +#include "magic.h" +#include "debug.h" + +#include +#include +#include + +/***************************************************************************** + * + * spell api + * + *****************************************************************************/ + +static struct spell *spell_new(char *code) +{ + struct spell *spell; + + spell = (struct spell*)calloc(1, sizeof(*spell)); + assert(spell); + + spell->code = strdup(code); + assert(spell->code); + + return spell; +} + +static void spell_del(struct spell *entry) +{ + assert(entry); + + if (entry->code) + free(entry->code); + free(entry); +} + +int spell_add_reagent(struct spell *spell, ObjectType *reagent) +{ + if (spell->n_reagents == MAX_MIX_REAGENTS) { + warn("spell_add_reagent: spell %s already maxed out on "\ + "reagents\n", spell->code); + return -1; + } + + spell->reagents[spell->n_reagents++] = reagent; + return 0; +} + +/***************************************************************************** + * + * helper functions + * + *****************************************************************************/ + +static int magic_check_code(struct magic *magic, char *code) +{ + if (! code) + return -1; + + while (*code) { + if (! magic->words[(*code - 'A')]) { + warn("magic_check_code: no magic word starts with %c\n", + *code); + return -1; + } + code++; + } + + return 0; +} + +static void magic_del_spell_tree(struct spell *root) +{ + if (root->left) + magic_del_spell_tree(root->left); + if (root->right) + magic_del_spell_tree(root->right); + spell_del(root); +} + +static int magic_is_code(char code) +{ + int index = code - 'A'; + return (index >= 0 && index < MAX_SPELL_WORDS); +} + +/***************************************************************************** + * + * public api + * + *****************************************************************************/ + + +/* Initialize at start-of-session prior to loading */ +void magic_init(struct magic *magic) +{ + memset(magic->words, 0, sizeof(magic->words)); + magic->spells = NULL; +} + +/* Cleanup at end-of-session */ +void magic_end_session(struct magic *magic) +{ + int i; + + for (i = 0; i < MAX_SPELL_WORDS; i++) { + if (NULL != magic->words[i]) + free(magic->words[i]); + magic->words[i] = NULL; + } + + if (magic->spells != NULL) { + magic_del_spell_tree(magic->spells); + magic->spells = NULL; + } +} + +struct spell *magic_add_spell(struct magic *magic, char *code) +{ + struct spell *parent = 0; + struct spell *current = magic->spells; + int dir; + + /* Make sure the code is valid */ + if (magic_check_code(magic, code)) + return NULL; + + /* Descend the spell tree to a vacant leaf */ + while (current) { + + /* Parent always points to last valid node */ + parent = current; + + dir = strcmp(code, current->code); + + /* Check if a spell was already inserted with this code */ + if (dir == 0) { + warn("magic_add_spell: there's already a spell with "\ + "code '%s'\n", code); + return NULL; + } + else if (dir < 0) + current = current->left; + else + current = current->right; + } + + current = spell_new(code); + + if (!parent) { + /* First entry (root) */ + magic->spells = current; + } else if (strcmp(code, parent->code) < 0) { + /* Left child vacant */ + parent->left = current; + } else { + /* Right child vacant */ + parent->right = current; + } + + /* Success */ + return current; + +} + +/* Lookup spells when casting them during play */ +struct spell *magic_lookup_spell(struct magic *magic, char *code) +{ + struct spell *current; + + current = magic->spells; + + while (current) { + + int dir = strcmp(code, current->code); + + if (! dir) { + /* Found it! */ + return current; + } else if (dir < 0) { + current = current->left; + } else { + current = current->right; + } + } + + /* Didn't find it */ + return NULL; +} + +int magic_add_word(struct magic *magic, char *word) +{ + int index = word[0] - 'A'; + + if (! magic_is_code(word[0])) { + warn("magic_add_word: letter '%c' out of range [A, %c]\n", + word[0], MAX_SPELL_WORDS + 'A' - 1); + return -1; + } + + if (magic->words[index]) { + warn("magic_add_word: cannot add word '%s' because word "\ + "'%s' already starts with '%c'\n", word, + magic->words[index], + word[0]); + return -1; + } + + magic->words[index] = strdup(word); + assert(magic->words[index]); + + return 0; +} + +char *magic_lookup_word(struct magic *magic, char first_letter) +{ + int index = first_letter - 'A'; + + if (! magic_is_code(first_letter)) { + warn("magic_lookup_word: letter '%c' out of range [A, %c]\n", + first_letter, MAX_SPELL_WORDS + 'A' - 1); + return NULL; + } + + return magic->words[index]; +} + +int magic_spell_code_to_name(struct magic *magic, char *buf, int len, + char *code) +{ + int n = 0; + + while (*code) { + char *word = magic_lookup_word(magic, *code); + if (! word) + return -1; + n = snprintf(buf, len, "%s ", word); + if (n < 0) + return -1; + buf += n; + len -= n; + code++; + } + + // back up over the last space + if (! *code) { + buf--; + *buf = 0; + } + + return 0; +} + +int magic_spell_name_to_code(struct magic *magic, char *code, int len, + const char *name) +{ + int state = 2, i = 0; + const char *ptr = name; + + len--; /* leave space for null terminator */ + + while (*ptr && len) { + char c = *ptr; + ptr++; + switch (state) { + case 0: + /* looking for start of next word */ + if (! isspace(c)) { + + /* If this is a valid word then store it's + * first letter in the code buffer, else ignore + * it. Ignoring it lets us handle things like + * "vas Flam spell", where we ignore the + * "spell" part. */ + if (magic_is_code(c)) { + code[i] = c; + i++; + len--; + } + state = 1; + } + break; + case 1: + /* looking for end of current word */ + if (isspace(c)) { + state = 0; + } + break; + case 2: + /* spell names have code in <> */ + if (c == '<') { + state = 0; + } + break; + default: + assert(0); + break; + } + } + + code[i] = 0; /* null-terminate */ + + return 0; +} diff --git a/src/magic.h b/src/magic.h new file mode 100644 index 0000000..b741fd7 --- /dev/null +++ b/src/magic.h @@ -0,0 +1,104 @@ +/* + * nazghul - an old-school RPG engine + * Copyright (C) 2004 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + * + * Gordon McNutt + * gmcnutt@users.sourceforge.net + * + */ + +#ifndef magic_h +#define magic_h + +#include "object.h" /* for ObjectType */ +#include "macros.h" + +BEGIN_DECL + +/* The number of spell words or "syllables" is limited to the number of letters + * in the English alphabet. That's because the first letter of each syllable + * uniquely identifies it. */ +#define MAX_SPELL_WORDS 26 + +/* The max number of reagents allowed in the mixture for a spell. */ +#define MAX_MIX_REAGENTS 8 + +/* Arbitrary limit on the number of characters (not syllables!) in a full spell + * name */ +#define MAX_SPELL_NAME_LENGTH 64 + +/* Arbitrary limit on the number of syllables in a spell name. */ +#define MAX_SYLLABLES_PER_SPELL 8 + +/* Spells are stored in a tree indexed by their "code". The code is the first + * letter of each word in the spell. For example, An Nox has the code AN. I + * also store the mixture here with the associated spell. For cimplicity I + * hard-code the max number of reagents permitted in a spell. */ +struct spell { + ObjectType *type; + char *code; + int level; + int cost; + int context; + int action_points; + int n_reagents; + ObjectType *reagents[MAX_MIX_REAGENTS]; + struct sprite *sprite; + struct spell *left; + struct spell *right; +}; + +/* One of these is embedded in the global session structure. It manages all the + * magic-related information related to a session. */ +struct magic { + char *words[MAX_SPELL_WORDS]; + struct spell *spells; +}; + +/* Initialize before loading a new session */ +extern void magic_init(struct magic *); + +/* Cleanup at end-of-session */ +extern void magic_end_session(struct magic *); + +/* Add a spell during session load. Returns the newly added spell or NULL on + * error. */ +extern struct spell *magic_add_spell(struct magic *, char *code); + +/* Add a word during session load. Returns 0 on success or -1 on error. */ +extern int magic_add_word(struct magic *, char *word); + +/* Lookup a word based on its first letter. Returns NULL on error or if no such + * word exists, otherwise the desired word. */ +extern char *magic_lookup_word(struct magic *magic, char first_letter); + +/* Lookup spells when casting them during play */ +extern struct spell *magic_lookup_spell(struct magic *, char *code); + +/* Add another reagent to a spell mixture during session load. */ +extern int spell_add_reagent(struct spell *spell, ObjectType *reagent); + +/* Given a spell code like "VF" convert it to a full name like "Vas Flam" */ +extern int magic_spell_code_to_name(struct magic *magic, char *buf, int len, char *code); + +/* Opposite of magic_spell_code_to_name() */ +extern int magic_spell_name_to_code(struct magic *magic, char *buf, int len, const char *name); + + +END_DECL + +#endif diff --git a/src/map.c b/src/map.c new file mode 100644 index 0000000..e31776e --- /dev/null +++ b/src/map.c @@ -0,0 +1,1883 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#include "map.h" +#include "sky.h" // For time/date functions +#include "screen.h" +#include "place.h" +#include "player.h" +#include "sprite.h" +#include "cursor.h" +#include "terrain.h" +#include "Missile.h" +#include "object.h" +#include "vmask.h" +#include "session.h" +#include "sprite.h" +#include "nazghul.h" // for DeveloperMode + +#include +#include + +#define PROFILE_REPAINT 0 +#define PROFILE_ANIMATE 0 + +#define LMAP_W (VMASK_W) +#define LMAP_H (VMASK_H) + +#define MVIEW_SZ (sizeof(struct mview)) +#define LMAP_SZ (LMAP_W * LMAP_H) +#define MAX_LIGHTS LMAP_SZ +#define PEER_ZOOM 2 + +#define LIT 255 +#define UNLIT 0 + +#define mview_x(mview) ((mview)->vrect.x) +#define mview_y(mview) ((mview)->vrect.y) +#define mview_w(mview) ((mview)->vrect.w) +#define mview_h(mview) ((mview)->vrect.h) +#define mview_center_x(mview) (mview_x(mview) + mview_w(mview) / 2) +#define mview_center_y(mview) (mview_y(mview) + mview_h(mview) / 2) + +/** + * Convert map coords to screen coords + */ +#define MX_TO_SX(x) \ + (Map.srect.x+((x)-(Map.aview->vrect.x+Map.aview->subrect.x))*TILE_W) +#define MY_TO_SY(y) \ + (Map.srect.y+((y)-(Map.aview->vrect.y+Map.aview->subrect.y))*TILE_H) + +struct light_source { + int x, y, light; +}; + +struct mview { + struct list list; /* used internally by map lib */ + SDL_Rect vrect; /* map coords of vrect */ + SDL_Rect subrect; /* offset into visible subrect of vrect */ + //char *vmask; /* visibility mask */ + int rad; /* light radius */ + int zoom; /* zoom level */ + int dirty:1; /* needs repaint */ + int blackout:1; /* erase only on repaint */ +}; + +static struct map { + SDL_Rect srect; /* screen coords of viewer */ + SDL_Rect latencyRect; /* screen coords of latency time */ + SDL_Rect turnaroundRect; /* screen coords of turnaroud time */ + SDL_Rect locRect; /* screen coords of locater */ + SDL_Rect clkRect; /* screen coords of clock */ + struct place *place; /* subject being viewed */ + struct mview *aview; /* active view */ + struct list views; /* list of all views */ + struct mview *cam_view; + class Object *subject; + int cam_x, cam_y, cam_max_x, cam_max_y, cam_min_x, cam_min_y; + bool peering; + char *vmask; /* final mask used to render */ + SDL_Surface *tile_scratch_surf; + Uint32 last_repaint; + class Object *selected; /* selected object -- don't shade the tile it's + * on */ + + /* FIXME: why is this dynamically allocated when we're using + * MAX_LIGHTS? */ + struct light_source *lights; + unsigned char *lmap; + unsigned char *tmp_lmap; + char is_image_mode : 1; +} Map; + +/** + * The callback function prototype for rendering a tile. + */ +typedef void (*map_tile_render_t)(struct place *place, int map_x, int map_y, + int scr_x, int scr_y, int in_los); + + +static void myRmView(struct mview *view, void *data) +{ + list_remove(&view->list); +} + +static void mapMergeRects(SDL_Rect *src_rect, unsigned char *src, + SDL_Rect *dst_rect, unsigned char *dst) +{ + int r_src, r_src_start, c_src, c_src_start, i_src, r_end, c_end; + int r_dst, r_dst_start, c_dst, c_dst_start, i_dst; + int tmp; + + // skip identical merges (yes, it happens) + if (src == dst) + return; + + if (src_rect->x < dst_rect->x) { + // Source leftmost + tmp = src_rect->x + src_rect->w - dst_rect->x; + if (tmp < 0) + return; + c_src_start = dst_rect->x - src_rect->x; + c_end = c_src_start + tmp; + c_dst_start = 0; + } else { + // Destination leftmost + tmp = dst_rect->x + dst_rect->w - src_rect->x; + if (tmp < 0) + return; + c_src_start = 0; + c_end = tmp; + c_dst_start = src_rect->x - dst_rect->x; + } + + if (src_rect->y < dst_rect->y) { + // Source topmost + tmp = src_rect->y + src_rect->h - dst_rect->y; + if (tmp < 0) + return; + r_src_start = dst_rect->y - src_rect->y; + r_end = r_src_start + tmp; + r_dst_start = 0; + } else { + // Destination topmost + tmp = dst_rect->y + dst_rect->h - src_rect->y; + if (tmp < 0) + return; + r_src_start = 0; + r_end = tmp; + r_dst_start = src_rect->y - dst_rect->y; + } + + for (r_src = r_src_start, r_dst = r_dst_start; r_src < r_end; + r_src++, r_dst++) { + for (c_src = c_src_start, c_dst = c_dst_start; c_src < c_end; + c_src++, c_dst++) { + int val; + i_src = r_src * src_rect->w + c_src; + i_dst = r_dst * dst_rect->w + c_dst; + val = dst[i_dst] + src[i_src]; + dst[i_dst] = (unsigned char)min(val, 255); + } + } +} + +static void mapMergeView(struct mview *view, void *data) +{ + int r_src, r_src_start, c_src, c_src_start, i_src, r_end, c_end; + int r_dst, r_dst_start, c_dst, c_dst_start, i_dst; + int tmp; + char *vmask; + + /* Skip this view if it is the active view */ + if (view == Map.aview) + return; + + // --------------------------------------------------------------------- + // Find the indices to merge from depending on the relationship between + // the map view rectangle and the mview being merged. + // --------------------------------------------------------------------- + + if (view->vrect.x < Map.aview->vrect.x) { + /* This view leftmost (A) */ + tmp = view->vrect.x + view->vrect.w - Map.aview->vrect.x; + if (tmp < 0) + return; + c_src_start = Map.aview->vrect.x - view->vrect.x; + c_end = c_src_start + tmp; + c_dst_start = 0; + } else { + /* Active view leftmost (A) */ + tmp = Map.aview->vrect.x + Map.aview->vrect.w - view->vrect.x; + if (tmp < 0) + return; + c_src_start = 0; + c_end = tmp; + c_dst_start = view->vrect.x - Map.aview->vrect.x; + } + + if (view->vrect.y < Map.aview->vrect.y) { + /* This view topmost (A) */ + tmp = view->vrect.y + view->vrect.h - Map.aview->vrect.y; + if (tmp < 0) + return; + r_src_start = Map.aview->vrect.y - view->vrect.y; + r_end = r_src_start + tmp; + r_dst_start = 0; + } else { + /* Active view topmost (A) */ + tmp = Map.aview->vrect.y + Map.aview->vrect.h - view->vrect.y; + if (tmp < 0) + return; + r_src_start = 0; + r_end = tmp; + r_dst_start = view->vrect.y - Map.aview->vrect.y; + } + + // --------------------------------------------------------------------- + // From the vmask cache, fetch the vmask corresponding to the tile in + // the center of the view from the vmask cache. (This will automatically + // create the vmask if it doesn't already exist). + // --------------------------------------------------------------------- + + vmask = vmask_get(Map.place, mview_center_x(view), mview_center_y(view)); + assert(vmask); + if (NULL == vmask) + return; + + // --------------------------------------------------------------------- + // Copy the contents of the view's vmask to the master vmask. + // --------------------------------------------------------------------- + + for (r_src = r_src_start, r_dst = r_dst_start; r_src < r_end; + r_src++, r_dst++) { + for (c_src = c_src_start, c_dst = c_dst_start; c_src < c_end; + c_src++, c_dst++) { + i_src = r_src * VMASK_W + c_src; + i_dst = r_dst * VMASK_W + c_dst; + Map.vmask[i_dst] |= vmask[i_src]; + } + } + +} + +static void myMarkAsDirty(struct mview *view, void *data) +{ + view->dirty = 1; +} + +static void mySetViewLightRadius(struct mview *view, void *data) +{ + int rad = *((int*)data); + view->rad = rad; +} + +static int mapCalcMaxLightRadius(int light) +{ + // until something faster becomes necessary + return (int)sqrt((double)light); +} + +#if 0 +// debug +static void mapDumpRect(char *name, SDL_Rect *rect, unsigned char *data) +{ + int x, y, i; + + printf("Rect %s (%d %d %d %d):\n", name, rect->x, rect->y, rect->w, + rect->h); + i = 0; + for (y = 0; y < rect->h; y++) { + for (x = 0; x < rect->w; x++, i++) { + printf(" %03d", data[i]); + } + printf("\n"); + } + printf("\n"); +} +#endif + +/** + * Given a light source, add its contribution to the light map (Map.lmap). + * + * @param light is the light source to add + * @param main_view is the view containing the light source + */ +static void mapMergeLightSource(struct light_source *light, struct mview *main_view) +{ + int radius; + int vmask_i; + struct mview tmp_view; + int x; + int y; + int map_x; + int map_y; + int D; + char *vmask; + + // Initialize the temporary view to be centered on the light + // source. (Note: ignore the subrect, it shouldn't matter) + // + // REVISIT: not sure I'm calculating vrect.x right: VMASK_W is odd + memset(&tmp_view, 0, sizeof(tmp_view)); + tmp_view.vrect.x = place_wrap_x(Map.place, light->x - (VMASK_W / 2)); + tmp_view.vrect.y = place_wrap_y(Map.place, light->y - (VMASK_H / 2)); + tmp_view.vrect.w = VMASK_W; + tmp_view.vrect.h = VMASK_H; + tmp_view.zoom = 1; + + radius = min(mapCalcMaxLightRadius(light->light), VMASK_W / 2); + + // Fetch the vmask from the cache. + vmask = vmask_get(Map.place, light->x, light->y); + + // For each visible tile in the vmask, calculate how much light is + // hitting that tile from the light source. The loop optimizes by only + // checking those tiles that are within the radius of the light source. + // This optimization makes no difference on my fast box, haven't tested + // it yet on my slow one. + int min_y = 0; + int max_y = VMASK_H; + int min_x = 0; + int max_x = VMASK_W; + + //dbg("lightmap %d:%d:%s\n", light->x, light->y, Map.place->name); + + for (y = min_y; y < max_y; y++) { + + map_y = place_wrap_y(Map.place, tmp_view.vrect.y + y); + vmask_i = y * VMASK_W + min_x; + + for (x = min_x; x < max_x; x++, vmask_i++) { + + // skip non-visible tiles + if (vmask[vmask_i] == 0) { + Map.tmp_lmap[vmask_i] = 0; + continue; + } + + map_x = place_wrap_x(Map.place, tmp_view.vrect.x + x); + + D = place_flying_distance(Map.place, light->x, + light->y, map_x, map_y); + D = D * D + 1; + Map.tmp_lmap[vmask_i] = min(light->light / D, 255); + } + } + + // Merge this source's lightmap (contained in the vmask we just built) + // with the main lightmap. + // + // Note: try to optimize this by merging only the portion of the vmask + // which is within the light radius. In fact, why don't I just limit + // the vrect to the radius? Would that work? + mapMergeRects(&tmp_view.vrect, Map.tmp_lmap, &main_view->vrect, + Map.lmap); + +} + +/** + * This clears and rebuilds Map.lmap, which is a grid of values indicating how + * much light is hitting each tile. The results are used in mapShadeScene to + * darken the scene. + * + * @param view specifies which part of the map to use + */ +static void mapBuildLightMap(struct mview *view) +{ + int x; + int y; + int lt_i; + int map_x; + int map_y; + int ambient_light; + + + /* Initialize the main lightmap to ambient light levels. */ + ambient_light = sky_get_ambient_light(&Session->sky); + memset(Map.lmap, + (Map.place->underground ? UNLIT : ambient_light), + LMAP_SZ); + + /* Optimization: if we're already getting max light everywhere from the + * sun then skip further processing. Building a lightmap usually takes + * about 1/3 of the time devoted to rendering. */ + if (! Map.place->underground + && ambient_light == MAX_AMBIENT_LIGHT) { + return; + } + + /* Build the list of light sources visible in the current map viewer + * window. This actually searches outside of the current view to the + * entire mview rectangle, so light sources that are just out-of-view + * may cast light into the view. */ + lt_i = 0; + for (y = 0; y < LMAP_H; y++) { + map_y = place_wrap_y(Map.place, view->vrect.y + y); + for (x = 0; x < LMAP_W; x++) { + int light; + + map_x = place_wrap_x(Map.place, view->vrect.x + x); + light = place_get_light(Map.place, map_x, map_y); + if (!light) + continue; + + Map.lights[lt_i].x = map_x; + Map.lights[lt_i].y = map_y; + Map.lights[lt_i].light = light; + lt_i++; + } + } + + /* Skip further processing if there are no light sources */ + if (!lt_i) { + return; + } + + + /* For each light source build a lightmap centered on that source and + * merge it into the main lightmap. */ + while (lt_i--) { + mapMergeLightSource(&Map.lights[lt_i], view); + } + +} + +static void myShadeScene(SDL_Rect *subrect) +{ + int x, y; + SDL_Rect rect; + int lmap_i; + + rect.x = Map.srect.x; + rect.y = Map.srect.y; + rect.w = TILE_W; + rect.h = TILE_H; + + lmap_i = subrect->y * VMASK_W + subrect->x; + //lmap_i = 0; + + // Iterate over the tiles in the map window and the corresponding + // values in the lightmap simultaneously */ + for (y = 0; y < MAP_TILE_H; y++, rect.y += TILE_H, + lmap_i += LMAP_W /*lmap_i += VMASK_W*/) { + for (x = 0, rect.x = Map.srect.x; + x < MAP_TILE_W; x++, rect.x += TILE_W) { + + /* Set the shading based on the lightmap value. The + * lightmap values must be converted to opacity values + * for a black square, so I reverse them by subtracting + * them from LIT. */ + screenShade(&rect, LIT - Map.lmap[lmap_i + x]); + } + } +} + +static inline void myAdjustCameraInBounds(void) +{ + if (Map.place->wraps) + return; + + Map.cam_x = min(Map.cam_x, Map.cam_max_x); + Map.cam_x = max(Map.cam_x, Map.cam_min_x); + Map.cam_y = min(Map.cam_y, Map.cam_max_y); + Map.cam_y = max(Map.cam_y, Map.cam_min_y); +} + +void mapForEachView(void (*fx) (struct mview *, void *), void *data) +{ + struct list *list; + list = Map.views.next; + while (list != &Map.views) { + struct list *tmp; + struct mview *view; + view = outcast(list, struct mview, list); + tmp = list->next; + fx(view, data); + list = tmp; + } +} + +void mapSetLosStyle(const char *los) +{ + if (LosEngine) { + los_destroy(LosEngine); + } + LosEngine = los_create(los, VMASK_W, VMASK_H, -1); + assert(LosEngine); +} + +static void mapExit(void) +{ + if (Map.lights) { + free(Map.lights); + Map.lights = 0; + } + + if (Map.lmap) { + free(Map.lmap); + Map.lmap = 0; + } + + if (Map.tmp_lmap) { + free(Map.tmp_lmap); + Map.tmp_lmap = 0; + } + + if (Map.cam_view) { + mapDestroyView(Map.cam_view); + Map.cam_view = 0; + } + + if (Map.vmask) { + free(Map.vmask); + Map.vmask = 0; + } +} + +int mapInit(void) +{ + + memset(&Map, 0, sizeof(Map)); + + Map.lights = (struct light_source*)calloc(MAX_LIGHTS, + sizeof(Map.lights[0])); + if (!Map.lights) + goto abort; + + /* The lightmap only needs to be as big as the map viewer + window. Making it larger does allow for lights outside the field of + view to be processed, but this makes dungeons appear too bright - I + like them dark and gloomy. */ + Map.lmap = (unsigned char*)calloc(LMAP_SZ, sizeof(Map.lmap[0])); + if (!Map.lmap) + goto abort; + + /* This one is used during mapMergeLightSource */ + Map.tmp_lmap = (unsigned char*)calloc(LMAP_SZ, + sizeof(Map.tmp_lmap[0])); + if (!Map.tmp_lmap) + goto abort; + + if (!(Map.cam_view = mapCreateView())) + goto abort; + + Map.vmask = (char*)calloc(VMASK_SZ, sizeof(Map.vmask[0])); + if (!Map.vmask) + goto abort; + + list_init(&Map.views); + + Map.srect.x = MAP_X; + Map.srect.y = MAP_Y; + Map.srect.w = MAP_W; + Map.srect.h = MAP_H; + + Map.latencyRect.x = MAP_X; + Map.latencyRect.y = MAP_Y; + Map.latencyRect.w = ASCII_W * 10; + Map.latencyRect.h = ASCII_H; + + Map.turnaroundRect.x = MAP_X; + Map.turnaroundRect.y = MAP_Y + ASCII_H; + Map.turnaroundRect.w = ASCII_W * 10; + Map.turnaroundRect.h = ASCII_H; + + Map.locRect.x = MAP_X; + Map.locRect.y = MAP_Y + MAP_H - ASCII_H; + Map.locRect.w = ASCII_W * 9; + Map.locRect.h = ASCII_H; + + Map.clkRect.w = ASCII_W * 7; + Map.clkRect.h = ASCII_H; + Map.clkRect.x = MAP_X + MAP_W - Map.clkRect.w; + Map.clkRect.y = MAP_Y; + + Map.peering = false; + LosEngine = NULL; + + Map.tile_scratch_surf = screenCreateSurface(TILE_W, TILE_H); + assert(Map.tile_scratch_surf); + + return 0; + +abort: + mapExit(); + return -1; +} + +void mapFlash(int mdelay) +{ + screenFlash(&Map.srect, mdelay, White); +} + +void mapSetPlace(struct place *place) +{ + Map.place = place; + + if (place->wraps) + return; + + if (place_w(place) > MAP_TILE_W) { + Map.cam_max_x = place_w(place) - (MAP_TILE_W - 1) / 2 - 1; + Map.cam_min_x = MAP_TILE_W / 2; + } else { + Map.cam_min_x = Map.cam_max_x = (place_w(place) + 1)/ 2 - 1; + } + + if (place_h(place) > MAP_TILE_W) { + Map.cam_max_y = place_h(place) - (MAP_TILE_H - 1) / 2 - 1; + Map.cam_min_y = MAP_TILE_H / 2; + } else { + Map.cam_min_y = Map.cam_max_y = (place_h(place) + 1) / 2 - 1; + } +} + +struct mview *mapCreateView(void) +{ + struct mview *v; + + /* Allocate a new view */ + if (!(v = (struct mview *) malloc(MVIEW_SZ))) + return 0; + + /* Initialize the new view */ + memset(v, 0, MVIEW_SZ); + list_init(&v->list); + v->vrect.w = VMASK_W; + v->vrect.h = VMASK_H; + v->zoom = 1; + v->subrect.w = MAP_TILE_W * v->zoom; + v->subrect.h = MAP_TILE_H * v->zoom; + v->subrect.x = (v->vrect.w - v->subrect.w) / 2; + v->subrect.y = (v->vrect.h - v->subrect.h) / 2; + + //dbg("mapCreateView: return %08lx\n", v); + + return v; + +} + +void mapDestroyView(struct mview *view) +{ + //dbg("mapDestroyView(%08lx)\n", view); + free(view); +} + +void mapAddView(struct mview *view) +{ + //dbg("mapAddView(%08lx)\n", view); + list_add(&Map.views, &view->list); +} + +void mapRmView(struct mview *view) +{ + //dbg("mapRmView(%08lx)\n", view); + if (view == ALL_VIEWS) + mapForEachView(myRmView, 0); + else + myRmView(view, 0); +} + +void mapCenterView(struct mview *view, int x, int y) +{ + x -= view->vrect.w / 2; // back up to corner of vrect + y -= view->vrect.h / 2; // back up to corner of vrect + view->vrect.x = place_wrap_x(Map.place, x); + view->vrect.y = place_wrap_y(Map.place, y); +} + +void mapRepaintClock(void) +{ + char * date_time_str = time_HHMM_as_string(); + + if (! DeveloperMode) + return; + + // Show the clock time: + screenErase(&Map.clkRect); + screenPrint(&Map.clkRect, 0, "%s", date_time_str); + screenUpdate(&Map.clkRect); +} // mapRepaintClock() + +/** + * converts points so they appear correctly on wrapping maps + */ +static void map_convert_point_to_vrect(int *x, int *y) +{ + SDL_Rect *vrect = &Map.aview->vrect; + + // If the view rect extends past the right side of the map, and x is + // left of the view rect, then convert x to be right of the view rect. + if ((vrect->x + vrect->w) > place_w(Map.place) && + *x < vrect->x) { + *x += place_w(Map.place); + } + + // Likewise if the view rect extends beyond the southern edge of the + // map, and y is less than the top of the view rect, then convert y to + // be south of the view rect. + if ((vrect->y + vrect->h) > place_h(Map.place) && + *y < vrect->y) { + *y += place_h(Map.place); + } +} + +static void map_paint_cursor(void) +{ + int x, y; + + if (!Session->crosshair->is_active()) + return; + + /* Convert to view rect offset */ + x = Session->crosshair->getX(); + y = Session->crosshair->getY(); + map_convert_point_to_vrect(&x, &y); + if (!point_in_rect(x, y, &Map.aview->vrect)) { + return; + } + + /* Paint it */ + sprite_paint(Session->crosshair->getSprite(), 0, + MX_TO_SX(x), MY_TO_SY(y)); + +} + +/** + * Paint the terrain sprite for a tile. + * + * @param place The place to use as the tile source. + * @param map_x The tile coordinate in the place. + * @param map_y The tile coordinate in the place. + * @param scr_x The screen pixel coordinate to blit to. + * @param scr_y The screen pixel coordinate to blit to. + * @param in_los Zero iff the tile is not in player LOS. + */ +static void map_paint_tile_terrain(struct place *place, int map_x, int map_y, + int scr_x, int scr_y, int in_los) +{ + if (in_los) { + + /* This tile is in player LOS, so paint normally. */ + struct terrain *terrain = place_get_terrain(place, map_x, map_y); + struct sprite *sprite = terrain->sprite; + sprite_paint(sprite, 0, scr_x, scr_y); + + } else if (ShowAllTerrain || XrayVision) { + + /* This tile is not in player LOS, but the command-line option + * to show all terrain or the special XrayVision flag is in + * effect, so paint the terrain but then shade it. */ + struct terrain *terrain = place_get_terrain(place,map_x,map_y); + struct sprite *sprite = terrain->sprite; + sprite_paint(sprite, 0, scr_x, scr_y); + + SDL_Rect shade_rect; + shade_rect.x = scr_x; + shade_rect.y = scr_y; + shade_rect.w = TILE_W; + shade_rect.h = TILE_H; + screenShade(&shade_rect, 128); + } + +} + +/** + * Paint the object sprites for a tile. + * + * @param place The place to use as the tile source. + * @param map_x The tile coordinate in the place. + * @param map_y The tile coordinate in the place. + * @param scr_x The screen pixel coordinate to blit to. + * @param scr_y The screen pixel coordinate to blit to. + * @param in_los Zero iff the tile is not in player LOS. + */ +static void map_paint_tile_objects(struct place *place, int map_x, int map_y, + int scr_x, int scr_y, int in_los) +{ + if (in_los) { + + /* The tile is visible, so paint the objects normally. */ + place_paint_objects(place, map_x, map_y, scr_x, scr_y); + + /* If the crosshair is active but this tile is not in range + * then shade the tile. */ + if (Session->crosshair->is_active() && + Session->crosshair->isRangeShaded() && + ! Session->crosshair->inRange(map_x, map_y)) { + SDL_Rect shade_rect; + shade_rect.x = scr_x; + shade_rect.y = scr_y; + shade_rect.w = TILE_W; + shade_rect.h = TILE_H; + screenShade(&shade_rect, 128); + } + } +} + +/** + * Loop over the map tiles shown in the map viewer, invoking a callback + * function for each tile. + * + * @param place The place viewed. + * @param region The part of the place covered by the visibility mask. Units + * are tiles. + * @param dest The screen rectangle of the viewer. Units are pixels. + * @param mask The visibility mask for the region. Each entry in the mask + * covers one tile. + * @param subrect The part of the place under the viewer (this is contained + * within the region). Units are tiles. + * @param tile_w Tile dimension in pixels. + * @param tile_h Tile dimension in pixels. + */ +static void map_render_loop(struct place *place, + SDL_Rect * region, + SDL_Rect * dest, + unsigned char *mask, + SDL_Rect * subrect, + int tile_h, + int tile_w, + map_tile_render_t tile_render) +{ + int row; + int col; + int map_y; /* in rows */ + int map_x; /* in cols */ + int scr_x; /* in pixels */ + int scr_y; /* in pixels */ + int mask_i; + bool use_mask; + + if (place->wraps) { + region->x = place_wrap_x(place, region->x); + region->y = place_wrap_y(place, region->y); + } + + /* + +-----------------------------------------------------------------+ + | region/mask | + | | + | +-------------------------+ | + | | subrect | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | | | | + | +-------------------------+ | + | | + | | + +-----------------------------------------------------------------+ + */ + + use_mask = (mask != NULL); + map_y = region->y + subrect->y; + mask_i = (subrect->y * region->w) + subrect->x; + + for (row = 0; row < subrect->h; row++, map_y++, mask_i += region->w) { + + /* Test if the row is off-map */ + if (place->wraps) { + map_y = place_wrap_y(place, map_y); + } else if (map_y < 0) { + continue; + } else if (map_y >= place->terrain_map->h) { + break; + } + + /* Set the screen pixel row */ + scr_y = row * tile_h + dest->y; + + /* Set the initial map column for this row */ + map_x = region->x + subrect->x; + + for (col = 0; col < subrect->w; col++, map_x++) { + + int in_los; + + /* Test if the column is off-map */ + if (place->wraps) { + map_x = place_wrap_x(place, map_x); + } else if (map_x < 0) { + continue; + } else if (map_x >= place->terrain_map->w) { + break; + } + + /* Set the screen pixel column */ + scr_x = col * tile_w + dest->x; + + /* Set the LOS flag. */ + in_los = (!use_mask || mask[mask_i + col]); + + /* Invoke the callback function that does the rendering + * for the tile. */ + tile_render(place, map_x, map_y, scr_x, scr_y, in_los); + } + } + +} + +static void mapPaintPlace(struct place *place, + SDL_Rect * region, /* portion of place covered by + * the vmask */ + SDL_Rect * dest, /* screen rectangle */ + unsigned char *mask, /* visibility mask for entire + * region */ + SDL_Rect * subrect, /* sub-rectangle within region + * that the map viewer sees */ + int tile_h, + int tile_w) +{ + /* In order to render giant characters properly over the terrain of + * neighboring tiles, rendering must be done in two passes. The first + * pass renders the terrain, the second the objects. */ + map_render_loop(place, region, dest, mask, subrect, tile_h, tile_w, + map_paint_tile_terrain); + map_render_loop(place, region, dest, mask, subrect, tile_h, tile_w, + map_paint_tile_objects); + place->dirty = 0; +} + + +static void mapRepaintCoordinates(void) +{ + if (! DeveloperMode) { + return; + } + + if (player_party->isOnMap()) { + screenPrint(&Map.locRect, 0, "[%d,%d]", player_party->getX(), + player_party->getY()); + return; + } + + if (NULL != Map.subject) + screenPrint(&Map.locRect, 0, "[%d,%d]", Map.subject->getX(), + Map.subject->getY()); +} + +static void mapRepaintTurnaround(void) +{ + extern int G_turnaround; + + if (! DeveloperMode) + return; + + screenPrint(&Map.turnaroundRect, 0, "TA: %d", G_turnaround); +} + +extern int G_latency_start; +static void mapRepaintLatency(void) +{ + static int latency = 0; + + if (! DeveloperMode) + return; + + latency = SDL_GetTicks() - G_latency_start; + + //printf("repaint: %d\n", latency); + screenPrint(&Map.latencyRect, 0, "LAT: %d", latency); + screenUpdate(&Map.latencyRect); +} + +/** + * This is the main paint routine. + * + * @param view defines which part of the map to show + * @param flags controls controls policies of whether and what to paint + */ +static void mapRepaintView(struct mview *view, int flags) +{ + int t1, t2, t3, t4, t5, t6, t7, t8; + + Map.aview = view; + + if (flags & REPAINT_IF_DIRTY && !view->dirty) + return; + + if (flags & REPAINT_IF_OLD + && (SDL_GetTicks() - Map.last_repaint) < (Uint32)TickMilliseconds + && (Map.last_repaint < SDL_GetTicks())) + return; + + Map.last_repaint = SDL_GetTicks(); + view->dirty = 0; + + G_latency_start = SDL_GetTicks(); + + t1 = SDL_GetTicks(); + + screenErase(&Map.srect); + + t2 = SDL_GetTicks(); + + if (Map.aview->blackout) { + // In blackout mode leave the screen erased + goto done_painting_place; + } + + if (Map.aview->zoom > 1) { + sprite_zoom_out(Map.aview->zoom); + screenZoomOut(Map.aview->zoom); + t5 = SDL_GetTicks(); + mapPaintPlace(Map.place, &view->vrect, &Map.srect, + 0/* vmask */, &view->subrect, + TILE_W / Map.aview->zoom, + TILE_H / Map.aview->zoom); + t6 = SDL_GetTicks(); + screenZoomIn(Map.aview->zoom); + sprite_zoom_in(Map.aview->zoom); + } else if (flags & REPAINT_NO_LOS) { + t5 = SDL_GetTicks(); + mapPaintPlace(Map.place, &view->vrect, &Map.srect, 0, + &view->subrect, TILE_W, TILE_H); + t6 = SDL_GetTicks(); + } else { + + // ------------------------------------------------------------ + // Map.vmask serves as the "master" vmask. Start by zeroing it + // out so that by default nothing is in line-of-sight. Then + // iterate over all the active views (each player party member + // has an active view, spells may add others), and for each + // view merge it's vmask onto the master. The result is the + // line-of-sight for all party members is always visible to the + // player. + // ------------------------------------------------------------ + + memset(Map.vmask, 0, VMASK_SZ); + t3 = SDL_GetTicks(); + mapForEachView(mapMergeView, 0); + //vmask_dump(Map.vmask); + t4 = SDL_GetTicks(); + mapBuildLightMap(view); + t5 = SDL_GetTicks(); + mapPaintPlace(Map.place, &view->vrect, &Map.srect, + (unsigned char *) Map.vmask, &view->subrect, + TILE_W, TILE_H); + t6 = SDL_GetTicks(); + if (! XrayVision) { + myShadeScene(&view->subrect); + } + t7 = SDL_GetTicks(); + map_paint_cursor(); + + // After shading, repaint the tile with the selected object so + // that it shows up brightly even in darkness. + if (Map.selected + && Map.selected->getPlace() == Map.place) + mapUpdateTile(Map.place, + Map.selected->getX(), + Map.selected->getY()); + } + + done_painting_place: + + mapRepaintCoordinates(); + mapRepaintClock(); + mapRepaintTurnaround(); + screenUpdate(&Map.srect); + + // --------------------------------------------------------------------- + // Repaint the latency AFTER the screenUpdate because we want that to + // be part of the time measurement. + // --------------------------------------------------------------------- + + mapRepaintLatency(); + + t8 = SDL_GetTicks(); + + if (PROFILE_REPAINT) { + printf("Total time=%d\n", t8 - t1); + printf(" erase screen=%d\n", t2 - t1); + printf(" memcpy=%d\n", t3 - t2); + printf(" merge vmasks=%d\n", t4 - t3); + printf(" build lightmap=%d\n", t5 - t4); + printf(" paint place=%d\n", t6 - t5); + printf(" shade=%d\n", t7 - t6); + printf(" update screen=%d\n", t8 - t7); + } +} + +static int mapXToViewX(int x) +{ + SDL_Rect *vrect = &Map.aview->vrect; + int x2 = x - vrect->x; + if (x2 < 0 + && place_is_wrapping(Map.place) + && (vrect->x + vrect->w) > place_w(Map.place)) + x2 += place_w(Map.place); + return x2; +} + +static int mapYToViewY(int y) +{ + SDL_Rect *vrect = &Map.aview->vrect; + int y2 = y - vrect->y; + if (y2 < 0 + && place_is_wrapping(Map.place) + && (vrect->y + vrect->h) > place_h(Map.place)) + y2 += place_h(Map.place); + return y2; +} + +int mapTileIsWithinViewport(int x, int y) +{ + SDL_Rect *vrect = &Map.aview->vrect; + int vx = mapXToViewX(x); + int vy = mapYToViewY(y); + if (vx < 0 + || vx >= vrect->w + || vy < 0 + || vy >= vrect->h) + return 0; + return 1; +} + +unsigned char mapTileLightLevel(int x, int y) +{ + int vx = mapXToViewX(x); + int vy = mapYToViewY(y); + return Map.lmap[vy * LMAP_W + vx]; +} + +int mapTileIsVisible(int x, int y) +{ + SDL_Rect *vrect = &Map.aview->vrect; + int vx = mapXToViewX(x); + int vy = mapYToViewY(y); + + // check if coords in vrect + if (vx < 0 + || vx >= vrect->w + || vy < 0 + || vy >= vrect->h) + return 0; + + // If zoomed out then don't bother checking the vmask. + if (Map.aview->zoom > 1) + return 1; + + // Return if the tile is marked as visible + return Map.vmask[vy * vrect->w + vx]; + +} +void mapMarkAsDirty(struct mview *view) +{ + if (view == ALL_VIEWS) + mapForEachView(myMarkAsDirty, 0); + else + myMarkAsDirty(view, 0); +} + +void mapSetRadius(struct mview *view, int rad) +{ + if (view == ALL_VIEWS) + mapForEachView(mySetViewLightRadius, (void *) &rad); + else + mySetViewLightRadius(view, (void *) &rad); +} + +int mapGetRadius(struct mview *view) +{ + return view->rad; +} + +void mapGetMapOrigin(int *x, int *y) +{ + assert(Map.aview); + *x = Map.aview->vrect.x + Map.aview->subrect.x; + *y = Map.aview->vrect.y + Map.aview->subrect.y; +} + +void mapGetScreenOrigin(int *x, int *y) +{ + *x = Map.srect.x; + *y = Map.srect.y; +} + +void mapGetTileDimensions(int *w, int *h) +{ + *w = TILE_W / Map.aview->zoom; + *h = TILE_H / Map.aview->zoom; +} + +void mapSetActiveView(struct mview *view) +{ + Map.aview = view; + //dbg("mapSetActiveView: aview=[%d %d]\n", Map.aview->vrect.x, Map.aview->vrect.y); +} + +void mapCenterCamera(int x, int y) +{ + Map.cam_x = x; + Map.cam_y = y; + + Map.cam_x = place_wrap_x(Map.place, Map.cam_x); + Map.cam_y = place_wrap_y(Map.place, Map.cam_y); + + myAdjustCameraInBounds(); + mapCenterView(Map.cam_view, Map.cam_x, Map.cam_y); +} + +void mapMoveCamera(int dx, int dy) +{ + mapCenterCamera(Map.cam_x + dx, Map.cam_y + dy); +} + +void mapUpdate(int flags) +{ + if (Map.is_image_mode) + return; + + mapRepaintView(Map.cam_view, flags); +} + +void mapSetDirty(void) +{ + if (Map.cam_view != NULL) + Map.cam_view->dirty = 1; +} + +void mapJitter(bool val) +{ + Map.srect.x = MAP_X; + Map.srect.y = MAP_Y; + Map.srect.w = MAP_W; + Map.srect.h = MAP_H; + + if (val) { + Map.srect.x += (rand() % 5) - 2; + Map.srect.y += (rand() % 5) - 2; + } +} + +void mapPeer(bool val) +{ + int dx, dy; + // Peering will apply to the camera view. Set the scale factor and + // adjust the pertinent rectangle dimensions. + Map.peering = val; + if (val) { + Map.cam_view->zoom = PEER_ZOOM; + dx = (Map.cam_view->vrect.w / 2) * (PEER_ZOOM - 1); + dy = (Map.cam_view->vrect.h / 2) * (PEER_ZOOM - 1); + Map.cam_view->vrect.x -= dx; + Map.cam_view->vrect.y -= dy; + Map.cam_view->vrect.w *= PEER_ZOOM; + Map.cam_view->vrect.h *= PEER_ZOOM; + } else { + Map.cam_view->zoom = 1; + Map.cam_view->vrect.w /= PEER_ZOOM; + Map.cam_view->vrect.h /= PEER_ZOOM; + dx = (Map.cam_view->vrect.w / 2) * (PEER_ZOOM - 1); + dy = (Map.cam_view->vrect.h / 2) * (PEER_ZOOM - 1); + Map.cam_view->vrect.x += dx; + Map.cam_view->vrect.y += dy; + } + + Map.cam_view->subrect.w = MAP_TILE_W * Map.cam_view->zoom; + Map.cam_view->subrect.h = MAP_TILE_H * Map.cam_view->zoom; + Map.cam_view->subrect.x = (Map.cam_view->vrect.w - + Map.cam_view->subrect.w) / 2; + Map.cam_view->subrect.y = (Map.cam_view->vrect.h - + Map.cam_view->subrect.h) / 2; + + mapCenterCamera(Map.cam_x, Map.cam_y); // recenter +} + +void mapTogglePeering(void) +{ + mapPeer(!Map.peering); + mapCenterCamera(Map.cam_x, Map.cam_y); // recenter + mapUpdate(0); +} + +void mapGetCameraFocus(struct place **place, int *x, int *y) +{ + *place = Map.place; + *x = Map.cam_x; + *y = Map.cam_y; +} + +int mapIsInCameraView(struct place *place, int x, int y) +{ + int min; + int max; + + if (place != Map.place) + return 0; + + min = Map.cam_view->subrect.x + Map.cam_view->vrect.x; + max = min + Map.cam_view->subrect.w; + + if (x < min || x >= max) + return 0; + + min = Map.cam_view->subrect.y + Map.cam_view->vrect.y; + max = min + Map.cam_view->subrect.h; + + if (y < min || y >= max) + return 0; + + return 1; +} + +void mapBlackout(int val) +{ + Map.cam_view->blackout = !!val; +} + +static void mapPaintProjectile(SDL_Rect *rect, struct sprite *sprite, + SDL_Surface *surf, int dur, int currentframe, bool beam) +{ + // The rect coordinates are in SCREEN coordinates (not map) so I need + // to do some clipping here to make sure we don't paint off the map + // viewer. + if (rect->x < MAP_X || rect->y < MAP_Y || + ((rect->x + rect->w) > (MAP_X + MAP_W)) || + ((rect->y + rect->h) > (MAP_Y + MAP_H))) + return; + + // Save the backdrop of the new location + if (!beam) + screenCopy(rect, NULL, surf); + + // Paint the missile at the new location + sprite_zoom_out(Map.aview->zoom); + screenZoomOut(Map.aview->zoom); + sprite_paint_frame(sprite, currentframe, rect->x, rect->y); + sprite_zoom_in(Map.aview->zoom); + screenZoomIn(Map.aview->zoom); + + screenUpdate(rect); + + SDL_Delay(dur); + + // Erase the missile by blitting the background + if (!beam) + { + screenBlit(surf, NULL, rect); + screenUpdate(rect); + } +} + +void mapPaintDamage(int x, int y) +{ + int tile_w, tile_h; + SDL_Rect rect; + + if (!mapTileIsVisible(x, y)) + return; + + mapGetTileDimensions(&tile_w, &tile_h); + rect.w = tile_w; + rect.h = tile_h; + rect.x = MX_TO_SX(x); + rect.y = MY_TO_SY(y); + + /* Sometimes a damage flash doesn't make sense to the player unless the + * map view is updated first. For example, a character that gets 2x the + * normal action points per turn might move and then attack. The move + * won't be shown until the map is updated. */ + mapUpdate(REPAINT_IF_DIRTY); + + mapPaintProjectile(&rect, Session->damage_sprite, + Map.tile_scratch_surf, 100, 0, false); +} + +//paint damage, but with custom sprite +void mapFlashSprite(int x, int y, struct sprite *sprite) +{ + int tile_w, tile_h; + SDL_Rect rect; + + if (!mapTileIsVisible(x, y)) + return; + + mapGetTileDimensions(&tile_w, &tile_h); + rect.w = tile_w; + rect.h = tile_h; + rect.x = MX_TO_SX(x); + rect.y = MY_TO_SY(y); + + /* Sometimes a damage flash doesn't make sense to the player unless the + * map view is updated first. For example, a character that gets 2x the + * normal action points per turn might move and then attack. The move + * won't be shown until the map is updated. */ + mapUpdate(REPAINT_IF_DIRTY); + + mapPaintProjectile(&rect, sprite, + Map.tile_scratch_surf, 100, 0, false); +} + +void mapAnimateProjectile(int Ax, int Ay, int *Bx, int *By, + struct sprite *sprite, struct place *place, + class Missile *missile, float range) +{ + // + // Derived from Kenny Hoff's Bresenhaum impl at + // http://www.cs.unc.edu/~hoff/projects/comp235/bresline/breslin1.txt + // (no license or copyright noted) + // + int framecount = sprite_num_frames(sprite); + int currentframe = 0; + + int t1, t2; + SDL_Surface * surf; // for saving/restoring the background + + t1 = SDL_GetTicks(); + + // Get tile dimensions + int tile_w; + int tile_h; + mapGetTileDimensions(&tile_w, &tile_h); + + // Half tile offset- missiles fly from and to the middle of a tile + int tile_w_half = tile_w/2; + int tile_h_half = tile_h/2; + + MissileType *mistype = missile->getObjectType(); + bool canEnter = missile->canEnter(); + + // Create a scratch surface for saving/restoring the background + surf = Map.tile_scratch_surf; + assert(surf); + + // Get the map coordinates of the view origin (upper left corner) + int Ox, Oy; + mapGetMapOrigin(&Ox, &Oy); + + // Get the screen coordinates of the map viewer origin + int Sx, Sy; + mapGetScreenOrigin(&Sx, &Sy); + + // Copy the place coordinates of the origin of flight. I'll walk these + // along as the missile flies and check for obstructions. + int Px, Py, oPx, oPy, orx, ory; + Px = Ax; + Py = Ay; + orx = Ax; + ory = Ay; + + // Convert to screen coordinates. (I need to keep the original + // B-coordinates for field effects at the bottom of this routine). + int sBx; + int sBy; + + if (place_is_wrapping(place)) + { + if (Ax > Ox) + Ax = (Ax - Ox) * tile_w + Sx; + else + Ax = (place_w(place) - Ox + Ax) * tile_w + Sx; + if (Ay >= Oy) + Ay = (Ay - Oy) * tile_h + Sy; + else + Ay = (place_h(place) - Oy + Ay) * tile_h + Sy; + + if (*Bx >= Ox) + sBx = (*Bx - Ox) * tile_w + Sx; + else + sBx = (place_w(place) - Ox + *Bx) * tile_w + Sx; + if (*By >= Oy) + sBy = (*By - Oy) * tile_h + Sy; + else + sBy = (place_h(place) - Oy + *By) * tile_h + Sy; + } + else + { + Ax = (Ax - Ox) * tile_w + Sx; + Ay = (Ay - Oy) * tile_h + Sy; + sBx = (*Bx - Ox) * tile_w + Sx; + sBy = (*By - Oy) * tile_h + Sy; + } + + // Create the rect which bounds the missile's sprite (used to update + // that portion of the screen after blitting the sprite). + SDL_Rect rect; + rect.x = Ax; + rect.y = Ay; + rect.w = TILE_W; + rect.h = TILE_H; + + // Get the distance components + int dX = sBx - rect.x; + int dY = sBy - rect.y; + int AdX = abs(dX); + int AdY = abs(dY); + + // Select the sprite orientation based on direction of travel + if (sprite) + { + if ((sprite_facings_list(sprite) & 495) == 495) //nsew + diagonals + { + sprite_set_facing(sprite, vector_to_8facing(dX, dY)); + } + else if ((sprite_facings_list(sprite) & 170) == 170) //nsew only + { + sprite_set_facing(sprite, vector_to_dir(dX, dY)); + } + } + + // Moving left? + int Xincr = (rect.x > sBx) ? -1 : 1; + // adjust for rounding errors + if (rect.x < sBx) + { + tile_w_half--; + } + + // Moving down? + int Yincr = (rect.y > sBy) ? -1 : 1; + // adjust for rounding errors + if (rect.y < sBy) + { + tile_h_half--; + } + + int dPr, dPru, P, i , Xsubincr, Ysubincr; + int oldx, oldy, tempx, tempy; + + //number of steps between missile repaints + int paintloopsize = 20; + + // Walk the x-axis? + if (AdX >= AdY) + { + dPr = AdY << 1; + dPru = dPr - (AdX << 1); + P = dPr - AdX; + Xsubincr = Xincr; + Ysubincr = 0; + if (range > 0.5) // floating point hence error margins + { + i = TILE_W * (place_w(place) + 2); // == "enough": its actually checked in the loop instead + } + else + { + i = AdX; + } + if (AdX==0 && AdY==0) { + // Fix for 2364311: avoid divide-by-zero + paintloopsize = 0; + } else { + paintloopsize = paintloopsize * (AdX*AdX)/((AdX*AdX)+(AdY*AdY)); + } + } + else + { + dPr = AdX << 1; + dPru = dPr - (AdY << 1); + P = dPr - AdY; + Xsubincr = 0; + Ysubincr = Yincr; + + if (range > 0.5) // floating point hence error margins + { + i = TILE_H * (place_h(place) + 2); // == "enough": its actually checked in the loop instead + } + else + { + i = AdY; + } + paintloopsize = paintloopsize * (AdY*AdY)/((AdX*AdX)+(AdY*AdY)); + } + + // firing past selected range, so work out the map edges if need be. + bool checkEdge = ((range >= 1) && !(place_is_wrapping(place))); + + oldx = rect.x; + oldy = rect.y; + + int paintloop = paintloopsize; + + bool beam = missile->getObjectType()->isBeam(); + + // For each step + for (; i >= 0; i--) + { + oPx = Px; + oPy = Py; + Px = place_wrap_x(place, ((tile_w_half + rect.x - Sx) / tile_w + Ox)); + Py = place_wrap_y(place, ((tile_h_half + rect.y - Sy) / tile_h + Oy)); + + if (oPx != Px || oPy != Py) + { + // check edge if required + if (checkEdge) + { + if (Px < 0 || Py < 0 || Px >= place_w(place) || Py >= place_h(place)) + goto done; + } + + // check range if required + if (range>1) + { + if (range < place_flying_distance(place, orx, ory, Px, Py)) + { + //need to back up one square, since we the missile shouldnt have gotten this far + Px = oPx; + Py = oPy; + goto done; + } + } + + // check if blocked by terrain + if (!missile->enterTile(place, Px, Py)) + goto done; + + + //check if callback indicates blocked + if (canEnter & !mistype->fireEnterTile(missile, place, Px, Py)) + goto done; + } + + if (paintloop == 0) + { + // if have done paintloop steps, redraw sprite + paintloop = paintloopsize; + if (mapTileIsVisible(Px, Py) && sprite) + { + tempx = rect.x; + tempy = rect.y; + rect.x = (rect.x + oldx)/2; + rect.y = (rect.y + oldy)/2; + + mapPaintProjectile(&rect, sprite, surf, 15, currentframe, beam); + if (framecount > 1) + currentframe=(currentframe+1)%framecount; + + rect.x = oldx = tempx; + rect.y = oldy = tempy; + + mapPaintProjectile(&rect, sprite, surf, 15, currentframe, beam); + if (framecount > 1) + currentframe=(currentframe+1)%framecount; + } + else if (framecount > 1) + { + currentframe=(currentframe+2)%framecount; + } + } + paintloop--; + + if (P > 0) + { + rect.x += Xincr; + rect.y += Yincr; + P += dPru; + } + else + { + rect.x += Xsubincr; + rect.y += Ysubincr; + P += dPr; + } + } + done: + // erase the missile + // mapRepaintView(NULL, REPAINT_ACTIVE); + if (beam) + SDL_Delay(100); + + mapUpdate(0); + + // restore the missile sprite to the default facing + if (sprite) + sprite_set_facing(sprite, SPRITE_DEF_FACING); + + *Bx = Px; + *By = Py; + + t2 = SDL_GetTicks(); + + if (PROFILE_ANIMATE) { + printf("mapAnimateProjectile: %d msec\n", t2 - t1); + } +} + +void mapAttachCamera(class Object *subject) +{ + Map.subject = subject; +} + +void mapDetachCamera(class Object *subject) +{ + Map.subject = NULL; +} + +void mapUpdateTile(struct place *place, int x, int y) +{ + struct terrain *terrain; + int index; + char *vmask; + SDL_Rect rect; + + //dbg("mapUpdateTile %d:%d:%s\n", x, y, place->name); + + if (NULL == Map.aview) + return; + + + // --------------------------------------------------------------------- + // Assume we want the active view as it was last rendered. Calculate + // the screen coordinates of the given map location. Check if the + // coordinates are in the map viewer and abort if not. + // --------------------------------------------------------------------- + + if (place != Map.place) + return; + + rect.x = (x - (Map.aview->vrect.x + Map.aview->subrect.x)) + * TILE_W/Map.aview->zoom + Map.srect.x; + if (rect.x < Map.srect.x || rect.x > (Map.srect.x + Map.srect.w + - TILE_W/Map.aview->zoom)) + return; + + rect.y = (y - (Map.aview->vrect.y + Map.aview->subrect.y)) + * TILE_H/Map.aview->zoom + Map.srect.y; + if (rect.y < Map.srect.y || rect.y > (Map.srect.y + Map.srect.h + - TILE_H/Map.aview->zoom)) + return; + + // --------------------------------------------------------------------- + // Erase the tile. + // --------------------------------------------------------------------- + + rect.w = TILE_W/Map.aview->zoom; + rect.h = TILE_H/Map.aview->zoom; + screenErase(&rect); + + terrain = place_get_terrain(place, x, y); + + if (Map.aview->zoom > 1) { + + // ------------------------------------------------------------ + // When zoomed ignore LOS. The vmasks aren't big enough to + // cover the area viewed. + // ------------------------------------------------------------ + + sprite_zoom_out(Map.aview->zoom); + screenZoomOut(Map.aview->zoom); + sprite_paint(terrain->sprite, 0, rect.x, rect.y); + place_paint_objects(place, x, y, rect.x, rect.y); + sprite_zoom_in(Map.aview->zoom); + screenZoomIn(Map.aview->zoom); + + } else { + + // ------------------------------------------------------------ + // If the place is not in line-of-sight then don't paint the + // object(s) there. Paint the terrain iff ShowAllTerrain or + // XrayVision are in effect. + // ------------------------------------------------------------ + + vmask = Map.vmask; + index = ((y - Map.aview->vrect.y) * Map.aview->vrect.w) + + (x - Map.aview->vrect.x); + + if (vmask[index] || ShowAllTerrain || XrayVision) { + sprite_paint(terrain->sprite, 0, rect.x, rect.y); + } + + if (vmask[index]) { + place_paint_objects(place, x, y, rect.x, rect.y); + } + + // If the selected object is not on this tile then shade it + if (! Map.selected + || Map.selected->getPlace() != Map.place + || Map.selected->getX() != x + || Map.selected->getY() != y) + screenShade(&rect, LIT - Map.lmap[index]); + + } + + if (x == Session->crosshair->getX() && y == Session->crosshair->getY()) + map_paint_cursor(); + + + + + screenUpdate(&rect); + +} + +void mapSetSelected(class Object *obj) +{ + if (Map.selected == obj) + return; + + if (Map.selected) { + obj_dec_ref(Map.selected); + Map.selected = NULL; + } + + Map.selected = obj; + if (obj) + obj_inc_ref(obj); +} + +int mapScreenToPlaceCoords(int *x, int *y) +{ + if (! point_in_rect(*x, *y, &Map.srect)) { + return -1; + } + int px = ((*x - Map.srect.x) * Map.aview->zoom) / TILE_W + Map.aview->vrect.x + Map.aview->subrect.x; + int py = ((*y - Map.srect.y) * Map.aview->zoom) / TILE_H + Map.aview->vrect.y + Map.aview->subrect.y; + + if (place_off_map(Map.place, px, py)) { + return -1; + } + + *x = place_wrap_x(Map.place, px); + *y = place_wrap_y(Map.place, py); + return 0; +} + +void mapSetImage(SDL_Surface *image) +{ + Map.is_image_mode = 1; + if (image) { + /* center the image over the map */ + SDL_Rect rect = Map.srect; + if (image->w < Map.srect.w) { + rect.x = Map.srect.x + (Map.srect.w - image->w) / 2; + rect.w = image->w; + } + if (image->h < Map.srect.h) { + rect.y = Map.srect.y + (Map.srect.h - image->h) / 2; + rect.h = image->h; + } + screenErase(&Map.srect); + screenBlit(image, NULL, &rect); + } else { + screenErase(&Map.srect); + } + screenUpdate(&Map.srect); +} + +void mapClearImage(void) +{ + Map.is_image_mode = 0; +} + +void mapBlitImage(SDL_Surface *image, Uint32 x, Uint32 y) +{ + SDL_Rect rect; + + rect.x = Map.srect.x + x; + rect.y = Map.srect.y + y; + rect.w = Map.srect.w - x; + rect.h = Map.srect.h - y; + + screenBlit(image, NULL, &rect); + screenUpdate(&Map.srect); +} diff --git a/src/map.h b/src/map.h new file mode 100644 index 0000000..b662db2 --- /dev/null +++ b/src/map.h @@ -0,0 +1,126 @@ +// +// nazghul - an old-school RPG engine +// Copyright (C) 2002, 2003 Gordon McNutt +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 of the License, or (at your option) +// any later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +// more details. +// +// You should have received a copy of the GNU General Public License along with +// this program; if not, write to the Free Foundation, Inc., 59 Temple Place, +// Suite 330, Boston, MA 02111-1307 USA +// +// Gordon McNutt +// gmcnutt@users.sourceforge.net +// +#ifndef map_h +#define map_h + +#include "macros.h" +#include + +BEGIN_DECL + +/* In general, this is valid for functions which take only a 'view' arg */ +#define ALL_VIEWS ((struct mview *)-1) + +/* Flags for mapRepaintView() */ +#define REPAINT_IF_DIRTY 1 /* repaint iff the view is dirty */ +#define REPAINT_NO_LOS 2 /* don't apply LOS */ +#define REPAINT_IF_OLD 4 /* repaint iff last repaint < tick ms ago */ + +extern int map_use_circular_vision_radius; + +struct mview; +struct place; + +extern int mapInit(void); +extern void mapFlash(int mdelay); +extern void mapSetPlace(struct place *place); + +extern struct mview *mapCreateView(void); +extern void mapDestroyView(struct mview *view); +extern void mapAddView(struct mview *view); +extern void mapRmView(struct mview *mview); +extern void mapCenterView(struct mview *view, int x, int y); +extern void mapRecomputeLos(struct mview *view); +extern void mapSetRadius(struct mview *view, int rad); +extern int mapGetRadius(struct mview *view); + +// Hacked in to support missile animation: +extern void mapGetMapOrigin(int *x, int *y); +extern void mapGetScreenOrigin(int *x, int *y); + +extern void mapCenterCamera(int x, int y); +extern void mapMoveCamera(int dx, int dy); +extern void mapUpdate(int flags); +extern void mapSetDirty(void); + +extern void mapRepaintClock(void); +extern void mapJitter(bool val); // added for tremor +extern void mapPeer(bool val); +extern void mapTogglePeering(void); + +extern void mapGetCameraFocus(struct place **place, int *x, int *y); +extern int mapIsInCameraView(struct place *place, int x, int y); + +extern int mapTileIsWithinViewport(int x, int y); +extern int mapTileIsVisible(int x, int y); +extern unsigned char mapTileLightLevel(int x, int y); + +extern void mapBlackout(int val); // for sleeping in town + +// The destination (dx, dy) point is an in-out parm, upon return it +// points to the location where the missile actually landed (in case it +// was blocked in its path) +extern void mapAnimateProjectile(int ox, int oy, int *dx, int *dy, + struct sprite *sprite, + struct place *place, + class Missile *missile, + float range); + +extern void mapAttachCamera(class Object *subject); +extern void mapDetachCamera(class Object *subject); +extern void mapSetLosStyle(const char *los); +extern void mapUpdateTile(struct place *place, int x, int y); +extern void mapPaintDamage(int x, int y); +extern void mapSetSelected(class Object *obj); +extern void mapFlashSprite(int x, int y, struct sprite *sprite); + +extern int mapScreenToPlaceCoords(int *x, int *y); + +/** + * Instead of showing the current place, show an image. This lasts until + * mapClearImage() is called. + * + * @param image The image to show. If null, the map is erased instead (ie, + * blacked-out). + */ +extern void mapSetImage(SDL_Surface *image); + +/** + * Turn off the image set via mapSetImage() and resume showing the current + * place. + */ +extern void mapClearImage(void); + +/** + * Blit an image onto the map window. This lasts until something else is + * painted over it. The image will be clipped to fit within the map + * window. This function will update the screen before returning. + * + * @param image is the image to show. It should not be NULL. + * @param x is the pixel offset within the map window to blit it. + * @param y is the pixel offset within the map window to blit it. + */ +extern void mapBlitImage(SDL_Surface *image, Uint32 x, Uint32 y); + +END_DECL + +#endif diff --git a/src/menus.c b/src/menus.c new file mode 100644 index 0000000..738910b --- /dev/null +++ b/src/menus.c @@ -0,0 +1,1816 @@ +/* $Id: menus.c,v 1.41 2010/08/26 05:56:21 gmcnutt Exp $ + * + * Copyright (C) 2006 Gordon McNutt + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Foundation, Inc., 59 Temple Place, + * Suite 330, Boston, MA 02111-1307 USA + */ + +#include "menus.h" + +#include "ascii.h" +#include "cfg.h" +#include "conv.h" +#include "cmd.h" +#include "cmdwin.h" +#include "console.h" +#include "event.h" +#include "foogod.h" +#include "log.h" +#include "list.h" +#include "map.h" +#include "screen.h" +#include "status.h" +#include "file.h" +#include "nazghul.h" + +#include "session.h" /* added for demo */ +#include "place.h" /* added for demo */ +#include "sprite.h" /* added for demo */ +#include "tick.h" /* added for demo */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOADSAVE_HINT "\005\006=scroll ENT=select DEL=delete ESC=exit" + +/** + * Enable this option to have the a "L)oad Game" menu item in addition to the + * "J)ourney Onward" menu item. When this is enabled J)ourney Onward + * automatically picks the last saved game. Otherwise, J)ourney Onward works + * like L)oad Game, providing a list of all saved games, with the most recently + * saved one at the top. + */ +#ifndef CONFIG_LOAD_GAME_OPTION +#define CONFIG_LOAD_GAME_OPTION 0 +#endif + +/** + * Information about saved game files. + */ +typedef struct saved_game { + struct list list; /**< For menu_saved_games list */ + char *fname; /**< Filename (w/o path) */ + char *path; /**< Full pathname to save file */ + time_t timestamp; /**< Last modification time */ + int ref; /**< Reference count on this struct */ + SDL_Surface *screenshot; /**< Map screenshot */ + char is_current; /**< is this the currently loaded game? */ +} saved_game_t; + +/** + * The context used for the menu_scroll function. This keeps track of the + * currently selected saved game from the menu and communicates a player abort + * back to the menu code. + */ +typedef struct { + saved_game_t *save; /**< Currently highlighted saved game */ + char *entry; /**< Currently highlighted string entry */ + char *hotkeys; /**< Hotkey characters, in order of listing */ + const char **menu; /**< Menu strings */ + int n_menu; /**< Number of menu strings */ + const char *title; /**< Menu title */ + char abort : 1; /**< The player aborted the selection */ +} menu_scroll_data_t; + + +/** + * The list of saved games, built when we evaluate the saved-game script for + * the load and save menus. + */ +static struct list menu_saved_games; + +/** + * Keep track of the name of the currently loaded game so we can mark it in the + * load and save menus. + */ +static saved_game_t *menu_current_saved_game = 0; + +/** + * This is what the Save Game menu shows for the new game option. + */ +static const char *MENU_NEW_GAME_STR = "N)ew Saved Game"; + +/** + * This is a hack added to support demo mode. I'll try to explain, because it's + * convoluted. Normally (before I added demo support) the main menu runs an + * event loop by calling eventHandle(), which returns when the user makes a + * choice. + * + * For demo mode, I added an extra wrinkle. When I setup the demo I push a tick + * handler (I mean animation ticks, which are usually disabled until we start + * the game, but for demo mode I need them). The tick handler calls + * place_exec() to run the demo. The idea is we would run the demo more or less + * concurrently with our processing of user keystrokes in the main menu, but of + * course we're doing it all on a single thread. + * + * Running place_exec() on every tick caused a lot of latency in our response + * to handling user keypresses. So I added the first hack: place_exec() will + * call eventHandlePending() after processing each object. That gives us a + * chance to process user keystrokes more frequently while the demo is + * running. The simplified call tree when the user hits to select a + * menu item is something like this: + * + * main_menu + * `-eventHandle + * `-menu_demo_tick_handler + * `-place_exec + * `-eventHandlePending + * + * Normally we're directly in eventHandle when the player presses , and + * we fall back to main_menu and handle the selection. But if we're in + * eventHandlePending this doesn't happen, and we keep on handling events, so + * the player perceives this as a dropped keystroke. + * + * To "fix" it I added the main_menu_handled variable. This causes the + * menu_demo_tick_handler to return a value that kicks eventHandle out of its + * loop when the user selects . + */ +int main_menu_handled = 0; + +/** + * Another hack for demos! What fun. Little flag to let the main menu code know + * that the demo is done and doesn't need to keep running any more, thanks. + */ +int demo_done = 0; + +/** + * Delete a saved game struct and all it's strings. Don't call this, use + * saved_game_unref(). + * + * @param save The struct to delete. + */ +static void saved_game_del(saved_game_t *save) +{ + assert(! save->ref); + + if (save->fname) + free(save->fname); + if (save->path) + free(save->path); + if (save->screenshot) + SDL_FreeSurface(save->screenshot); + free(save); +} + +/** + * Infer the filename of a screenshot from the filename for the saved game. + * + * @param save The saved game that goes with the screenshot. + * @returns The full pathname to the screenshot file. The caller should free() + * the string when done using it. + */ +static char *saved_game_mk_screenshot_fname(saved_game_t *save) +{ + char *s_fname = (char*)malloc(strlen(save->path)+5); + assert(s_fname); + sprintf(s_fname, "%s.png", save->path); + return s_fname; +} + +/** + * Create a new saved game struct and populate it's fields. This makes a copy + * of the fname, creates a copy of the full pathname, and gets the modification + * time of the file. + * + * @param fname Name of the saved game file. + * @returns The new struct or 0 if there was a problem accessing the file or + * allocating memory. + */ +static saved_game_t *saved_game_new(char *fname) +{ + struct stat fileinfo; + char *s_fname = 0; + saved_game_t *save = (saved_game_t*)malloc(sizeof(*save)); + if (!save) { + warn("Could not alloc save\n"); + return 0; + } + + memset(save, 0, sizeof(*save)); + + list_init(&save->list); + + /* Keep a copy of the file name. */ + save->fname = strdup(fname); + if (! save->fname) { + warn("Could not alloc fname\n"); + goto abort; + } + + /* Build the full path. */ + save->path = file_mkpath(cfg_get("saved-games-dirname"), fname); + if (!save->path) { + warn("Could not alloc filename\n"); + goto abort; + } + + /* Get the timestamp on the file. */ + if (! stat(save->path, &fileinfo)) { + save->timestamp = fileinfo.st_mtime; + } else { + /* This is probably a new save that hasn't been written to file + * yet. Use the current time as it's timestamp. */ + save->timestamp = time(0); + } + + /* Load the screenshot. Ignore failure. */ + s_fname = saved_game_mk_screenshot_fname(save); + if (file_exists(s_fname)) { + save->screenshot = IMG_Load(s_fname); + } + free(s_fname); + + save->ref = 1; + return save; + + abort: + saved_game_del(save); + return 0; +} + +/** + * Release a reference to a saved game struct. This could destroy it. + * + * @param save The struct to release. + */ +static void saved_game_unref(saved_game_t *save) +{ + assert(save->ref); + save->ref--; + if (!save->ref) { + saved_game_del(save); + } +} + +/** + * Called when the user kills the window during the main menu. Exits the + * program. + * + * @param kh Unused + * @returns Nothing, the program exits. + */ +static bool main_menu_quit_handler(struct QuitHandler *kh) +{ + exit(0); + return(0); /* for Sun compiler */ +} + +/** + * Shows the game credits in the status window. + */ +static void show_credits(void) +{ + struct KeyHandler kh; + const char *title = "Credits"; + const char *text = + "Engine Programming\n"\ + "...Gordon McNutt\n"\ + "...Kris Parker\n"\ + "...Sam Glasby\n"\ + "...Tim Douglas\n"\ + "...Janne Johansson\n"\ + "...Karl Garrison\n"\ + "Build System\n"\ + "...Andreas Bauer\n"\ + "Game Scripting\n"\ + "...Gordon McNutt\n"\ + "...Kris Parker\n"\ + "...Sam Glasby\n" + "Art Provided by\n"\ + "...Joshua Steele\n"\ + "...David Gervais\n"\ + "...Kris Parker\n" + "...Kevin Gabbert\n"\ + "...Gordon McNutt\n"\ + "...Sam Glasby\n"\ + "...Steve Riberdy\n"\ + "Music Provided by\n"\ + "...Jim Paterson\n"\ + ; + + statusSetPageText(title, text); + statusSetMode(Page); + consolePrint("[Hit ESC to continue]\n"); + + kh.fx = scroller; + kh.data = NULL; + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); +} + +/** + * Prompts the user to confirm that they want to overwrite a saved game. + * + * @returns 1 On confirm, 0 on cancel. + */ +static int confirm_selection() +{ + int yesno; + log_msg("Existing saved game will be overwritten! Are you sure?"); + cmdwin_clear(); + cmdwin_spush("Confirm"); + cmdwin_spush(""); + getkey(&yesno, yesnokey); + cmdwin_pop(); + if (yesno=='y') { + cmdwin_spush("yes!"); + log_msg("Ok!"); + return 1; + } else { + cmdwin_spush("no!"); + log_msg("Canceled!"); + return 0; + } +} + +/** + * Add another saved game to the list. This is called as a result of executing + * the saved-games script, which is just a sequence of (kern-add-saved-game + * ) procedure calls, each of which lands here. Based on the filename + * we'll build out the other info associated with the saved game like the + * timestamp and screenshot image. This also adds the saved game to the list in + * order sorted by timestamp, using a simple insertion sort algorithm. + * + * @param fname The name of the saved game file. + */ +void menu_add_saved_game(char *fname) +{ + struct list *lptr; + + /* Create a new saved game list element. */ + saved_game_t *save = saved_game_new(fname); + if (!save) { + warn("menu_add_saved_game: could not add '%s'\n", fname); + return; + } + + /* Insert it in the list ordered by timestamp. Find the first saved + * game in the list which has a timestamp after this one. */ + lptr = menu_saved_games.next; + while (lptr != &menu_saved_games) { + saved_game_t *save2 = outcast(lptr, saved_game_t, list); + if (save->timestamp > save2->timestamp) { + break; + } + lptr = lptr->next; + } + + /* Insert this one previous to it. Works for empty lists, too. */ + list_add_tail(lptr, &save->list); +} + +/** + * Print the saved game's name, timestamp and other info for display in the + * status window. + * + * @param buf The string buffer to hold the printed line. + * @param n The size in bytes of the string buffer (including a terminating + * NULL). + * @param fname The name of the saved game file, not including the full path. + */ +static int sprintf_game_info(char *buf, int n, saved_game_t *save, char hotkey) +{ + struct tm *timeinfo; + int ret = -1; + char datebuf[n]; + int padlen; + char mark = ' '; + + /* Convert the timestamp from epoch to a time structure. */ + timeinfo = localtime(&save->timestamp); + + /* Print the date to a temp buffer to see how big it is. */ + snprintf(datebuf, n, "%02d:%02d %02d/%02d/%d", timeinfo->tm_hour, + timeinfo->tm_min, timeinfo->tm_mon, timeinfo->tm_mday, + 1900+timeinfo->tm_year); + + /* Calculate necessary padding to right-justify the date. */ + padlen = n - (strlen(save->fname) + + strlen(datebuf) + + 3 + + (hotkey ? 3 : 0)); + + /* We'll mark the current game with an '*'. */ + if (save->is_current) { + mark = '*'; + } + + /* Print to the buffer. */ + if (hotkey) { + snprintf(buf, n, "%c) %s %*c%c%s", hotkey, save->fname, + padlen, ' ', mark, datebuf); + } else { + snprintf(buf, n, "%s %*c%c%s", save->fname, + padlen, ' ', mark, datebuf); + } + return ret; + +} + +/** + * Extract the filename from the menu entry strings used in the load and save + * game menus. + * @returns A strdup'd copy of the fname. + */ +static char *menu_entry_to_fname(char *entry) +{ + char *fname, *end; + int mod; + + /* Most saved games entries start with x), where x is a 0-9 */ + if (isdigit(entry[0]) && ')' == entry[1]) { + entry += 3; + } + + end = strchr(entry, ' '); + mod = end ? 1 : 0; + if (mod) + *end = 0; + fname = strdup(entry); + assert(fname); + if (mod) + *end = ' '; + return fname; +} + +/** + * Reset the current saved game. + * @param save A pointer to the new saved game struct. + */ +static void menu_set_current_saved_game(saved_game_t *save) +{ + if (menu_current_saved_game) { + menu_current_saved_game->is_current = 0; + saved_game_unref(menu_current_saved_game); + menu_current_saved_game = 0; + } + menu_current_saved_game = save; + if (save) { + save->is_current = 1; + save->ref++; + /* Move it to the front of the list. */ + list_remove(&save->list); + list_add(&menu_saved_games, &save->list); + } +} + +/** + * Search the list of saved games for one with the given file name. + * + * @param fname Filename to search for. + * @returns The saved game with the matching filename, or 0 if none found. + */ +static saved_game_t *saved_game_lookup(char *fname) +{ + struct list *lptr; + list_for_each(&menu_saved_games, lptr) { + saved_game_t *save = outcast(lptr, saved_game_t, list); + if (! strcmp(fname, save->fname)) + return save; + } + return 0; +} + +/** + * Show a screenshot over the map viewer with the words "SCREEN SHOT" in the + * middle. + * + * @param screenshot The image to show, or 0 to just show a blank screen. For a + * blank screen the words "SCREEN SHOT" are still printed. + */ +static void menu_show_screenshot(SDL_Surface *screenshot) +{ + static const char *MENU_SCREEN_SHOT_STR = "^c+ySCREEN SHOT^c-"; + SDL_Rect rect; + + mapSetImage(screenshot); + rect.x = (((MAP_X + MAP_W) / 2) - (5 * ASCII_W)); + rect.y = (MAP_Y + MAP_H)/4; + rect.w = strlen(MENU_SCREEN_SHOT_STR); + rect.h = ASCII_H; + screenPrint(&rect, 0, MENU_SCREEN_SHOT_STR); + + rect.w *= ASCII_W; + screenUpdate(&rect); +} + +/** + * Get the highlighted menu item from the status viewer and figure out which + * saved game it corresponds to. + * + * @returns The saved game struct that goes with the menu entry, or 0 if the + * "New Game" option is highlighted. + */ +static saved_game_t *menu_scroller_get_selected() +{ + char *fname; + char *entry_str = (char*)statusGetSelected(String); + if (!entry_str) { + return 0; + } + if (! strcmp(entry_str, MENU_NEW_GAME_STR)) { + return 0; + } + fname = menu_entry_to_fname(entry_str); + return saved_game_lookup(fname); +} + +/** + * Rewrite the saved-game script, using the current list of saved games. + * + * @returns -1 on error, 0 on success. + */ +static int menu_rewrite_saves() +{ + FILE *file; + struct list *lptr; + char *fname = cfg_get("save-game-filename"); + + file = file_open_in_save_dir(fname, "w"); + if (! file) { + warn("Problem updating %s: %s\n", fname, file_get_error()); + return -1; + } + + list_for_each(&menu_saved_games, lptr) { + saved_game_t *save = outcast(lptr, saved_game_t, list); + fprintf(file, "(kern-add-save-game \"%s\")\n", save->fname); + } + + fclose(file); + return 0; +} + +/** + * Prompt the user to delete the currently highlighted save-game. This checks + * if the highlighted entry is a valid save game, prompts the user to confirm + * the deletetion, deletes the save file and the screenshot file, removes the + * saved game struct from the list, unrefs it, and re-writes the saved game + * script. + * + * If the save-game or screenshot files can't be deleted the operation warns + * the user but continues to remove and unreference the saved game. It will + * appear again the next time nazghul is restarted. + */ +static void menu_prompt_to_delete(menu_scroll_data_t *data) +{ + char *selstr = 0; + saved_game_t *save = 0; + int yesno = 0; + int i1, i2; + + /* Check if user tried to delete the N)ew Saved Game option */ + selstr = (char*)statusGetSelected(String); + if (! strcmp(selstr, MENU_NEW_GAME_STR)) + return; + + /* Get the saved game struct for the selection. */ + save = menu_scroller_get_selected(); + if (!save) + return; + + /* Prompt to confirm. */ + log_begin("Delete %s?", save->fname); + log_flush(); + cmdwin_clear(); + cmdwin_push("Delete-"); + cmdwin_push(""); + getkey(&yesno, yesnokey); + cmdwin_pop(); + + /* If confirmation denied then cancel. */ + if (yesno == 'n') { + cmdwin_spush("abort!"); + log_end(" Canceled!"); + return; + } + + /* Confirmed, try to delete the save file. Abort if it doesn't work. */ + cmdwin_push("yes!"); + statusFlashSelected(Red); + if (unlink(save->path)) { + log_continue(" WARNING! Failed to delete save file %s: %s", + save->path, strerror(errno)); + } + + /* Try to delete the screenshot. Warn the user and continue if it + * doesn't work. */ + if (save->screenshot) { + char *scr_fname = saved_game_mk_screenshot_fname(save); + if (unlink(scr_fname)) { + log_continue(" WARNING! Failed to delete screenshot "\ + "file %s: %s:", scr_fname, + strerror(errno)); + } + free(scr_fname); + } + + /* Remove and unreference the saved game struct. */ + list_remove(&save->list); + if (save == menu_current_saved_game) { + menu_set_current_saved_game(0); + } + saved_game_unref(save); + + /* Re-write the saved game script. */ + menu_rewrite_saves(); + + /* Reshuffle all the menu entries to close the gap and reset the status + * menu list. */ + i1 = statusGetSelectedIndex(String); + assert(i1 >= 0); + for (i2 = i1; i2 < data->n_menu-1; i2++) { + data->menu[i2] = data->menu[i2+1]; + } + data->menu[i2] = 0; + data->n_menu--; + statusSetStringList(data->title, data->n_menu, data->menu); + + /* Disable repainting while re-setting the mode to avoid the ugly + * flashes on the top line. */ + statusDisableRepaint(); + statusSetMode(StringList); + statusEnableRepaint(); + + statusSetSelectedIndex(i1 ? (i1 - 1) : 0); + /*statusRepaint();*/ + + log_end(" Removed!"); +} + +/** + * Scroll the status window for the load/save menus. As the player scrolls over + * a saved game, show its screenshot on the map window. + * + * @param kh Keyhandler with the menu context as its data element. + * @param key The key pressed by the player. + * @param keymod Reflects the status of the SHIFT, CTRL and ALT keys. + * @returns 0 to keep the Status window in scroll mode, 1 to end it. + */ +int menu_scroller(struct KeyHandler * kh, int key, int keymod) +{ + menu_scroll_data_t *data = (menu_scroll_data_t *) kh->data; + enum StatusScrollDir dir; + int i1; + + if (data->hotkeys && key < 128) { + char ckey = (char)key; + char *hotkey = strchr(data->hotkeys, ckey); + if (hotkey) { + int index = hotkey - data->hotkeys; + printf("ckey=%c index=%d\n", ckey, index); + statusSetSelectedIndex(index); + statusFlashSelected(Green); + data->entry = (char*)statusGetSelected(String); + data->save = menu_scroller_get_selected(); + return 1; + } + } + + switch (key) { + case KEY_NORTH: + dir = ScrollUp; + break; + case KEY_SOUTH: + dir = ScrollDown; + break; + case SDLK_PAGEUP: + dir = ScrollPageUp; + break; + case SDLK_PAGEDOWN: + dir = ScrollPageDown; + break; + case SDLK_HOME: + dir = ScrollTop; + break; + case SDLK_END: + dir = ScrollBottom; + break; + case SDLK_RETURN: + case SDLK_SPACE: + case KEY_HERE: + case '\n': + i1 = statusGetSelectedIndex(String); + statusFlashSelected(Green); + data->entry = (char*)statusGetSelected(String); + data->save = menu_scroller_get_selected(); + return 1; + case SDLK_ESCAPE: + case 'q': + data->abort = 1; + return 1; + case SDLK_DELETE: + case 'd': + menu_prompt_to_delete(data); + return data->n_menu ? 0 : 1; + default: + return 0; + } + + statusScroll(dir); + data->entry = (char*)statusGetSelected(String); + data->save = menu_scroller_get_selected(); + menu_show_screenshot(data->save ? data->save->screenshot : 0); + + return 0; +} + +/** + * Scroll the status window for the main menu. + * + * @param kh Keyhandler with the menu context as its data element. + * @param key The key pressed by the player. + * @param keymod Reflects the status of the SHIFT, CTRL and ALT keys. + * @returns 0 to keep the Status window in scroll mode, 1 to end it. + */ +int main_menu_scroller(struct KeyHandler * kh, int key, int keymod) +{ + menu_scroll_data_t *data = (menu_scroll_data_t *) kh->data; + enum StatusScrollDir dir; + + if (data->hotkeys && key < 128) { + char ckey = (char)key; + char *hotkey = strchr(data->hotkeys, ckey); + if (hotkey) { + int index = hotkey - data->hotkeys; + printf("ckey=%c index=%d\n", ckey, index); + statusSetSelectedIndex(index); + data->entry = (char*)statusGetSelected(String); + return 1; + } + } + + switch (key) { + case KEY_NORTH: + dir = ScrollUp; + break; + case KEY_SOUTH: + dir = ScrollDown; + break; + case SDLK_PAGEUP: + dir = ScrollPageUp; + break; + case SDLK_PAGEDOWN: + dir = ScrollPageDown; + break; + case SDLK_RETURN: + case SDLK_SPACE: + case KEY_HERE: + case '\n': + data->entry = (char*)statusGetSelected(String); + main_menu_handled = 1; + return 1; + case SDLK_ESCAPE: + case 'q': + data->abort = 1; + main_menu_handled = 1; + return 1; + default: + return 0; + } + + statusScroll(dir); + data->entry = (char*)statusGetSelected(String); + + return 0; +} + +/** + * Get a suitable hotkey for the numeral. + * + * @param i The number of the hotkey. + * @returns ASCII 0-9 or NULL if i is out of range. + */ +static char menu_hotkey(int i) +{ + return (i < 10) ? (i + '0') : 0; +} + +/** + * Find the most recently saved game. + * + * @returns A copy of the full pathname of the most recently saved game, or 0 + * if there are no saved games. + */ +char * journey_onward(void) +{ + char *ret = 0; + saved_game_t *save; + + if (list_empty(&menu_saved_games)) { + return 0; + } + + /* Since the saved game list is kept sorted by modification time, the + * first element in the list is the most recent. */ + save = outcast(menu_saved_games.next, saved_game_t, list); + ret = strdup(save->path); + menu_set_current_saved_game(save); + return ret; +} + +/** + * Give the user a choice of saved games to load, with the most recently saved + * always at the top for easy access. If there is only one saved game then + * don't bother asking, just load it directly. + * + * @returns A copy of the full pathname of the game file to load, or 0 if the + * player canceled. + */ +char * load_game_menu(void) +{ + const char **menu = 0; + char *menubuf, *menubufptr; + int n = 0; + int i = 0; + struct list *lptr = 0; + struct KeyHandler kh; + menu_scroll_data_t data; + char *selection = 0; + enum StatusMode omode = statusGetMode(); + int linew = STAT_CHARS_PER_LINE; + + /* If there is only one saved game then just load it without prompting + * the user. */ + if (1 == list_len(&menu_saved_games)) { + return journey_onward(); + } + + memset(&data, 0, sizeof(data)); + + /* Allocate the memory for the menu strings. */ + n = list_len(&menu_saved_games); + menubuf = (char*)calloc(n, linew+1); + assert(menubuf); + menu = (const char**)calloc(n, sizeof(menu[0])); + assert(menu); + + data.hotkeys = (char*)calloc(n + 1, 1); + assert(data.hotkeys); + data.menu = menu; + data.n_menu = n; + data.title = "Load Game"; + + /* Add each saved game to the menu list. */ + menubufptr = menubuf; + list_for_each(&menu_saved_games, lptr) { + saved_game_t *save = outcast(lptr, saved_game_t, list); + menu[i] = menubufptr; + data.hotkeys[i] = menu_hotkey(i); + sprintf_game_info(menubufptr, linew+1, save, data.hotkeys[i]); + menubufptr += linew+1; + i++; + } + + foogodSetHintText(LOADSAVE_HINT); + foogodSetMode(FOOGOD_HINT); + statusSetStringList(data.title, n, menu); + statusSetMode(StringList); + + /* Setup the initial screen shot */ + if (list_empty(&menu_saved_games)) { + menu_show_screenshot(0); + } else { + saved_game_t *save = outcast(menu_saved_games.next, + saved_game_t, list); + menu_show_screenshot(save->screenshot); + } + + kh.fx = menu_scroller; + kh.data = &data; + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + + /* If the player selected something then build the full pathname for + * return. */ + if (! data.abort + && data.save) { + selection = strdup(data.save->path); + assert(selection); + menu_set_current_saved_game(data.save); + } + + mapClearImage(); + + /* If the original status mode was already StringList don't reset the + * mode, this will cause status to highlight the top list entry of our + * list and it looks funny while we're loading the game. */ + if (omode != StringList) + statusSetMode(omode); + + foogodSetMode(FOOGOD_DEFAULT); + free(menu); + free(menubuf); + free(data.hotkeys); + + return selection; +} + +/** + * Filter characters we don't want to show in filenames. + * + * @param key A keypress code, usually ASCII. + * @returns 1 to reject the character, 0 to allow it. + */ +static int menu_fname_filter(int key) +{ + if (isalnum(key) + || (key=='_') + || (key=='-') + || (key=='.')) { + return 0; + } else { + return 1; + } +} + +/** + * Get a file name from the player. + * @returns A strdup'd copy of the filename. + */ +static char *prompt_for_fname() +{ + char buf[32]; + + log_msg("Enter the new filename."); + cmdwin_clear(); + cmdwin_push("Filename: "); + + if (ui_getline_filtered(buf, sizeof(buf), menu_fname_filter)) { + return strdup(buf); + } + return 0; +} + +/** + * Let the player select a file to save the current game. + * + * @returns A strdup'd copy of the name of the file to save to, or 0 if the + * player aborts. The filename is NOT the full path, like some of the other + * menu functions return, because we're not going to load anything with the + * result. + */ +char * save_game_menu(void) +{ + const char **menu = 0; + char *menubuf, *menubufptr; + int n = 0; + int i = 0; + struct list *lptr = 0; + struct KeyHandler kh; + menu_scroll_data_t data; + enum StatusMode omode = statusGetMode(); + int linew = STAT_CHARS_PER_LINE; + saved_game_t *selected_game = 0; + + memset(&data, 0, sizeof(data)); + + /* Allocate the string buffers to display the menu. */ + n = list_len(&menu_saved_games) + 1; + menubuf = (char*)calloc(n, linew+1); + assert(menubuf); + menu = (const char**)calloc(n, sizeof(menu[0])); + assert(menu); + + data.hotkeys = (char*)calloc(n+1, 1); + assert(data.hotkeys); + data.menu = menu; + data.n_menu = n; + data.title = "Save Game"; + + /* Prepare to fill in the menu list. */ + i = 0; + menubufptr = menubuf; + + /* The first entry is always the New Save Game option. */ + sprintf(menubufptr, MENU_NEW_GAME_STR); + data.hotkeys[i] = 'n'; + menu[i++] = menubufptr; + menubufptr += linew+1; + + /* Is there a game already loaded? */ + if (menu_current_saved_game) { + + /* It should be first in the list of saved games. */ + assert(menu_saved_games.next + == &menu_current_saved_game->list); + + data.hotkeys[i] = menu_hotkey(i); + + /* Put it as the next item in the menu. */ + sprintf_game_info(menubufptr, linew+1, + menu_current_saved_game, data.hotkeys[i]); + menu[i++] = menubufptr; + menubufptr += linew+1; + } + + /* Prepare to list the remaining saved games. */ + if (menu_current_saved_game) { + lptr = menu_current_saved_game->list.next; + } else { + lptr = menu_saved_games.next; + } + + /* The remaining saved games are in timestamp order on the list; add + * them to the menu in this order. */ + while (lptr != &menu_saved_games) { + saved_game_t *save = outcast(lptr, saved_game_t, list); + lptr = lptr->next; + menu[i] = menubufptr; + data.hotkeys[i] = menu_hotkey(i); + sprintf_game_info(menubufptr, linew+1, save, data.hotkeys[i]); + menubufptr += linew+1; + i++; + } + + foogodSetHintText(LOADSAVE_HINT); + foogodSetMode(FOOGOD_HINT); + + /* Setup the menu in the status window. */ + statusSetStringList(data.title, n, menu); + statusSetMode(StringList); + + /* Highlight the current saved game. */ + if (menu_current_saved_game) { + statusSetSelectedIndex(1); + } + + /* Show the initial screenshot. */ + menu_show_screenshot(menu_current_saved_game + ? menu_current_saved_game->screenshot + : 0); + +reselect: + kh.fx = menu_scroller; + kh.data = &data; + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + + if (data.abort) { + selected_game = 0; + goto done; + } + + /* Did the player select an existing saved game? */ + if (data.save) { + + /* Yes. Overwrite? */ + if (confirm_selection()) { + selected_game = data.save; + } else { + goto reselect; + } + } + + /* No. Did player abort? */ + else if (!data.abort) { + + /* No. Must be a new saved game. */ + struct list *lptr; + char *new_name = prompt_for_fname(); + if (!new_name) + goto reselect; + + /* Did player re-type an existing filename? */ + list_for_each(&menu_saved_games, lptr) { + saved_game_t *exist = outcast(lptr, saved_game_t, + list); + if (!strcmp(new_name, exist->fname)) { + + /* Yes. Confirm overwrite? */ + if (!confirm_selection()) { + /* No. Reselect. */ + free(new_name); + goto reselect; + } + + /* Ok, overwrite. Nothing new to add to the + * saved-game script. */ + break; + } + } + + /* Replace the "New Saved Game" menu line with what the player + typed. */ + strncpy(menubuf, new_name, linew); + + /* Add a new saved game struct to the list. */ + selected_game = saved_game_new(new_name); + list_add(&menu_saved_games, &selected_game->list); + + /* Re-write the saved games file to add the new + * save. */ + menu_rewrite_saves(); + + free(new_name); + } + + /* Save selected? */ + if (selected_game) { + + char *s_fname = saved_game_mk_screenshot_fname(selected_game); + SDL_Rect rect; + + /* Does it have an old screenshot? */ + if (selected_game->screenshot) { + /* Yes. Get rid of it. */ + SDL_FreeSurface(selected_game->screenshot); + selected_game->screenshot = 0; + } + + /* Restore map view so we can get a new screenshot. */ + mapClearImage(); + mapUpdate(0); + + /* Take a new screenshot. */ + rect.x = MAP_X; + rect.y = MAP_Y; + rect.w = MAP_W; + rect.h = MAP_H; + screenCapture(s_fname, &rect); + selected_game->screenshot = IMG_Load(s_fname); + menu_set_current_saved_game(selected_game); + free(s_fname); + } + + done: + /* Restore the original status mode before deleting the list. */ + statusSetMode(omode); + foogodSetMode(FOOGOD_DEFAULT); + foogodRepaint(); + mapClearImage(); + + free(menu); + free(menubuf); + free(data.hotkeys); + + if (selected_game) { + return strdup(selected_game->fname); + } + return 0; +} + +static bool menus_demo_tick_handler(struct TickHandler *th) +{ + static int in_tick = 0; /* hack: prevent recursive entry */ + if (Session && !in_tick) { + in_tick = 1; + Tick++; + sprite_advance_ticks(1); + if (Place) { + place_exec(Place); + } + in_tick = 0; + } + + if (Quit) { + demo_done = 1; + } + + /* See the comment over main_menu_handled. */ + return (bool)(main_menu_handled || demo_done); +} + +char * main_menu(void) +{ + static const char *START_NEW_GAME="S)tart New Game"; + static const char *JOURNEY_ONWARD="J)ourney Onward"; + static const char *LOAD_GAME="L)oad Game"; + static const char *CREDITS="C)redits"; + static const char *QUIT="Q)uit"; + static const char *TUTORIAL="T)utorial"; + static const char *SETTINGS = "S(e)ttings"; + static const char *DEMO = "Show (I)ntro"; + const char *menu[8]; + char hotkeys[8+1]; + int n_items = 0; + struct KeyHandler kh; + menu_scroll_data_t data; + char *selection = NULL; + struct QuitHandler qh; + static char *new_game_fname = + file_mkpath(cfg_get("include-dirname"), + cfg_get("new-game-filename")); + static char *tutorial_fname = + file_mkpath(cfg_get("include-dirname"), + cfg_get("tutorial-filename")); + char *load_fname = 0; + char *save_game_fname = cfg_get("save-game-filename"); + struct TickHandler th; + int show_demo_option = 0; + static int first_time = 1; + char *demo_fname = 0; + + /* If the player has a saved game, then he's already seen the + * demo. Don't make him wait to load it before he can continue his + * game. */ + int run_demo = ! file_exists_in_save_dir(save_game_fname); + + /* setup main menu quit handler so player can click close window to + * exit */ + qh.fx = main_menu_quit_handler; + eventPushQuitHandler(&qh); + + /* Does the config file mention a demo? */ + if (cfg_get("demo-filename")) { + demo_fname = file_mkpath(cfg_get("include-dirname"), + cfg_get("demo-filename")); + + /* Can we find it? */ + if (file_exists(demo_fname)) { + + /* Have we already run the demo once? */ + if (! run_demo || ! first_time) { + + /* Show the demo as a menu option but don't + * automatically start it. */ + show_demo_option = 1; + + } else { + /* Setup the demo to run in parallel with the + * main menu. */ + run_demo = 1; + session_load(demo_fname); + foogodSetMode(FOOGOD_DEFAULT); + Session->is_demo = 1; + session_run_hook(Session, + new_game_start_hook, "p", + Session->player); + th.fx = menus_demo_tick_handler; + eventPushTickHandler(&th); + Quit = false; + cfg_set("demo-has-run", "yes"); + } + } + } + + + start_main_menu: + n_items = 0; + cmdwin_clear(); + + if (! run_demo) { + nazghul_splash(); + } + + /* check for a previously saved game to Journey Onward */ + if (file_exists_in_save_dir(save_game_fname)) { + menu[n_items] = JOURNEY_ONWARD; + hotkeys[n_items] = 'j'; + n_items++; + if (CONFIG_LOAD_GAME_OPTION) { + menu[n_items] = LOAD_GAME; + hotkeys[n_items] = 'l'; + n_items++; + } + } + + /* check for the default script for Start New Game */ + if (file_exists(new_game_fname)) { + menu[n_items] = START_NEW_GAME; + hotkeys[n_items] = 's'; + n_items++; + } + + /* check for a tutorial script for Tutorial */ + if (file_exists(tutorial_fname)) { + menu[n_items] = TUTORIAL; + hotkeys[n_items] = 't'; + n_items++; + } + + /* check for demo */ + if (show_demo_option) { + menu[n_items] = DEMO; + hotkeys[n_items] = 'i'; + n_items++; + } + + menu[n_items] = SETTINGS; + hotkeys[n_items] = 'e'; + n_items++; + + menu[n_items] = CREDITS; + hotkeys[n_items] = 'c'; + n_items++; + + menu[n_items] = QUIT; + hotkeys[n_items] = 'q'; + n_items++; + + hotkeys[n_items] = 0; + + foogodSetHintText("\005\006=scroll ENT=select"); + foogodSetMode(FOOGOD_HINT); + statusSetStringList("Main Menu", n_items, menu); + statusSetMode(StringList); + + data.hotkeys = hotkeys; + data.entry = NULL; + kh.fx = main_menu_scroller; + kh.data = &data; + main_menu_handled = 0; + + /* If running a demo then start/resume it. */ + if (run_demo) { + tick_run(); + } + + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + + /* Did we come back because the demo is done? */ + if (demo_done) { + + /* Yep. Setup for plain old splash and show the demo as a menu + * option. */ + run_demo = 0; + show_demo_option = 1; + demo_done = 0; + Quit = false; + session_del(Session); /* wish me luck! */ + Session = 0; + tick_pause(); + eventPopTickHandler(); + } + + + /* Pause the demo while running the submenus. This is really only + * necessary for the load_game_menu(). */ + if (run_demo) { + tick_pause(); + } + + selection = data.entry; + if (! selection) { + goto start_main_menu; + } + + if (! strcmp(selection, START_NEW_GAME)) { + load_fname = new_game_fname; + assert(load_fname); + } + else if (! strcmp(selection, JOURNEY_ONWARD)) { + if (CONFIG_LOAD_GAME_OPTION) { + load_fname = journey_onward(); + } else { + load_fname = load_game_menu(); + } + if (! load_fname) + goto start_main_menu; + } + else if (CONFIG_LOAD_GAME_OPTION + && ! strcmp(selection, LOAD_GAME)) { + load_fname = load_game_menu(); + if (!load_fname) + goto start_main_menu; + } + else if (! strcmp(selection, SETTINGS)) { + options_menu(); + goto start_main_menu; + } + else if (! strcmp(selection, CREDITS)) { + show_credits(); + goto start_main_menu; + } + else if (! strcmp(selection, TUTORIAL)) { + load_fname = tutorial_fname; + } + else if (! strcmp(selection, QUIT)) { + exit(0); + } + else if (! strcmp(selection, DEMO)) { + /* FIXME: this means that once the demo is started, it won't + * appear as an option again until the user selects to leave + * the main menu and then comes back. Currently there is no way + * to tell when the demo is done, so we don't know when it's ok + * to put the option back in. */ + show_demo_option = 0; + run_demo = 1; + + session_load(demo_fname); + Session->is_demo = 1; + foogodSetMode(FOOGOD_DEFAULT); + session_run_hook(Session, new_game_start_hook, "p", Session->player); + th.fx = menus_demo_tick_handler; + eventPushTickHandler(&th); + Quit = false; + goto start_main_menu; + } + else { + fprintf(stderr, "Invalid selection: '%s'\n", selection); + exit(-1); + } + + /* turn off status while new session is loading */ + statusSetMode(DisableStatus); + foogodSetMode(FOOGOD_DEFAULT); + + /* pop main menu quit handler, new one will be pushed in play.c */ + eventPopQuitHandler(); + + /* Cleanup after the demo. */ + if (run_demo) { + tick_pause(); + eventPopTickHandler(); + } + + first_time = 0; + return load_fname; +} + +int menu_init(void) +{ + char *fname = cfg_get("save-game-filename"); + list_init(&menu_saved_games); + if (file_exists_in_save_dir(fname)) { + file_load_from_save_dir(fname); + } + return 0; +} + +/***************************************************************************** + * Options Menu + */ +#include "cmd.h" /* for yesnokey() */ +#include "sound.h" + +#define OPTION_MAXNAMESTRLEN 32 +#define OPTION_MAXVALSTRLEN 16 +#define OPTION_MAXMENUSTRLEN (OPTION_MAXNAMESTRLEN + OPTION_MAXVALSTRLEN + 4) + +enum { + OPTION_SCREEN_DIMS = 0, + OPTION_SOUND_ENABLE, + OPTION_MUSIC_VOLUME, + OPTION_KEYWORD_HIGHLIGHTING, + OPTION_NUMOPTIONS /* keep last */ +}; + +struct option { + const char *name; + const char *comment; + const char *key; + const char *val; + char *entry_val; + char *startup_val; + void (*handler)(struct option *); + void (*enable)(int val); + char restart : 1; + char changed : 1; + char restart_on_enable : 1; +}; + +static void option_screen_dims(struct option *opt); +static void option_yes_no(struct option *opt); +static void option_music(struct option *opt); + +#define DECL_OPTION(name,comment,key,handler) \ + { name, comment, key, 0, 0, 0, handler, NULL, 0, 0 } + +#define DECL_YESNO_OPTION(name,comment,key,handler,ctrl,roo) \ + { name, comment, key, 0, 0, 0, handler, ctrl, 0, 0, roo } + +static struct option options[OPTION_NUMOPTIONS] = { + DECL_OPTION("Screen Size", "Set the dimensions of the game screen.", + "screen-dims", option_screen_dims), + DECL_YESNO_OPTION("Sound", "Turn sound on or off.", + "sound-enabled", option_yes_no, sound_enable, 1), + DECL_OPTION("Music Volume", "Adjust volume of builtin music.", + "music-volume", option_music), + DECL_YESNO_OPTION("Keyword Highlighting", + "Highlight keywords in conversations with NPC's.", + "keyword-highlighting", option_yes_no, + conv_enable_keyword_highlighting, 0), +}; + +/* option_screen_dims -- let player select desired screen size from a list */ +static void option_screen_dims(struct option *opt) +{ +# define ADD_SCREEN_DIM(dim,mapw) (dim), + const char *menu[] = { +# include "screen_dims.h" + }; + struct KeyHandler kh; + struct ScrollerContext data; + + log_msg("Choose your screen size"); + cmdwin_clear(); + cmdwin_spush("Screen size"); + cmdwin_spush(""); + + + statusSetStringList("Music Volume", array_sz(menu), menu); + statusSetMode(StringList); + data.selection = NULL; + data.selector = String; + kh.fx = scroller; + kh.data = &data; + eventPushKeyHandler(&kh); + eventHandle(); + eventPopKeyHandler(); + + if (!data.selection) + { + return; + } + + opt->val = (char*)data.selection; + set_music_volume((char*)data.selection); + +} + +static int options_save(void) +{ + int i; + char *fname = cfg_get("options-script-filename"); + FILE *file = file_open_in_save_dir(fname, "w"); + if (!file) { + warn("Could not open '%s': %s\n", fname, strerror(errno)); + return -1; + } + + fprintf(file, + ";; %s -- This file contains user-specified options that override the\n" + ";; game defaults.\n" + "(kern-cfg-set \n\n", + fname); + + for (i = 0; i < OPTION_NUMOPTIONS; i++) { + fprintf(file, ";; %s\n \"%s\" \"%s\"\n\n", + options[i].comment, + options[i].key, + options[i].val); + } + + fprintf(file, ")\n"); + fclose(file); + + return 0; +} + +/* options_menu -- show the user-configurable options. Upon exit prompt to save + * the current settings to the options file. */ +void options_menu(void) +{ + int i; + int yesno; + int any_changed = 0; + int any_restart = 0; + char menu_strings[OPTION_NUMOPTIONS][OPTION_MAXMENUSTRLEN] = {}; + const char *menu[OPTION_NUMOPTIONS]; + struct KeyHandler kh; + struct ScrollerContext data; + + /* Get current values and build the menu list. */ + for (i = 0; i < OPTION_NUMOPTIONS; i++) { + + /* Make a copy of the original value on startup. */ + if (! options[i].startup_val) { + options[i].startup_val = strdup(cfg_get(options[i].key)); + } + + /* Make a copy of the values on entry. */ + options[i].entry_val = strdup(cfg_get(options[i].key)); + + /* Clear the flags on entry */ + options[i].changed = 0; + + /* Init the current val. */ + options[i].val = cfg_get(options[i].key); + + /* Build the menu entry. */ + snprintf(menu_strings[i], OPTION_MAXMENUSTRLEN, + "%s [%s] %s", + options[i].name, + options[i].val, + options[i].restart ? "(restart)" : "" + ); + + /* Add it to the menu list. */ + menu[i] = menu_strings[i]; + } + + /* Menu loop */ + for (;;) { + + /* Setup status browser (do this every time through the loop, + * as the handler functions might change things) */ + cmdwin_clear(); + cmdwin_spush("Settings"); + cmdwin_push("