mirror of
				https://github.com/simon987/Much-Assembly-Required.git
				synced 2025-10-31 08:16:52 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "master" and "v1.0a" have entirely different histories.
		
	
	
		
	
		
							
								
								
									
										5
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							| @ -1,5 +0,0 @@ | |||||||
| Server/src/main/resources/static/css/bootstrap4-neon-glow.min linguist-vendored |  | ||||||
| Server/src/main/resources/static/css/bootstrap-grid.min linguist-vendored |  | ||||||
| Server/src/main/resources/static/css/bootstrap-reboot.min linguist-vendored |  | ||||||
| Server/src/main/resources/static/js/* linguist-vendored |  | ||||||
| Server/src/main/resources/static/js/ace/* linguist-vendored |  | ||||||
							
								
								
									
										22
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -1,22 +0,0 @@ | |||||||
| 
 |  | ||||||
| plugins/Plugin NPC.jar |  | ||||||
| plugins/Plugin Misc HW.jar |  | ||||||
| plugins/Plant.jar |  | ||||||
| plugins/Cubot.jar |  | ||||||
| .idea/* |  | ||||||
| mar.log |  | ||||||
| mar.log.lck |  | ||||||
| *.iml |  | ||||||
| *.class |  | ||||||
| */target/* |  | ||||||
| plugins/*.jar |  | ||||||
| save.json |  | ||||||
| Server/Server.iml |  | ||||||
| target/* |  | ||||||
| Server/Server.iml |  | ||||||
| Server/src/main/java/META-INF/MANIFEST.MF |  | ||||||
| .settings |  | ||||||
| .project |  | ||||||
| .classpath |  | ||||||
| # VSCode Workspace |  | ||||||
| .vscode/ |  | ||||||
| @ -1,19 +0,0 @@ | |||||||
| ## General guide |  | ||||||
| 
 |  | ||||||
| [Collaboration guide](https://github.com/simon987/Much-Assembly-Required/wiki/Collaboration-Guide) |  | ||||||
| 
 |  | ||||||
| ## Before creating a pull request |  | ||||||
| 
 |  | ||||||
| Here small unordered list of guidelines to read before creating a pull request |  | ||||||
| - Use java <= 1.8 features |  | ||||||
| - Please follow [Google's Java style guide](https://google.github.io/styleguide/javaguide.html) |  | ||||||
| - Constants (e.g. the energy cost of an in-game action) should be loaded from config.properties |  | ||||||
| - The project is separated into multiple modules, the `Server` module and its plugins. Plugins should  |  | ||||||
| not depend on another plugin to compile or to run. |  | ||||||
| (e.g. NPC plugin shouldn't import `net.simon987.biomassplugin` ) |  | ||||||
| - Use `Logmanager.LOGGER` to log messages to the console. Use `.fine()` for debugging messages and `.info()` for  |  | ||||||
| info for more important messages  |  | ||||||
| that are not too frequently used. |  | ||||||
| - Do not submit a pull request for a new feature that has not been approved  |  | ||||||
| by [simon987](https://github.com/simon987) in an Issue beforehand |  | ||||||
| - Please state what tests have been performed in the pull request |  | ||||||
| @ -1,6 +0,0 @@ | |||||||
| FROM maven:3.5-jdk-8 |  | ||||||
| COPY /. /app/ |  | ||||||
| WORKDIR /app |  | ||||||
| RUN mvn package |  | ||||||
| WORKDIR /app/target |  | ||||||
| CMD ["java", "-jar", "/app/target/server-1.4a.jar"] |  | ||||||
							
								
								
									
										674
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										674
									
								
								LICENSE
									
									
									
									
									
								
							| @ -1,674 +0,0 @@ | |||||||
|                     GNU GENERAL PUBLIC LICENSE |  | ||||||
|                        Version 3, 29 June 2007 |  | ||||||
| 
 |  | ||||||
|  Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> |  | ||||||
|  Everyone is permitted to copy and distribute verbatim copies |  | ||||||
|  of this license document, but changing it is not allowed. |  | ||||||
| 
 |  | ||||||
|                             Preamble |  | ||||||
| 
 |  | ||||||
|   The GNU General Public License is a free, copyleft license for |  | ||||||
| software and other kinds of works. |  | ||||||
| 
 |  | ||||||
|   The licenses for most software and other practical works are designed |  | ||||||
| to take away your freedom to share and change the works.  By contrast, |  | ||||||
| the GNU General Public License is intended to guarantee your freedom to |  | ||||||
| share and change all versions of a program--to make sure it remains free |  | ||||||
| software for all its users.  We, the Free Software Foundation, use the |  | ||||||
| GNU General Public License for most of our software; it applies also to |  | ||||||
| any other work released this way by its authors.  You can apply it to |  | ||||||
| your programs, too. |  | ||||||
| 
 |  | ||||||
|   When we speak of free software, we are referring to freedom, not |  | ||||||
| price.  Our General Public Licenses are designed to make sure that you |  | ||||||
| have the freedom to distribute copies of free software (and charge for |  | ||||||
| them if you wish), that you receive source code or can get it if you |  | ||||||
| want it, that you can change the software or use pieces of it in new |  | ||||||
| free programs, and that you know you can do these things. |  | ||||||
| 
 |  | ||||||
|   To protect your rights, we need to prevent others from denying you |  | ||||||
| these rights or asking you to surrender the rights.  Therefore, you have |  | ||||||
| certain responsibilities if you distribute copies of the software, or if |  | ||||||
| you modify it: responsibilities to respect the freedom of others. |  | ||||||
| 
 |  | ||||||
|   For example, if you distribute copies of such a program, whether |  | ||||||
| gratis or for a fee, you must pass on to the recipients the same |  | ||||||
| freedoms that you received.  You must make sure that they, too, receive |  | ||||||
| or can get the source code.  And you must show them these terms so they |  | ||||||
| know their rights. |  | ||||||
| 
 |  | ||||||
|   Developers that use the GNU GPL protect your rights with two steps: |  | ||||||
| (1) assert copyright on the software, and (2) offer you this License |  | ||||||
| giving you legal permission to copy, distribute and/or modify it. |  | ||||||
| 
 |  | ||||||
|   For the developers' and authors' protection, the GPL clearly explains |  | ||||||
| that there is no warranty for this free software.  For both users' and |  | ||||||
| authors' sake, the GPL requires that modified versions be marked as |  | ||||||
| changed, so that their problems will not be attributed erroneously to |  | ||||||
| authors of previous versions. |  | ||||||
| 
 |  | ||||||
|   Some devices are designed to deny users access to install or run |  | ||||||
| modified versions of the software inside them, although the manufacturer |  | ||||||
| can do so.  This is fundamentally incompatible with the aim of |  | ||||||
| protecting users' freedom to change the software.  The systematic |  | ||||||
| pattern of such abuse occurs in the area of products for individuals to |  | ||||||
| use, which is precisely where it is most unacceptable.  Therefore, we |  | ||||||
| have designed this version of the GPL to prohibit the practice for those |  | ||||||
| products.  If such problems arise substantially in other domains, we |  | ||||||
| stand ready to extend this provision to those domains in future versions |  | ||||||
| of the GPL, as needed to protect the freedom of users. |  | ||||||
| 
 |  | ||||||
|   Finally, every program is threatened constantly by software patents. |  | ||||||
| States should not allow patents to restrict development and use of |  | ||||||
| software on general-purpose computers, but in those that do, we wish to |  | ||||||
| avoid the special danger that patents applied to a free program could |  | ||||||
| make it effectively proprietary.  To prevent this, the GPL assures that |  | ||||||
| patents cannot be used to render the program non-free. |  | ||||||
| 
 |  | ||||||
|   The precise terms and conditions for copying, distribution and |  | ||||||
| modification follow. |  | ||||||
| 
 |  | ||||||
|                        TERMS AND CONDITIONS |  | ||||||
| 
 |  | ||||||
|   0. Definitions. |  | ||||||
| 
 |  | ||||||
|   "This License" refers to version 3 of the GNU General Public License. |  | ||||||
| 
 |  | ||||||
|   "Copyright" also means copyright-like laws that apply to other kinds of |  | ||||||
| works, such as semiconductor masks. |  | ||||||
| 
 |  | ||||||
|   "The Program" refers to any copyrightable work licensed under this |  | ||||||
| License.  Each licensee is addressed as "you".  "Licensees" and |  | ||||||
| "recipients" may be individuals or organizations. |  | ||||||
| 
 |  | ||||||
|   To "modify" a work means to copy from or adapt all or part of the work |  | ||||||
| in a fashion requiring copyright permission, other than the making of an |  | ||||||
| exact copy.  The resulting work is called a "modified version" of the |  | ||||||
| earlier work or a work "based on" the earlier work. |  | ||||||
| 
 |  | ||||||
|   A "covered work" means either the unmodified Program or a work based |  | ||||||
| on the Program. |  | ||||||
| 
 |  | ||||||
|   To "propagate" a work means to do anything with it that, without |  | ||||||
| permission, would make you directly or secondarily liable for |  | ||||||
| infringement under applicable copyright law, except executing it on a |  | ||||||
| computer or modifying a private copy.  Propagation includes copying, |  | ||||||
| distribution (with or without modification), making available to the |  | ||||||
| public, and in some countries other activities as well. |  | ||||||
| 
 |  | ||||||
|   To "convey" a work means any kind of propagation that enables other |  | ||||||
| parties to make or receive copies.  Mere interaction with a user through |  | ||||||
| a computer network, with no transfer of a copy, is not conveying. |  | ||||||
| 
 |  | ||||||
|   An interactive user interface displays "Appropriate Legal Notices" |  | ||||||
| to the extent that it includes a convenient and prominently visible |  | ||||||
| feature that (1) displays an appropriate copyright notice, and (2) |  | ||||||
| tells the user that there is no warranty for the work (except to the |  | ||||||
| extent that warranties are provided), that licensees may convey the |  | ||||||
| work under this License, and how to view a copy of this License.  If |  | ||||||
| the interface presents a list of user commands or options, such as a |  | ||||||
| menu, a prominent item in the list meets this criterion. |  | ||||||
| 
 |  | ||||||
|   1. Source Code. |  | ||||||
| 
 |  | ||||||
|   The "source code" for a work means the preferred form of the work |  | ||||||
| for making modifications to it.  "Object code" means any non-source |  | ||||||
| form of a work. |  | ||||||
| 
 |  | ||||||
|   A "Standard Interface" means an interface that either is an official |  | ||||||
| standard defined by a recognized standards body, or, in the case of |  | ||||||
| interfaces specified for a particular programming language, one that |  | ||||||
| is widely used among developers working in that language. |  | ||||||
| 
 |  | ||||||
|   The "System Libraries" of an executable work include anything, other |  | ||||||
| than the work as a whole, that (a) is included in the normal form of |  | ||||||
| packaging a Major Component, but which is not part of that Major |  | ||||||
| Component, and (b) serves only to enable use of the work with that |  | ||||||
| Major Component, or to implement a Standard Interface for which an |  | ||||||
| implementation is available to the public in source code form.  A |  | ||||||
| "Major Component", in this context, means a major essential component |  | ||||||
| (kernel, window system, and so on) of the specific operating system |  | ||||||
| (if any) on which the executable work runs, or a compiler used to |  | ||||||
| produce the work, or an object code interpreter used to run it. |  | ||||||
| 
 |  | ||||||
|   The "Corresponding Source" for a work in object code form means all |  | ||||||
| the source code needed to generate, install, and (for an executable |  | ||||||
| work) run the object code and to modify the work, including scripts to |  | ||||||
| control those activities.  However, it does not include the work's |  | ||||||
| System Libraries, or general-purpose tools or generally available free |  | ||||||
| programs which are used unmodified in performing those activities but |  | ||||||
| which are not part of the work.  For example, Corresponding Source |  | ||||||
| includes interface definition files associated with source files for |  | ||||||
| the work, and the source code for shared libraries and dynamically |  | ||||||
| linked subprograms that the work is specifically designed to require, |  | ||||||
| such as by intimate data communication or control flow between those |  | ||||||
| subprograms and other parts of the work. |  | ||||||
| 
 |  | ||||||
|   The Corresponding Source need not include anything that users |  | ||||||
| can regenerate automatically from other parts of the Corresponding |  | ||||||
| Source. |  | ||||||
| 
 |  | ||||||
|   The Corresponding Source for a work in source code form is that |  | ||||||
| same work. |  | ||||||
| 
 |  | ||||||
|   2. Basic Permissions. |  | ||||||
| 
 |  | ||||||
|   All rights granted under this License are granted for the term of |  | ||||||
| copyright on the Program, and are irrevocable provided the stated |  | ||||||
| conditions are met.  This License explicitly affirms your unlimited |  | ||||||
| permission to run the unmodified Program.  The output from running a |  | ||||||
| covered work is covered by this License only if the output, given its |  | ||||||
| content, constitutes a covered work.  This License acknowledges your |  | ||||||
| rights of fair use or other equivalent, as provided by copyright law. |  | ||||||
| 
 |  | ||||||
|   You may make, run and propagate covered works that you do not |  | ||||||
| convey, without conditions so long as your license otherwise remains |  | ||||||
| in force.  You may convey covered works to others for the sole purpose |  | ||||||
| of having them make modifications exclusively for you, or provide you |  | ||||||
| with facilities for running those works, provided that you comply with |  | ||||||
| the terms of this License in conveying all material for which you do |  | ||||||
| not control copyright.  Those thus making or running the covered works |  | ||||||
| for you must do so exclusively on your behalf, under your direction |  | ||||||
| and control, on terms that prohibit them from making any copies of |  | ||||||
| your copyrighted material outside their relationship with you. |  | ||||||
| 
 |  | ||||||
|   Conveying under any other circumstances is permitted solely under |  | ||||||
| the conditions stated below.  Sublicensing is not allowed; section 10 |  | ||||||
| makes it unnecessary. |  | ||||||
| 
 |  | ||||||
|   3. Protecting Users' Legal Rights From Anti-Circumvention Law. |  | ||||||
| 
 |  | ||||||
|   No covered work shall be deemed part of an effective technological |  | ||||||
| measure under any applicable law fulfilling obligations under article |  | ||||||
| 11 of the WIPO copyright treaty adopted on 20 December 1996, or |  | ||||||
| similar laws prohibiting or restricting circumvention of such |  | ||||||
| measures. |  | ||||||
| 
 |  | ||||||
|   When you convey a covered work, you waive any legal power to forbid |  | ||||||
| circumvention of technological measures to the extent such circumvention |  | ||||||
| is effected by exercising rights under this License with respect to |  | ||||||
| the covered work, and you disclaim any intention to limit operation or |  | ||||||
| modification of the work as a means of enforcing, against the work's |  | ||||||
| users, your or third parties' legal rights to forbid circumvention of |  | ||||||
| technological measures. |  | ||||||
| 
 |  | ||||||
|   4. Conveying Verbatim Copies. |  | ||||||
| 
 |  | ||||||
|   You may convey verbatim copies of the Program's source code as you |  | ||||||
| receive it, in any medium, provided that you conspicuously and |  | ||||||
| appropriately publish on each copy an appropriate copyright notice; |  | ||||||
| keep intact all notices stating that this License and any |  | ||||||
| non-permissive terms added in accord with section 7 apply to the code; |  | ||||||
| keep intact all notices of the absence of any warranty; and give all |  | ||||||
| recipients a copy of this License along with the Program. |  | ||||||
| 
 |  | ||||||
|   You may charge any price or no price for each copy that you convey, |  | ||||||
| and you may offer support or warranty protection for a fee. |  | ||||||
| 
 |  | ||||||
|   5. Conveying Modified Source Versions. |  | ||||||
| 
 |  | ||||||
|   You may convey a work based on the Program, or the modifications to |  | ||||||
| produce it from the Program, in the form of source code under the |  | ||||||
| terms of section 4, provided that you also meet all of these conditions: |  | ||||||
| 
 |  | ||||||
|     a) The work must carry prominent notices stating that you modified |  | ||||||
|     it, and giving a relevant date. |  | ||||||
| 
 |  | ||||||
|     b) The work must carry prominent notices stating that it is |  | ||||||
|     released under this License and any conditions added under section |  | ||||||
|     7.  This requirement modifies the requirement in section 4 to |  | ||||||
|     "keep intact all notices". |  | ||||||
| 
 |  | ||||||
|     c) You must license the entire work, as a whole, under this |  | ||||||
|     License to anyone who comes into possession of a copy.  This |  | ||||||
|     License will therefore apply, along with any applicable section 7 |  | ||||||
|     additional terms, to the whole of the work, and all its parts, |  | ||||||
|     regardless of how they are packaged.  This License gives no |  | ||||||
|     permission to license the work in any other way, but it does not |  | ||||||
|     invalidate such permission if you have separately received it. |  | ||||||
| 
 |  | ||||||
|     d) If the work has interactive user interfaces, each must display |  | ||||||
|     Appropriate Legal Notices; however, if the Program has interactive |  | ||||||
|     interfaces that do not display Appropriate Legal Notices, your |  | ||||||
|     work need not make them do so. |  | ||||||
| 
 |  | ||||||
|   A compilation of a covered work with other separate and independent |  | ||||||
| works, which are not by their nature extensions of the covered work, |  | ||||||
| and which are not combined with it such as to form a larger program, |  | ||||||
| in or on a volume of a storage or distribution medium, is called an |  | ||||||
| "aggregate" if the compilation and its resulting copyright are not |  | ||||||
| used to limit the access or legal rights of the compilation's users |  | ||||||
| beyond what the individual works permit.  Inclusion of a covered work |  | ||||||
| in an aggregate does not cause this License to apply to the other |  | ||||||
| parts of the aggregate. |  | ||||||
| 
 |  | ||||||
|   6. Conveying Non-Source Forms. |  | ||||||
| 
 |  | ||||||
|   You may convey a covered work in object code form under the terms |  | ||||||
| of sections 4 and 5, provided that you also convey the |  | ||||||
| machine-readable Corresponding Source under the terms of this License, |  | ||||||
| in one of these ways: |  | ||||||
| 
 |  | ||||||
|     a) Convey the object code in, or embodied in, a physical product |  | ||||||
|     (including a physical distribution medium), accompanied by the |  | ||||||
|     Corresponding Source fixed on a durable physical medium |  | ||||||
|     customarily used for software interchange. |  | ||||||
| 
 |  | ||||||
|     b) Convey the object code in, or embodied in, a physical product |  | ||||||
|     (including a physical distribution medium), accompanied by a |  | ||||||
|     written offer, valid for at least three years and valid for as |  | ||||||
|     long as you offer spare parts or customer support for that product |  | ||||||
|     model, to give anyone who possesses the object code either (1) a |  | ||||||
|     copy of the Corresponding Source for all the software in the |  | ||||||
|     product that is covered by this License, on a durable physical |  | ||||||
|     medium customarily used for software interchange, for a price no |  | ||||||
|     more than your reasonable cost of physically performing this |  | ||||||
|     conveying of source, or (2) access to copy the |  | ||||||
|     Corresponding Source from a network server at no charge. |  | ||||||
| 
 |  | ||||||
|     c) Convey individual copies of the object code with a copy of the |  | ||||||
|     written offer to provide the Corresponding Source.  This |  | ||||||
|     alternative is allowed only occasionally and noncommercially, and |  | ||||||
|     only if you received the object code with such an offer, in accord |  | ||||||
|     with subsection 6b. |  | ||||||
| 
 |  | ||||||
|     d) Convey the object code by offering access from a designated |  | ||||||
|     place (gratis or for a charge), and offer equivalent access to the |  | ||||||
|     Corresponding Source in the same way through the same place at no |  | ||||||
|     further charge.  You need not require recipients to copy the |  | ||||||
|     Corresponding Source along with the object code.  If the place to |  | ||||||
|     copy the object code is a network server, the Corresponding Source |  | ||||||
|     may be on a different server (operated by you or a third party) |  | ||||||
|     that supports equivalent copying facilities, provided you maintain |  | ||||||
|     clear directions next to the object code saying where to find the |  | ||||||
|     Corresponding Source.  Regardless of what server hosts the |  | ||||||
|     Corresponding Source, you remain obligated to ensure that it is |  | ||||||
|     available for as long as needed to satisfy these requirements. |  | ||||||
| 
 |  | ||||||
|     e) Convey the object code using peer-to-peer transmission, provided |  | ||||||
|     you inform other peers where the object code and Corresponding |  | ||||||
|     Source of the work are being offered to the general public at no |  | ||||||
|     charge under subsection 6d. |  | ||||||
| 
 |  | ||||||
|   A separable portion of the object code, whose source code is excluded |  | ||||||
| from the Corresponding Source as a System Library, need not be |  | ||||||
| included in conveying the object code work. |  | ||||||
| 
 |  | ||||||
|   A "User Product" is either (1) a "consumer product", which means any |  | ||||||
| tangible personal property which is normally used for personal, family, |  | ||||||
| or household purposes, or (2) anything designed or sold for incorporation |  | ||||||
| into a dwelling.  In determining whether a product is a consumer product, |  | ||||||
| doubtful cases shall be resolved in favor of coverage.  For a particular |  | ||||||
| product received by a particular user, "normally used" refers to a |  | ||||||
| typical or common use of that class of product, regardless of the status |  | ||||||
| of the particular user or of the way in which the particular user |  | ||||||
| actually uses, or expects or is expected to use, the product.  A product |  | ||||||
| is a consumer product regardless of whether the product has substantial |  | ||||||
| commercial, industrial or non-consumer uses, unless such uses represent |  | ||||||
| the only significant mode of use of the product. |  | ||||||
| 
 |  | ||||||
|   "Installation Information" for a User Product means any methods, |  | ||||||
| procedures, authorization keys, or other information required to install |  | ||||||
| and execute modified versions of a covered work in that User Product from |  | ||||||
| a modified version of its Corresponding Source.  The information must |  | ||||||
| suffice to ensure that the continued functioning of the modified object |  | ||||||
| code is in no case prevented or interfered with solely because |  | ||||||
| modification has been made. |  | ||||||
| 
 |  | ||||||
|   If you convey an object code work under this section in, or with, or |  | ||||||
| specifically for use in, a User Product, and the conveying occurs as |  | ||||||
| part of a transaction in which the right of possession and use of the |  | ||||||
| User Product is transferred to the recipient in perpetuity or for a |  | ||||||
| fixed term (regardless of how the transaction is characterized), the |  | ||||||
| Corresponding Source conveyed under this section must be accompanied |  | ||||||
| by the Installation Information.  But this requirement does not apply |  | ||||||
| if neither you nor any third party retains the ability to install |  | ||||||
| modified object code on the User Product (for example, the work has |  | ||||||
| been installed in ROM). |  | ||||||
| 
 |  | ||||||
|   The requirement to provide Installation Information does not include a |  | ||||||
| requirement to continue to provide support service, warranty, or updates |  | ||||||
| for a work that has been modified or installed by the recipient, or for |  | ||||||
| the User Product in which it has been modified or installed.  Access to a |  | ||||||
| network may be denied when the modification itself materially and |  | ||||||
| adversely affects the operation of the network or violates the rules and |  | ||||||
| protocols for communication across the network. |  | ||||||
| 
 |  | ||||||
|   Corresponding Source conveyed, and Installation Information provided, |  | ||||||
| in accord with this section must be in a format that is publicly |  | ||||||
| documented (and with an implementation available to the public in |  | ||||||
| source code form), and must require no special password or key for |  | ||||||
| unpacking, reading or copying. |  | ||||||
| 
 |  | ||||||
|   7. Additional Terms. |  | ||||||
| 
 |  | ||||||
|   "Additional permissions" are terms that supplement the terms of this |  | ||||||
| License by making exceptions from one or more of its conditions. |  | ||||||
| Additional permissions that are applicable to the entire Program shall |  | ||||||
| be treated as though they were included in this License, to the extent |  | ||||||
| that they are valid under applicable law.  If additional permissions |  | ||||||
| apply only to part of the Program, that part may be used separately |  | ||||||
| under those permissions, but the entire Program remains governed by |  | ||||||
| this License without regard to the additional permissions. |  | ||||||
| 
 |  | ||||||
|   When you convey a copy of a covered work, you may at your option |  | ||||||
| remove any additional permissions from that copy, or from any part of |  | ||||||
| it.  (Additional permissions may be written to require their own |  | ||||||
| removal in certain cases when you modify the work.)  You may place |  | ||||||
| additional permissions on material, added by you to a covered work, |  | ||||||
| for which you have or can give appropriate copyright permission. |  | ||||||
| 
 |  | ||||||
|   Notwithstanding any other provision of this License, for material you |  | ||||||
| add to a covered work, you may (if authorized by the copyright holders of |  | ||||||
| that material) supplement the terms of this License with terms: |  | ||||||
| 
 |  | ||||||
|     a) Disclaiming warranty or limiting liability differently from the |  | ||||||
|     terms of sections 15 and 16 of this License; or |  | ||||||
| 
 |  | ||||||
|     b) Requiring preservation of specified reasonable legal notices or |  | ||||||
|     author attributions in that material or in the Appropriate Legal |  | ||||||
|     Notices displayed by works containing it; or |  | ||||||
| 
 |  | ||||||
|     c) Prohibiting misrepresentation of the origin of that material, or |  | ||||||
|     requiring that modified versions of such material be marked in |  | ||||||
|     reasonable ways as different from the original version; or |  | ||||||
| 
 |  | ||||||
|     d) Limiting the use for publicity purposes of names of licensors or |  | ||||||
|     authors of the material; or |  | ||||||
| 
 |  | ||||||
|     e) Declining to grant rights under trademark law for use of some |  | ||||||
|     trade names, trademarks, or service marks; or |  | ||||||
| 
 |  | ||||||
|     f) Requiring indemnification of licensors and authors of that |  | ||||||
|     material by anyone who conveys the material (or modified versions of |  | ||||||
|     it) with contractual assumptions of liability to the recipient, for |  | ||||||
|     any liability that these contractual assumptions directly impose on |  | ||||||
|     those licensors and authors. |  | ||||||
| 
 |  | ||||||
|   All other non-permissive additional terms are considered "further |  | ||||||
| restrictions" within the meaning of section 10.  If the Program as you |  | ||||||
| received it, or any part of it, contains a notice stating that it is |  | ||||||
| governed by this License along with a term that is a further |  | ||||||
| restriction, you may remove that term.  If a license document contains |  | ||||||
| a further restriction but permits relicensing or conveying under this |  | ||||||
| License, you may add to a covered work material governed by the terms |  | ||||||
| of that license document, provided that the further restriction does |  | ||||||
| not survive such relicensing or conveying. |  | ||||||
| 
 |  | ||||||
|   If you add terms to a covered work in accord with this section, you |  | ||||||
| must place, in the relevant source files, a statement of the |  | ||||||
| additional terms that apply to those files, or a notice indicating |  | ||||||
| where to find the applicable terms. |  | ||||||
| 
 |  | ||||||
|   Additional terms, permissive or non-permissive, may be stated in the |  | ||||||
| form of a separately written license, or stated as exceptions; |  | ||||||
| the above requirements apply either way. |  | ||||||
| 
 |  | ||||||
|   8. Termination. |  | ||||||
| 
 |  | ||||||
|   You may not propagate or modify a covered work except as expressly |  | ||||||
| provided under this License.  Any attempt otherwise to propagate or |  | ||||||
| modify it is void, and will automatically terminate your rights under |  | ||||||
| this License (including any patent licenses granted under the third |  | ||||||
| paragraph of section 11). |  | ||||||
| 
 |  | ||||||
|   However, if you cease all violation of this License, then your |  | ||||||
| license from a particular copyright holder is reinstated (a) |  | ||||||
| provisionally, unless and until the copyright holder explicitly and |  | ||||||
| finally terminates your license, and (b) permanently, if the copyright |  | ||||||
| holder fails to notify you of the violation by some reasonable means |  | ||||||
| prior to 60 days after the cessation. |  | ||||||
| 
 |  | ||||||
|   Moreover, your license from a particular copyright holder is |  | ||||||
| reinstated permanently if the copyright holder notifies you of the |  | ||||||
| violation by some reasonable means, this is the first time you have |  | ||||||
| received notice of violation of this License (for any work) from that |  | ||||||
| copyright holder, and you cure the violation prior to 30 days after |  | ||||||
| your receipt of the notice. |  | ||||||
| 
 |  | ||||||
|   Termination of your rights under this section does not terminate the |  | ||||||
| licenses of parties who have received copies or rights from you under |  | ||||||
| this License.  If your rights have been terminated and not permanently |  | ||||||
| reinstated, you do not qualify to receive new licenses for the same |  | ||||||
| material under section 10. |  | ||||||
| 
 |  | ||||||
|   9. Acceptance Not Required for Having Copies. |  | ||||||
| 
 |  | ||||||
|   You are not required to accept this License in order to receive or |  | ||||||
| run a copy of the Program.  Ancillary propagation of a covered work |  | ||||||
| occurring solely as a consequence of using peer-to-peer transmission |  | ||||||
| to receive a copy likewise does not require acceptance.  However, |  | ||||||
| nothing other than this License grants you permission to propagate or |  | ||||||
| modify any covered work.  These actions infringe copyright if you do |  | ||||||
| not accept this License.  Therefore, by modifying or propagating a |  | ||||||
| covered work, you indicate your acceptance of this License to do so. |  | ||||||
| 
 |  | ||||||
|   10. Automatic Licensing of Downstream Recipients. |  | ||||||
| 
 |  | ||||||
|   Each time you convey a covered work, the recipient automatically |  | ||||||
| receives a license from the original licensors, to run, modify and |  | ||||||
| propagate that work, subject to this License.  You are not responsible |  | ||||||
| for enforcing compliance by third parties with this License. |  | ||||||
| 
 |  | ||||||
|   An "entity transaction" is a transaction transferring control of an |  | ||||||
| organization, or substantially all assets of one, or subdividing an |  | ||||||
| organization, or merging organizations.  If propagation of a covered |  | ||||||
| work results from an entity transaction, each party to that |  | ||||||
| transaction who receives a copy of the work also receives whatever |  | ||||||
| licenses to the work the party's predecessor in interest had or could |  | ||||||
| give under the previous paragraph, plus a right to possession of the |  | ||||||
| Corresponding Source of the work from the predecessor in interest, if |  | ||||||
| the predecessor has it or can get it with reasonable efforts. |  | ||||||
| 
 |  | ||||||
|   You may not impose any further restrictions on the exercise of the |  | ||||||
| rights granted or affirmed under this License.  For example, you may |  | ||||||
| not impose a license fee, royalty, or other charge for exercise of |  | ||||||
| rights granted under this License, and you may not initiate litigation |  | ||||||
| (including a cross-claim or counterclaim in a lawsuit) alleging that |  | ||||||
| any patent claim is infringed by making, using, selling, offering for |  | ||||||
| sale, or importing the Program or any portion of it. |  | ||||||
| 
 |  | ||||||
|   11. Patents. |  | ||||||
| 
 |  | ||||||
|   A "contributor" is a copyright holder who authorizes use under this |  | ||||||
| License of the Program or a work on which the Program is based.  The |  | ||||||
| work thus licensed is called the contributor's "contributor version". |  | ||||||
| 
 |  | ||||||
|   A contributor's "essential patent claims" are all patent claims |  | ||||||
| owned or controlled by the contributor, whether already acquired or |  | ||||||
| hereafter acquired, that would be infringed by some manner, permitted |  | ||||||
| by this License, of making, using, or selling its contributor version, |  | ||||||
| but do not include claims that would be infringed only as a |  | ||||||
| consequence of further modification of the contributor version.  For |  | ||||||
| purposes of this definition, "control" includes the right to grant |  | ||||||
| patent sublicenses in a manner consistent with the requirements of |  | ||||||
| this License. |  | ||||||
| 
 |  | ||||||
|   Each contributor grants you a non-exclusive, worldwide, royalty-free |  | ||||||
| patent license under the contributor's essential patent claims, to |  | ||||||
| make, use, sell, offer for sale, import and otherwise run, modify and |  | ||||||
| propagate the contents of its contributor version. |  | ||||||
| 
 |  | ||||||
|   In the following three paragraphs, a "patent license" is any express |  | ||||||
| agreement or commitment, however denominated, not to enforce a patent |  | ||||||
| (such as an express permission to practice a patent or covenant not to |  | ||||||
| sue for patent infringement).  To "grant" such a patent license to a |  | ||||||
| party means to make such an agreement or commitment not to enforce a |  | ||||||
| patent against the party. |  | ||||||
| 
 |  | ||||||
|   If you convey a covered work, knowingly relying on a patent license, |  | ||||||
| and the Corresponding Source of the work is not available for anyone |  | ||||||
| to copy, free of charge and under the terms of this License, through a |  | ||||||
| publicly available network server or other readily accessible means, |  | ||||||
| then you must either (1) cause the Corresponding Source to be so |  | ||||||
| available, or (2) arrange to deprive yourself of the benefit of the |  | ||||||
| patent license for this particular work, or (3) arrange, in a manner |  | ||||||
| consistent with the requirements of this License, to extend the patent |  | ||||||
| license to downstream recipients.  "Knowingly relying" means you have |  | ||||||
| actual knowledge that, but for the patent license, your conveying the |  | ||||||
| covered work in a country, or your recipient's use of the covered work |  | ||||||
| in a country, would infringe one or more identifiable patents in that |  | ||||||
| country that you have reason to believe are valid. |  | ||||||
| 
 |  | ||||||
|   If, pursuant to or in connection with a single transaction or |  | ||||||
| arrangement, you convey, or propagate by procuring conveyance of, a |  | ||||||
| covered work, and grant a patent license to some of the parties |  | ||||||
| receiving the covered work authorizing them to use, propagate, modify |  | ||||||
| or convey a specific copy of the covered work, then the patent license |  | ||||||
| you grant is automatically extended to all recipients of the covered |  | ||||||
| work and works based on it. |  | ||||||
| 
 |  | ||||||
|   A patent license is "discriminatory" if it does not include within |  | ||||||
| the scope of its coverage, prohibits the exercise of, or is |  | ||||||
| conditioned on the non-exercise of one or more of the rights that are |  | ||||||
| specifically granted under this License.  You may not convey a covered |  | ||||||
| work if you are a party to an arrangement with a third party that is |  | ||||||
| in the business of distributing software, under which you make payment |  | ||||||
| to the third party based on the extent of your activity of conveying |  | ||||||
| the work, and under which the third party grants, to any of the |  | ||||||
| parties who would receive the covered work from you, a discriminatory |  | ||||||
| patent license (a) in connection with copies of the covered work |  | ||||||
| conveyed by you (or copies made from those copies), or (b) primarily |  | ||||||
| for and in connection with specific products or compilations that |  | ||||||
| contain the covered work, unless you entered into that arrangement, |  | ||||||
| or that patent license was granted, prior to 28 March 2007. |  | ||||||
| 
 |  | ||||||
|   Nothing in this License shall be construed as excluding or limiting |  | ||||||
| any implied license or other defenses to infringement that may |  | ||||||
| otherwise be available to you under applicable patent law. |  | ||||||
| 
 |  | ||||||
|   12. No Surrender of Others' Freedom. |  | ||||||
| 
 |  | ||||||
|   If conditions are imposed on you (whether by court order, agreement or |  | ||||||
| otherwise) that contradict the conditions of this License, they do not |  | ||||||
| excuse you from the conditions of this License.  If you cannot convey a |  | ||||||
| covered work so as to satisfy simultaneously your obligations under this |  | ||||||
| License and any other pertinent obligations, then as a consequence you may |  | ||||||
| not convey it at all.  For example, if you agree to terms that obligate you |  | ||||||
| to collect a royalty for further conveying from those to whom you convey |  | ||||||
| the Program, the only way you could satisfy both those terms and this |  | ||||||
| License would be to refrain entirely from conveying the Program. |  | ||||||
| 
 |  | ||||||
|   13. Use with the GNU Affero General Public License. |  | ||||||
| 
 |  | ||||||
|   Notwithstanding any other provision of this License, you have |  | ||||||
| permission to link or combine any covered work with a work licensed |  | ||||||
| under version 3 of the GNU Affero General Public License into a single |  | ||||||
| combined work, and to convey the resulting work.  The terms of this |  | ||||||
| License will continue to apply to the part which is the covered work, |  | ||||||
| but the special requirements of the GNU Affero General Public License, |  | ||||||
| section 13, concerning interaction through a network will apply to the |  | ||||||
| combination as such. |  | ||||||
| 
 |  | ||||||
|   14. Revised Versions of this License. |  | ||||||
| 
 |  | ||||||
|   The Free Software Foundation may publish revised and/or new versions of |  | ||||||
| the GNU General Public License from time to time.  Such new versions will |  | ||||||
| be similar in spirit to the present version, but may differ in detail to |  | ||||||
| address new problems or concerns. |  | ||||||
| 
 |  | ||||||
|   Each version is given a distinguishing version number.  If the |  | ||||||
| Program specifies that a certain numbered version of the GNU General |  | ||||||
| Public License "or any later version" applies to it, you have the |  | ||||||
| option of following the terms and conditions either of that numbered |  | ||||||
| version or of any later version published by the Free Software |  | ||||||
| Foundation.  If the Program does not specify a version number of the |  | ||||||
| GNU General Public License, you may choose any version ever published |  | ||||||
| by the Free Software Foundation. |  | ||||||
| 
 |  | ||||||
|   If the Program specifies that a proxy can decide which future |  | ||||||
| versions of the GNU General Public License can be used, that proxy's |  | ||||||
| public statement of acceptance of a version permanently authorizes you |  | ||||||
| to choose that version for the Program. |  | ||||||
| 
 |  | ||||||
|   Later license versions may give you additional or different |  | ||||||
| permissions.  However, no additional obligations are imposed on any |  | ||||||
| author or copyright holder as a result of your choosing to follow a |  | ||||||
| later version. |  | ||||||
| 
 |  | ||||||
|   15. Disclaimer of Warranty. |  | ||||||
| 
 |  | ||||||
|   THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY |  | ||||||
| APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT |  | ||||||
| HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY |  | ||||||
| OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, |  | ||||||
| THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |  | ||||||
| PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM |  | ||||||
| IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF |  | ||||||
| ALL NECESSARY SERVICING, REPAIR OR CORRECTION. |  | ||||||
| 
 |  | ||||||
|   16. Limitation of Liability. |  | ||||||
| 
 |  | ||||||
|   IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |  | ||||||
| WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS |  | ||||||
| THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY |  | ||||||
| GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE |  | ||||||
| USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF |  | ||||||
| DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD |  | ||||||
| PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), |  | ||||||
| EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF |  | ||||||
| SUCH DAMAGES. |  | ||||||
| 
 |  | ||||||
|   17. Interpretation of Sections 15 and 16. |  | ||||||
| 
 |  | ||||||
|   If the disclaimer of warranty and limitation of liability provided |  | ||||||
| above cannot be given local legal effect according to their terms, |  | ||||||
| reviewing courts shall apply local law that most closely approximates |  | ||||||
| an absolute waiver of all civil liability in connection with the |  | ||||||
| Program, unless a warranty or assumption of liability accompanies a |  | ||||||
| copy of the Program in return for a fee. |  | ||||||
| 
 |  | ||||||
|                      END OF TERMS AND CONDITIONS |  | ||||||
| 
 |  | ||||||
|             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. |  | ||||||
| 
 |  | ||||||
|     <one line to give the program's name and a brief idea of what it does.> |  | ||||||
|     Copyright (C) <year>  <name of author> |  | ||||||
| 
 |  | ||||||
|     This program is free software: you can redistribute it and/or modify |  | ||||||
|     it under the terms of the GNU General Public License as published by |  | ||||||
|     the Free Software Foundation, either version 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 <http://www.gnu.org/licenses/>. |  | ||||||
| 
 |  | ||||||
| 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: |  | ||||||
| 
 |  | ||||||
|     <program>  Copyright (C) <year>  <name of author> |  | ||||||
|     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 |  | ||||||
| <http://www.gnu.org/licenses/>. |  | ||||||
| 
 |  | ||||||
|   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 |  | ||||||
| <http://www.gnu.org/philosophy/why-not-lgpl.html>. |  | ||||||
| @ -1,59 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> |  | ||||||
|   <component name="FacetManager"> |  | ||||||
|     <facet type="Spring" name="Spring"> |  | ||||||
|       <configuration /> |  | ||||||
|     </facet> |  | ||||||
|   </component> |  | ||||||
|   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> |  | ||||||
|     <output url="file://$MODULE_DIR$/target/classes" /> |  | ||||||
|     <output-test url="file://$MODULE_DIR$/target/test-classes" /> |  | ||||||
|     <content url="file://$MODULE_DIR$"> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> |  | ||||||
|       <excludeFolder url="file://$MODULE_DIR$/target" /> |  | ||||||
|     </content> |  | ||||||
|     <orderEntry type="inheritedJdk" /> |  | ||||||
|     <orderEntry type="sourceFolder" forTests="false" /> |  | ||||||
|     <orderEntry type="module" module-name="Server" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.6" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-sync:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:bson:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-core:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.1.5.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.sparkjava:spark-core:2.8.0" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-server:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-webapp:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-servlet:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-security:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-server:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.sparkjava:spark-template-velocity:2.7.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.25" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: junit:junit:4.10" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" /> |  | ||||||
|   </component> |  | ||||||
| </module> |  | ||||||
| @ -1,34 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" |  | ||||||
|          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |  | ||||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |  | ||||||
|     <modelVersion>4.0.0</modelVersion> |  | ||||||
| 	 |  | ||||||
| 	<parent> |  | ||||||
| 		<groupId>net.simon987.server</groupId> |  | ||||||
| 		<artifactId>server_root</artifactId> |  | ||||||
|         <version>1.4a</version> |  | ||||||
|     </parent> |  | ||||||
| 	 |  | ||||||
|     <groupId>net.simon987.plugincubot</groupId> |  | ||||||
|     <artifactId>plugin-cubot</artifactId> |  | ||||||
|     <version>1.4a</version> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <dependencies> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>net.simon987.server</groupId> |  | ||||||
|             <artifactId>server</artifactId> |  | ||||||
|             <version>1.4a</version> |  | ||||||
|         </dependency> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>com.googlecode.json-simple</groupId> |  | ||||||
|             <artifactId>json-simple</artifactId> |  | ||||||
|             <version>1.1.1</version> |  | ||||||
|         </dependency> |  | ||||||
|     </dependencies> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| </project> |  | ||||||
| @ -1,605 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.cubotplugin.event.CubotWalkEvent; |  | ||||||
| import net.simon987.cubotplugin.event.DeathEvent; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.IServerConfiguration; |  | ||||||
| import net.simon987.server.assembly.CPU; |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Memory; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.assembly.exception.CancelledException; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.game.item.Item; |  | ||||||
| import net.simon987.server.game.item.ItemVoid; |  | ||||||
| import net.simon987.server.game.objects.*; |  | ||||||
| import net.simon987.server.user.User; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.*; |  | ||||||
| 
 |  | ||||||
| public class Cubot extends GameObject implements Updatable, ControllableUnit, MessageReceiver { |  | ||||||
| 
 |  | ||||||
|     private static final char MAP_INFO = 0x0200; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hit points |  | ||||||
|      */ |  | ||||||
|     private int hp; |  | ||||||
|     /** |  | ||||||
|      * Maximum hit points |  | ||||||
|      */ |  | ||||||
|     private int maxHp; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Shield points |  | ||||||
|      */ |  | ||||||
|     private int shield; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum shield points |  | ||||||
|      */ |  | ||||||
|     private int maxShield; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Action that was set during the current tick. It is set to IDLE by default |  | ||||||
|      */ |  | ||||||
|     private Action currentAction = Action.IDLE; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Action at the end of the last tick |  | ||||||
|      */ |  | ||||||
|     private Action lastAction = Action.IDLE; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Status bit field that was set during the current tick. It is set to 0 by default |  | ||||||
|      * <br>See CubotStatus and addStatus() method |  | ||||||
|      */ |  | ||||||
|     private char currentStatus; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Status bit field at the end of the last tick |  | ||||||
|      */ |  | ||||||
|     private char lastStatus; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Buffer of keypress codes. It is not changed between ticks and it is reset when |  | ||||||
|      * the player uploads their code |  | ||||||
|      */ |  | ||||||
|     private ArrayList<Integer> keyboardBuffer = new ArrayList<>(); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Buffer of console messages (also called 'internal buffer') that was set during the current tick |  | ||||||
|      */ |  | ||||||
|     private ArrayList<char[]> consoleMessagesBuffer = new ArrayList<>(CONSOLE_BUFFER_MAX_SIZE); |  | ||||||
|     /** |  | ||||||
|      * Buffer of console messages (also called 'internal buffer') at the end of the last tick |  | ||||||
|      */ |  | ||||||
|     private ArrayList<char[]> lastConsoleMessagesBuffer = new ArrayList<>(CONSOLE_BUFFER_MAX_SIZE); |  | ||||||
|     /** |  | ||||||
|      * Console mode that was set during the current tick. It is set to NORMAL by default |  | ||||||
|      */ |  | ||||||
|     private ConsoleMode consoleMode = ConsoleMode.NORMAL; |  | ||||||
|     /** |  | ||||||
|      * Console mode at the end of the last tick |  | ||||||
|      */ |  | ||||||
|     private ConsoleMode lastConsoleMode = ConsoleMode.NORMAL; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * User that controls this Cubot |  | ||||||
|      */ |  | ||||||
|     private User parent; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum size of the console buffer (also called 'internal buffer') |  | ||||||
|      */ |  | ||||||
|     public static final int CONSOLE_BUFFER_MAX_SIZE = 40; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * List of attached hardware, 'modules' |  | ||||||
|      */ |  | ||||||
|     private Map<Integer, HardwareModule> hardwareAddresses = new HashMap<>(); |  | ||||||
|     private Map<Class<? extends HardwareModule>, Integer> hardwareModules = new HashMap<>(); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Cubot's brain box |  | ||||||
|      */ |  | ||||||
|     private CPU cpu; |  | ||||||
| 
 |  | ||||||
|     public enum ConsoleMode { |  | ||||||
|         /** |  | ||||||
|          * Used by the ComPort hardware - clears the console screen (client-side) |  | ||||||
|          */ |  | ||||||
|         CLEAR, |  | ||||||
|         /** |  | ||||||
|          * No specific client-side action |  | ||||||
|          */ |  | ||||||
|         NORMAL |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Cubot() { |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Cubot(Document document) { |  | ||||||
|         super(document); |  | ||||||
| 
 |  | ||||||
|         hp = document.getInteger("hp"); |  | ||||||
|         shield = document.getInteger("shield"); |  | ||||||
|         setDirection(Direction.getDirection(document.getInteger("direction"))); |  | ||||||
| 
 |  | ||||||
|         IServerConfiguration config = GameServer.INSTANCE.getConfig(); |  | ||||||
|         maxHp = config.getInt("cubot_max_hp"); |  | ||||||
|         maxShield = config.getInt("cubot_max_shield"); |  | ||||||
| 
 |  | ||||||
|         try { |  | ||||||
|             cpu = CPU.deserialize((Document) document.get("cpu"), this); |  | ||||||
| 
 |  | ||||||
|             ArrayList hardwareList = (ArrayList) document.get("hardware"); |  | ||||||
| 
 |  | ||||||
|             for (Object serialisedHw : hardwareList) { |  | ||||||
|                 HardwareModule hardware = GameServer.INSTANCE.getRegistry().deserializeHardware((Document) serialisedHw, this); |  | ||||||
|                 hardware.setCpu(cpu); |  | ||||||
|                 attachHardware(hardware, ((Document) serialisedHw).getInteger("address")); |  | ||||||
|             } |  | ||||||
|         } catch (CancelledException e) { |  | ||||||
|             e.printStackTrace(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getMapInfo() { |  | ||||||
|         return MAP_INFO; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
|         if (currentAction == Action.WALKING) { |  | ||||||
|             if (spendEnergy(100)) { |  | ||||||
|                 if (!incrementLocation()) { |  | ||||||
|                     //Couldn't walk |  | ||||||
|                     currentAction = Action.IDLE; |  | ||||||
|                 }else{ |  | ||||||
|                     GameServer.INSTANCE.getEventDispatcher().dispatch(new CubotWalkEvent(this)); |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 currentAction = Action.IDLE; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /* |  | ||||||
|          * CurrentAction is set during the code execution and this function is called right after |  | ||||||
|          * If no action as been set, the action sent to the client is the action in currentAction that |  | ||||||
|          * was set last tick (IDLE) |  | ||||||
|          */ |  | ||||||
|         lastAction = currentAction; |  | ||||||
|         currentAction = Action.IDLE; |  | ||||||
| 
 |  | ||||||
|         //Same principle for hologram |  | ||||||
| 
 |  | ||||||
|         //And the console |  | ||||||
|         lastConsoleMode = consoleMode; |  | ||||||
|         consoleMode = ConsoleMode.NORMAL; |  | ||||||
| 
 |  | ||||||
|         lastConsoleMessagesBuffer = new ArrayList<>(consoleMessagesBuffer); |  | ||||||
|         consoleMessagesBuffer.clear(); |  | ||||||
| 
 |  | ||||||
|         //And the status.. |  | ||||||
|         lastStatus = currentStatus; |  | ||||||
|         currentStatus = 0; |  | ||||||
| 
 |  | ||||||
|         for (HardwareModule module : hardwareAddresses.values()) { |  | ||||||
|             module.update(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject jsonSerialise() { |  | ||||||
|         JSONObject json = super.jsonSerialise(); |  | ||||||
|         json.put("direction", getDirection().ordinal()); |  | ||||||
|         CubotInventory inv = (CubotInventory) getHardware(CubotInventory.class); |  | ||||||
|         int heldItem = inv.getInventory().getOrDefault(inv.getPosition(), new ItemVoid()).getId(); |  | ||||||
|         json.put("heldItem", heldItem); |  | ||||||
|         json.put("hp", hp); |  | ||||||
|         json.put("shield", shield); |  | ||||||
|         json.put("action", lastAction.ordinal()); |  | ||||||
| 
 |  | ||||||
|         if (parent != null) { |  | ||||||
|             json.put("parent", parent.getUsername()); //Only used client-side for now |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         for (HardwareModule module : hardwareAddresses.values()) { |  | ||||||
|             JSONObject hwJson = module.jsonSerialise(); |  | ||||||
|             if (hwJson != null) { |  | ||||||
|                 json.put(module.getClass().getName(), hwJson); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("direction", getDirection().ordinal()); |  | ||||||
|         dbObject.put("hp", hp); |  | ||||||
|         dbObject.put("shield", shield); |  | ||||||
|         dbObject.put("action", lastAction.ordinal()); |  | ||||||
| 
 |  | ||||||
|         if (parent != null) { |  | ||||||
|             dbObject.put("parent", parent.getUsername()); //Only used client-side for now |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         List<Document> hardwareList = new ArrayList<>(); |  | ||||||
| 
 |  | ||||||
|         for (Integer address : hardwareAddresses.keySet()) { |  | ||||||
| 
 |  | ||||||
|             HardwareModule hardware = hardwareAddresses.get(address); |  | ||||||
| 
 |  | ||||||
|             Document serialisedHw = hardware.mongoSerialise(); |  | ||||||
|             serialisedHw.put("address", address); |  | ||||||
|             hardwareList.add(serialisedHw); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         dbObject.put("hardware", hardwareList); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("cpu", cpu.mongoSerialise()); |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Reset to 'factory settings', as it were when it was first created |  | ||||||
|      */ |  | ||||||
|     private void reset() { |  | ||||||
|         setDead(false); |  | ||||||
|         setHp(maxHp); |  | ||||||
|         setShield(0); |  | ||||||
|         setEnergy(((CubotBattery) getHardware(CubotBattery.class)).getMaxEnergy()); |  | ||||||
|         clearKeyboardBuffer(); |  | ||||||
|         consoleMessagesBuffer.clear(); |  | ||||||
|         lastConsoleMessagesBuffer.clear(); |  | ||||||
|         currentStatus = 0; |  | ||||||
|         lastStatus = 0; |  | ||||||
|         addStatus(CubotStatus.FACTORY_NEW); |  | ||||||
| 
 |  | ||||||
|         for (HardwareModule module : hardwareAddresses.values()) { |  | ||||||
|             module.reset(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean onDeadCallback() { |  | ||||||
|         GameEvent event = new DeathEvent(this); |  | ||||||
|         GameServer.INSTANCE.getEventDispatcher().dispatch(event); |  | ||||||
| 
 |  | ||||||
|         reset(); |  | ||||||
| 
 |  | ||||||
|         //Teleport to spawn point |  | ||||||
|         this.getWorld().removeObject(this); |  | ||||||
|         this.getWorld().decUpdatable(); |  | ||||||
| 
 |  | ||||||
|         IServerConfiguration config = GameServer.INSTANCE.getConfig(); |  | ||||||
|         Random random = new Random(); |  | ||||||
| 
 |  | ||||||
|         int spawnX = config.getInt("new_user_worldX") + random.nextInt(5); |  | ||||||
|         int spawnY = config.getInt("new_user_worldY") + random.nextInt(5); |  | ||||||
|         String dimension = config.getString("new_user_dimension"); |  | ||||||
|         this.setWorld(GameServer.INSTANCE.getGameUniverse().getWorld(spawnX, spawnY, true, dimension)); |  | ||||||
| 
 |  | ||||||
|         Point point = this.getWorld().getRandomPassableTile(); |  | ||||||
|         this.setX(point.x); |  | ||||||
|         this.setY(point.y); |  | ||||||
| 
 |  | ||||||
|         this.getWorld().addObject(this); |  | ||||||
|         this.getWorld().incUpdatable(); |  | ||||||
| 
 |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setKeyboardBuffer(ArrayList<Integer> kbBuffer) { |  | ||||||
|         keyboardBuffer = kbBuffer; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public ArrayList<Integer> getKeyboardBuffer() { |  | ||||||
|         return keyboardBuffer; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void clearKeyboardBuffer() { |  | ||||||
|         keyboardBuffer.clear(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setCurrentAction(Action currentAction) { |  | ||||||
|         this.currentAction = currentAction; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setParent(User parent) { |  | ||||||
|         this.parent = parent; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public User getParent() { |  | ||||||
|         return parent; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Action getAction() { |  | ||||||
|         return lastAction; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Action getCurrentAction() { |  | ||||||
|         return currentAction; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getEnergy() { |  | ||||||
|         CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class); |  | ||||||
|         return battery.getEnergy(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setEnergy(int energy) { |  | ||||||
|         CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class); |  | ||||||
|         battery.setEnergy(energy); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public boolean spendEnergy(int amount) { |  | ||||||
| 
 |  | ||||||
|         CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class); |  | ||||||
| 
 |  | ||||||
|         if (battery.getEnergy() - amount < 0) { |  | ||||||
|             return false; |  | ||||||
|         } else { |  | ||||||
|             battery.setEnergy(battery.getEnergy() - amount); |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void storeEnergy(int amount) { |  | ||||||
| 
 |  | ||||||
|         CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class); |  | ||||||
|         battery.setEnergy(Math.min(battery.getEnergy() + amount, battery.getMaxEnergy())); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setMaxEnergy(int maxEnergy) { |  | ||||||
|         CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class); |  | ||||||
|         battery.setMaxEnergy(maxEnergy); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getMaxEnergy() { |  | ||||||
|         CubotBattery battery = (CubotBattery) getHardware(CubotBattery.class); |  | ||||||
|         return battery.getMaxEnergy(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getShield() { |  | ||||||
|         return shield; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setShield(int shield) { |  | ||||||
|         this.shield = shield; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public boolean chargeShield(int amount) { |  | ||||||
|         amount = Math.min(amount, maxShield - shield); |  | ||||||
| 
 |  | ||||||
|         int energySpent = amount * CubotShield.COST; |  | ||||||
|         if(spendEnergy(energySpent)) { |  | ||||||
|             shield += amount; |  | ||||||
|             return true; |  | ||||||
|         } else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Damages shield by amount. |  | ||||||
|      *  |  | ||||||
|      * Return damage that broke through the shield. |  | ||||||
|      */ |  | ||||||
|     public int damageShield(int amount) { |  | ||||||
|         int after = shield - amount; |  | ||||||
|         if(after < 0) { |  | ||||||
|             shield = 0; |  | ||||||
|             return -after; |  | ||||||
|         } |  | ||||||
|         shield = after; |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Memory getFloppyData() { |  | ||||||
| 
 |  | ||||||
|         CubotFloppyDrive drive = (CubotFloppyDrive) getHardware(CubotFloppyDrive.class); |  | ||||||
| 
 |  | ||||||
|         if (drive.getFloppy() != null) { |  | ||||||
|             return drive.getFloppy().getMemory(); |  | ||||||
|         } else { |  | ||||||
|             return null; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean isAt(int x, int y) { |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setAction(Action action) { |  | ||||||
|         currentAction = action; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean sendMessage(char[] message) { |  | ||||||
| 
 |  | ||||||
|         if (consoleMessagesBuffer.size() < CONSOLE_BUFFER_MAX_SIZE) { |  | ||||||
|             consoleMessagesBuffer.add(message); |  | ||||||
|             return true; |  | ||||||
|         } else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public ArrayList<char[]> getConsoleMessagesBuffer() { |  | ||||||
|         return lastConsoleMessagesBuffer; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     public int getConsoleMode() { |  | ||||||
|         return lastConsoleMode.ordinal(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setConsoleMode(ConsoleMode consoleMode) { |  | ||||||
|         this.consoleMode = consoleMode; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void addStatus(CubotStatus status) { |  | ||||||
| 
 |  | ||||||
|         currentStatus |= status.val; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void removeStatus(CubotStatus status) { |  | ||||||
| 
 |  | ||||||
|         currentStatus &= (~status.val); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public char getStatus() { |  | ||||||
|         return lastStatus; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Currently has no effect |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void setHealRate(int hp) { |  | ||||||
|         //no op |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getHp() { |  | ||||||
|         return hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setHp(int hp) { |  | ||||||
|         this.hp = hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getMaxHp() { |  | ||||||
|         return maxHp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setMaxHp(int hp) { |  | ||||||
|         this.maxHp = hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getMaxShield() { |  | ||||||
|         return maxShield; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setMaxShield(int maxShield) { |  | ||||||
|         this.maxShield = maxShield; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void heal(int amount) { |  | ||||||
|         hp += amount; |  | ||||||
| 
 |  | ||||||
|         //Can't heal above max |  | ||||||
|         if (hp > maxHp) { |  | ||||||
|             hp = maxHp; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void damage(int amount) { |  | ||||||
| 
 |  | ||||||
|         //Damage shield first |  | ||||||
|         int hullDamage = damageShield(amount); |  | ||||||
| 
 |  | ||||||
|         hp -= hullDamage; |  | ||||||
| 
 |  | ||||||
|         if (hp <= 0) { |  | ||||||
|             setDead(true); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void attachHardware(HardwareModule hardware, int address) { |  | ||||||
|         hardwareAddresses.put(address, hardware); |  | ||||||
|         hardwareModules.put(hardware.getClass(), address); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void detachHardware(int address) { |  | ||||||
|         hardwareAddresses.remove(address); |  | ||||||
| 
 |  | ||||||
|         Class<? extends HardwareModule> toRemove = null; |  | ||||||
|         for (Class<? extends HardwareModule> clazz : hardwareModules.keySet()) { |  | ||||||
|             if (hardwareModules.get(clazz) == address) { |  | ||||||
|                 toRemove = clazz; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         hardwareModules.remove(toRemove); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean hardwareInterrupt(int address, Status status) { |  | ||||||
|         HardwareModule hardware = hardwareAddresses.get(address); |  | ||||||
| 
 |  | ||||||
|         if (hardware != null) { |  | ||||||
|             hardware.handleInterrupt(status); |  | ||||||
|             return true; |  | ||||||
|         } else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int hardwareQuery(int address) { |  | ||||||
|         HardwareModule hardware = hardwareAddresses.get(address); |  | ||||||
| 
 |  | ||||||
|         if (hardware != null) { |  | ||||||
|             return hardware.getId(); |  | ||||||
|         } else { |  | ||||||
|             return 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public HardwareModule getHardware(Class<? extends HardwareModule> clazz) { |  | ||||||
|         return hardwareAddresses.get(hardwareModules.get(clazz)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public HardwareModule getHardware(int address) { |  | ||||||
|         return hardwareAddresses.get(address); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public CPU getCpu() { |  | ||||||
|         return cpu; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setCpu(CPU cpu) { |  | ||||||
|         this.cpu = cpu; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void giveItem(Item item) { |  | ||||||
|         //Overwrite item at current position |  | ||||||
|         ((CubotInventory) getHardware(CubotInventory.class)).putItem(item); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public String toString() { |  | ||||||
|         StringBuilder str = new StringBuilder(super.toString()); |  | ||||||
| 
 |  | ||||||
|         str.append("\nHardware: \n"); |  | ||||||
|         for (Integer i : hardwareAddresses.keySet()) { |  | ||||||
|             str.append(String.format("%04X", i)).append(":").append(hardwareAddresses.get(i)).append("\n"); |  | ||||||
|         } |  | ||||||
|         return str.toString(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,120 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| public class CubotBattery extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 0x000A; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     public static final char HWID = 0x000A; |  | ||||||
|     /** |  | ||||||
|      * Solar panel multiplier |  | ||||||
|      * <br>TODO: Set this constant in dimension |  | ||||||
|      */ |  | ||||||
|     private static final float SOLAR_PANEL_MULTIPLIER = 1; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Energy units in kJ |  | ||||||
|      */ |  | ||||||
|     private int energy; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum energy units in kJ |  | ||||||
|      */ |  | ||||||
|     private int maxEnergy; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     private static final int BATTERY_POLL = 1; |  | ||||||
|     private static final int BATTERY_GET_MAX_CAPACITY = 2; |  | ||||||
| 
 |  | ||||||
|     public CubotBattery(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
| 
 |  | ||||||
|         energy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy"); |  | ||||||
|         maxEnergy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotBattery(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
| 
 |  | ||||||
|         energy = document.getInteger("energy"); |  | ||||||
|         maxEnergy = document.getInteger("max_energy"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == BATTERY_POLL) { |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(energy); |  | ||||||
| 
 |  | ||||||
|         } else if (a == BATTERY_GET_MAX_CAPACITY) { |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(maxEnergy); |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject jsonSerialise() { |  | ||||||
|         JSONObject json = new JSONObject(); |  | ||||||
| 
 |  | ||||||
|         json.put("energy", energy); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject debugJsonSerialise() { |  | ||||||
|         JSONObject json = jsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         json.put("max_energy", maxEnergy); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document document = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         document.put("energy", energy); |  | ||||||
|         document.put("max_energy", maxEnergy); |  | ||||||
| 
 |  | ||||||
|         return document; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getEnergy() { |  | ||||||
|         return energy; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setEnergy(int energy) { |  | ||||||
|         this.energy = energy; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getMaxEnergy() { |  | ||||||
|         return maxEnergy; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setMaxEnergy(int maxEnergy) { |  | ||||||
|         this.maxEnergy = maxEnergy; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
|         energy = Math.min(maxEnergy, |  | ||||||
|                 energy + (int) (SOLAR_PANEL_MULTIPLIER * GameServer.INSTANCE.getDayNightCycle().getSunIntensity())); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,130 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import net.simon987.server.game.objects.MessageReceiver; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| 
 |  | ||||||
| public class CubotComPort extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     public static final char HWID = 0xD; |  | ||||||
|     public static final int DEFAULT_ADDRESS = 0xD; |  | ||||||
| 
 |  | ||||||
|     private static final int COMPORT_BUFFER_CLEAR = 0; |  | ||||||
|     private static final int COMPORT_POLL = 1; |  | ||||||
|     private static final int COMPORT_FRONT_PORT_OUT = 2; |  | ||||||
|     private static final int COMPORT_SELF_OUT = 3; |  | ||||||
|     private static final int COMPORT_CONSOLE_CLEAR = 4; |  | ||||||
| 
 |  | ||||||
|     public CubotComPort(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotComPort(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private static final int MESSAGE_LENGTH = 8; |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == COMPORT_BUFFER_CLEAR) { |  | ||||||
| 
 |  | ||||||
|             unit.getConsoleMessagesBuffer().clear(); |  | ||||||
|              |  | ||||||
|         } else if (a == COMPORT_CONSOLE_CLEAR) { |  | ||||||
| 
 |  | ||||||
|             if (unit instanceof Cubot) { |  | ||||||
|                 ((Cubot) unit).setConsoleMode(Cubot.ConsoleMode.CLEAR); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|         } else if (a == COMPORT_POLL) { |  | ||||||
| 
 |  | ||||||
|             if (unit.spendEnergy(4)) { |  | ||||||
| 
 |  | ||||||
|                 int x = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
| 
 |  | ||||||
|                 //Read all messages in the console buffer to memory at X |  | ||||||
| 
 |  | ||||||
|                 for (char[] message : unit.getConsoleMessagesBuffer()) { |  | ||||||
|                     if (x + MESSAGE_LENGTH >= getCpu().getMemory().getWords().length) { |  | ||||||
|                         //todo set interrupt ? |  | ||||||
|                         getCpu().getStatus().setErrorFlag(true); |  | ||||||
|                     } else { |  | ||||||
|                         System.arraycopy(message, 0, getCpu().getMemory().getWords(), x, MESSAGE_LENGTH); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 //Set B = number of messages |  | ||||||
|                 getCpu().getRegisterSet().getRegister("B").setValue(unit.getConsoleMessagesBuffer().size()); |  | ||||||
| 
 |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|         } else if (a == COMPORT_FRONT_PORT_OUT) { |  | ||||||
| 
 |  | ||||||
|             if (unit.spendEnergy(5)) { |  | ||||||
|                 //Get object directly in front of the Cubot |  | ||||||
|                 Point frontTile = unit.getFrontTile(); |  | ||||||
|                 //Todo will have to add getGameObjectsBlockingAt to enable Factory |  | ||||||
|                 ArrayList<GameObject> objects = unit.getWorld().getGameObjectsAt(frontTile.x, frontTile.y); |  | ||||||
| 
 |  | ||||||
|                 if (objects.size() > 0 && objects.get(0) instanceof MessageReceiver) { |  | ||||||
| 
 |  | ||||||
|                     int x = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
| 
 |  | ||||||
|                     if (x + MESSAGE_LENGTH >= getCpu().getMemory().getWords().length) { |  | ||||||
|                         //todo set interrupt ? |  | ||||||
|                         getCpu().getStatus().setErrorFlag(true); |  | ||||||
|                     } else { |  | ||||||
| 
 |  | ||||||
|                         //Get MESSAGE_LENGTH-word message pointed by X |  | ||||||
|                         char[] message = new char[MESSAGE_LENGTH]; |  | ||||||
|                         System.arraycopy(getCpu().getMemory().getWords(), x, message, 0, MESSAGE_LENGTH); |  | ||||||
| 
 |  | ||||||
|                         //Send it to the MessageReceiver object |  | ||||||
|                         getCpu().getRegisterSet().getRegister("B").setValue( |  | ||||||
|                                 ((MessageReceiver) objects.get(0)).sendMessage(message) ? 1 : 0); |  | ||||||
|                         return; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(0); //Failed |  | ||||||
| 
 |  | ||||||
|         } else if (a == COMPORT_SELF_OUT) { |  | ||||||
| 
 |  | ||||||
|             if (unit.spendEnergy(1)) { |  | ||||||
| 
 |  | ||||||
|                 int x = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
| 
 |  | ||||||
|                 //Write a single message to console buffer |  | ||||||
|                 if (x + MESSAGE_LENGTH >= getCpu().getMemory().getWords().length) { |  | ||||||
|                     //todo set interrupt ? |  | ||||||
|                     getCpu().getStatus().setErrorFlag(true); |  | ||||||
|                 } else { |  | ||||||
| 
 |  | ||||||
|                     //Get MESSAGE_LENGTH-word message pointed by X |  | ||||||
|                     char[] message = new char[MESSAGE_LENGTH]; |  | ||||||
|                     System.arraycopy(getCpu().getMemory().getWords(), x, message, 0, MESSAGE_LENGTH); |  | ||||||
|                     getCpu().getRegisterSet().getRegister("B").setValue(unit.sendMessage(message) ? 1 : 0); |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(0); //Failed |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,46 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| public class CubotCore extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 0x000E; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     public static final char HWID = 0x000E; |  | ||||||
| 
 |  | ||||||
|     private static final int CORE_STATUS_POLL = 1; |  | ||||||
|     private static final int CORE_HULL_POLL = 2; |  | ||||||
| 
 |  | ||||||
|     public CubotCore(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotCore(Document document, ControllableUnit unit) { |  | ||||||
|         super(document, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == CORE_STATUS_POLL) { |  | ||||||
|             if (unit instanceof Cubot) { |  | ||||||
|                 getCpu().getRegisterSet().getRegister("B").setValue(((Cubot) unit).getStatus()); |  | ||||||
|             } |  | ||||||
|         } else if (a == CORE_HULL_POLL) { |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(unit.getHp()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,60 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.item.Item; |  | ||||||
| import net.simon987.server.game.objects.Action; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import net.simon987.server.game.world.Tile; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| public class CubotDrill extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     static final char HWID = 0x0005; |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 5; |  | ||||||
| 
 |  | ||||||
|     private static final int DRILL_POLL = 1; |  | ||||||
|     private static final int DRILL_GATHER = 2; // simplified gather |  | ||||||
| 
 |  | ||||||
|     public CubotDrill(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotDrill(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == DRILL_POLL) { |  | ||||||
| 
 |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(0); |  | ||||||
| 
 |  | ||||||
|         } else if (a == DRILL_GATHER) { |  | ||||||
| 
 |  | ||||||
|             if (unit.spendEnergy(1400)) { |  | ||||||
|                 if (unit.getCurrentAction() == Action.IDLE) { |  | ||||||
| 
 |  | ||||||
|                     Tile tile = unit.getWorld().getTileMap().getTileAt(unit.getX(), unit.getY()); |  | ||||||
| 
 |  | ||||||
|                     Item newItem = tile.drill(); |  | ||||||
|                     if (newItem != null) { |  | ||||||
|                         unit.setCurrentAction(Action.DIGGING); |  | ||||||
|                         unit.giveItem(newItem); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,92 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| public class CubotFloppyDrive extends CubotHardwareModule { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     static final char HWID = 0x000B; |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 0x000B; |  | ||||||
| 
 |  | ||||||
|     private static final int FLOPPY_POLL = 1; |  | ||||||
|     private static final int FLOPPY_READ_SECTOR = 2; |  | ||||||
|     private static final int FLOPPY_WRITE_SECTOR = 3; |  | ||||||
| 
 |  | ||||||
|     private FloppyDisk floppyDisk; |  | ||||||
| 
 |  | ||||||
|     public CubotFloppyDrive(Cubot cubot) { |  | ||||||
|         super(cubot); |  | ||||||
| 
 |  | ||||||
|         floppyDisk = new FloppyDisk(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotFloppyDrive(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
| 
 |  | ||||||
|         if (document.containsKey("floppy")) { |  | ||||||
|             floppyDisk = new FloppyDisk((Document) document.get("floppy")); |  | ||||||
|         } else { |  | ||||||
|             floppyDisk = new FloppyDisk(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == FLOPPY_POLL) { |  | ||||||
| 
 |  | ||||||
|             if (floppyDisk != null) { |  | ||||||
|                 getCpu().getRegisterSet().getRegister("B").setValue(0); |  | ||||||
|             } else { |  | ||||||
|                 getCpu().getRegisterSet().getRegister("B").setValue(1); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|         } else if (a == FLOPPY_READ_SECTOR) { |  | ||||||
| 
 |  | ||||||
|             if (floppyDisk == null) { |  | ||||||
|                 getCpu().getRegisterSet().getRegister("B").setValue(0); |  | ||||||
|             } else { |  | ||||||
|                 if (cubot.spendEnergy(1)) { |  | ||||||
|                     getCpu().getRegisterSet().getRegister("B").setValue(1); |  | ||||||
| 
 |  | ||||||
|                     int x = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
|                     int y = getCpu().getRegisterSet().getRegister("Y").getValue(); |  | ||||||
| 
 |  | ||||||
|                     floppyDisk.readSector(x, cubot.getCpu().getMemory(), y); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         } else if (a == FLOPPY_WRITE_SECTOR) { |  | ||||||
|             if (floppyDisk == null) { |  | ||||||
|                 getCpu().getRegisterSet().getRegister("B").setValue(0); |  | ||||||
|             } else { |  | ||||||
|                 if (cubot.spendEnergy(1)) { |  | ||||||
|                     getCpu().getRegisterSet().getRegister("B").setValue(1); |  | ||||||
| 
 |  | ||||||
|                     int x = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
|                     int y = getCpu().getRegisterSet().getRegister("Y").getValue(); |  | ||||||
| 
 |  | ||||||
|                     floppyDisk.writeSector(x, cubot.getCpu().getMemory(), y); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     public FloppyDisk getFloppy() { |  | ||||||
|         return floppyDisk; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,19 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| public abstract class CubotHardwareModule extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     protected Cubot cubot; |  | ||||||
| 
 |  | ||||||
|     public CubotHardwareModule(Document document, ControllableUnit cubot) { |  | ||||||
|         this.cubot = (Cubot) cubot; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotHardwareModule(Cubot cubot) { |  | ||||||
|         this.cubot = cubot; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,164 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| public class CubotHologram extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     static final char HWID = 0x0009; |  | ||||||
|     public static final int DEFAULT_ADDRESS = 9; |  | ||||||
| 
 |  | ||||||
|     private static final int HOLO_CLEAR = 0; |  | ||||||
|     private static final int HOLO_DISPLAY_HEX = 1; |  | ||||||
|     private static final int HOLO_DISPLAY_STRING = 2; |  | ||||||
|     private static final int HOLO_DISPLAY_DEC = 3; |  | ||||||
|     private static final int HOLO_DISPLAY_COLOR = 4; |  | ||||||
| 
 |  | ||||||
|     private static final int STR_MAX_LEN = 8; |  | ||||||
| 
 |  | ||||||
|     private int displayValue = 0; |  | ||||||
|     private String displayString = ""; |  | ||||||
|     private HologramMode mode = HologramMode.CLEARED; |  | ||||||
|     private HologramMode lastMode = HologramMode.CLEARED; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hologram color code. Format is handled by the client |  | ||||||
|      */ |  | ||||||
|     private int displayColor = 0; |  | ||||||
| 
 |  | ||||||
|     public CubotHologram(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotHologram(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
| 
 |  | ||||||
|         displayValue = document.getInteger("value"); |  | ||||||
|         displayColor = document.getInteger("color"); |  | ||||||
|         displayString = document.getString("string"); |  | ||||||
|         mode = HologramMode.values()[document.getInteger("mode")]; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         char a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == HOLO_CLEAR) { |  | ||||||
|             mode = HologramMode.CLEARED; |  | ||||||
|         } else if (a == HOLO_DISPLAY_HEX) { |  | ||||||
|             displayValue = getCpu().getRegisterSet().getRegister("B").getValue(); |  | ||||||
|             mode = HologramMode.HEX; |  | ||||||
|         } else if (a == HOLO_DISPLAY_STRING) { |  | ||||||
|             char x = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
|             //Display zero-terminated string starting at X (max 8 chars) |  | ||||||
| 
 |  | ||||||
|             StringBuilder holoString = new StringBuilder(); |  | ||||||
| 
 |  | ||||||
|             for (int i = 0; i < STR_MAX_LEN; i++) { |  | ||||||
| 
 |  | ||||||
|                 char nextChar = (char) getCpu().getMemory().get(x + i); |  | ||||||
| 
 |  | ||||||
|                 if (nextChar != 0) { |  | ||||||
|                     holoString.append((char) getCpu().getMemory().get(x + i)); |  | ||||||
|                 } else { |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             displayString = holoString.toString(); |  | ||||||
|             mode = HologramMode.STRING; |  | ||||||
|         } else if (a == HOLO_DISPLAY_DEC) { |  | ||||||
|             //Display decimal number |  | ||||||
|             displayValue = getCpu().getRegisterSet().getRegister("B").getValue(); |  | ||||||
|             mode = HologramMode.DEC; |  | ||||||
| 
 |  | ||||||
|         } else if (a == HOLO_DISPLAY_COLOR) { |  | ||||||
| 
 |  | ||||||
|             if (unit.spendEnergy(4)) { |  | ||||||
|                 int b = getCpu().getRegisterSet().getRegister("B").getValue(); |  | ||||||
|                 int c = getCpu().getRegisterSet().getRegister("C").getValue(); |  | ||||||
| 
 |  | ||||||
|                 displayColor = (c | (b << 16)); //B:C |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document document = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         document.put("color", displayColor); |  | ||||||
|         document.put("value", displayValue); |  | ||||||
|         document.put("string", displayString); |  | ||||||
|         document.put("mode", lastMode.ordinal()); |  | ||||||
| 
 |  | ||||||
|         return document; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject debugJsonSerialise() { |  | ||||||
|         JSONObject json = jsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         json.put("lastmode", mode); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject jsonSerialise() { |  | ||||||
|         JSONObject json = new JSONObject(); |  | ||||||
| 
 |  | ||||||
|         json.put("color", displayColor); |  | ||||||
|         json.put("value", displayValue); |  | ||||||
|         json.put("string", displayString); |  | ||||||
|         json.put("mode", lastMode.ordinal()); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private enum HologramMode { |  | ||||||
|         /** |  | ||||||
|          * Display nothing |  | ||||||
|          */ |  | ||||||
|         CLEARED, |  | ||||||
|         /** |  | ||||||
|          * Display value as hexadecimal in format 0x0000 |  | ||||||
|          */ |  | ||||||
|         HEX, |  | ||||||
|         /** |  | ||||||
|          * Display string |  | ||||||
|          */ |  | ||||||
|         STRING, |  | ||||||
|         /** |  | ||||||
|          * Display value as decimal |  | ||||||
|          */ |  | ||||||
|         DEC |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void reset() { |  | ||||||
|         displayValue = 0; |  | ||||||
|         displayColor = 0; |  | ||||||
|         displayString = ""; |  | ||||||
|         mode = HologramMode.CLEARED; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
|         lastMode = mode; |  | ||||||
|         mode = HologramMode.CLEARED; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,142 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.item.Item; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Map; |  | ||||||
| 
 |  | ||||||
| public class CubotInventory extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     static final char HWID = 0x0006; |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 6; |  | ||||||
| 
 |  | ||||||
|     private static final int INV_CLEAR = 0; |  | ||||||
|     private static final int INV_POLL = 1; |  | ||||||
|     private static final int INV_SEEK = 2; |  | ||||||
|     private static final int INV_SCAN = 3; |  | ||||||
| 
 |  | ||||||
|     private int inventorySize = 4; //TODO: load from config |  | ||||||
|     private Map<Integer, Item> inventory; |  | ||||||
|     private int position = 0; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     public CubotInventory(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
| 
 |  | ||||||
|         inventory = new HashMap<>(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotInventory(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
| 
 |  | ||||||
|         position = document.getInteger("position"); |  | ||||||
|         inventorySize = document.getInteger("size"); |  | ||||||
| 
 |  | ||||||
|         inventory = new HashMap<>(); |  | ||||||
|         for (String i : ((Map<String, Document>) document.get("inventory")).keySet()) { |  | ||||||
|             inventory.put(Integer.valueOf(i), |  | ||||||
|                     GameServer.INSTANCE.getRegistry().deserializeItem(((Map<String, Document>) document.get("inventory")).get(i))); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void putItem(Item item) { |  | ||||||
|         inventory.put(position, item); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private void scanItem() { |  | ||||||
|         int x = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
|         Item item = inventory.get(position); |  | ||||||
|         item.digitize(unit.getCpu().getMemory(), x); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Item clearItem() { |  | ||||||
|         Item item = inventory.get(position); |  | ||||||
|         item.clear(unit); |  | ||||||
|         inventory.remove(position); |  | ||||||
| 
 |  | ||||||
|         return item; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getPosition() { |  | ||||||
|         return position; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setPosition(int inventoryPosition) { |  | ||||||
|         this.position = inventoryPosition; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Map<Integer, Item> getInventory() { |  | ||||||
|         return inventory; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == INV_POLL) { |  | ||||||
|             Item item = inventory.get(position); |  | ||||||
|             char result; |  | ||||||
|             if (item == null) { |  | ||||||
|                 result = 0; |  | ||||||
|             } else { |  | ||||||
|                 result = item.poll(); |  | ||||||
|             } |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(result); |  | ||||||
| 
 |  | ||||||
|         } else if (a == INV_CLEAR) { |  | ||||||
|             if (unit.spendEnergy(100)) { |  | ||||||
|                 clearItem(); |  | ||||||
|             } |  | ||||||
|         } else if (a == INV_SEEK) { |  | ||||||
|             setPosition(getCpu().getRegisterSet().getRegister("X").getValue()); |  | ||||||
|         } else if (a == INV_SCAN) { |  | ||||||
|             if (unit.spendEnergy(200)) { |  | ||||||
|                 scanItem(); |  | ||||||
|                 clearItem(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document document = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         document.put("position", position); |  | ||||||
|         document.put("size", inventorySize); |  | ||||||
| 
 |  | ||||||
|         Document items = new Document(); |  | ||||||
| 
 |  | ||||||
|         for (Integer i : inventory.keySet()) { |  | ||||||
|             items.put(i.toString(), inventory.get(i).mongoSerialise()); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         document.put("inventory", items); |  | ||||||
| 
 |  | ||||||
|         return document; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public String toString() { |  | ||||||
|         String itemList = ""; |  | ||||||
|         for (Integer i : inventory.keySet()) { |  | ||||||
|             itemList += i + ": " + inventory.get(i).getClass().getSimpleName() + ", "; |  | ||||||
|         } |  | ||||||
|         return String.format("{CubotInventory[%d/%d] @ %d [%s]}", inventory.size(), inventorySize, position, itemList); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,54 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| public class CubotKeyboard extends CubotHardwareModule { |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 4; |  | ||||||
| 
 |  | ||||||
|     private static final int KEYBOARD_CLEAR_BUFFER = 0; |  | ||||||
|     private static final int KEYBOARD_FETCH_KEY = 1; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     public static final char HWID = 0x0004; |  | ||||||
| 
 |  | ||||||
|     public CubotKeyboard(Cubot cubot) { |  | ||||||
|         super(cubot); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotKeyboard(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == KEYBOARD_CLEAR_BUFFER) { |  | ||||||
| 
 |  | ||||||
|             cubot.clearKeyboardBuffer(); |  | ||||||
| 
 |  | ||||||
|         } else if (a == KEYBOARD_FETCH_KEY) { |  | ||||||
|             //pop |  | ||||||
|             int key = 0; |  | ||||||
|             if (cubot.getKeyboardBuffer().size() > 0) { |  | ||||||
|                 key = cubot.getKeyboardBuffer().get(0); |  | ||||||
|                 cubot.getKeyboardBuffer().remove(0); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(key); |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,92 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.*; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| 
 |  | ||||||
| public class CubotLaser extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     static final char HWID = 0x0002; |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 2; |  | ||||||
| 
 |  | ||||||
|     private static final int LASER_WITHDRAW = 1; |  | ||||||
|     private static final int LASER_DEPOSIT = 2; |  | ||||||
|     private static final int LASER_ATTACK = 3; |  | ||||||
| 
 |  | ||||||
|     private static final int LASER_DAMAGE = 25; |  | ||||||
| 
 |  | ||||||
|     public CubotLaser(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotLaser(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
|         int b = getCpu().getRegisterSet().getRegister("B").getValue(); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         if (a == LASER_WITHDRAW) { |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|             Point frontTile = unit.getFrontTile(); |  | ||||||
|             ArrayList<GameObject> objects = unit.getWorld().getGameObjectsBlockingAt(frontTile.x, frontTile.y); |  | ||||||
| 
 |  | ||||||
|             if (unit.getCurrentAction() == Action.IDLE && objects.size() > 0) { |  | ||||||
|                 //FIXME: Problem here if more than 1 object |  | ||||||
|                 if (objects.get(0) instanceof InventoryHolder) { |  | ||||||
| 
 |  | ||||||
|                     if (((InventoryHolder) objects.get(0)).canTakeItem(b)) { |  | ||||||
|                         if (unit.spendEnergy(30)) { |  | ||||||
|                             //Take the item |  | ||||||
|                             ((InventoryHolder) objects.get(0)).takeItem(b); |  | ||||||
|                             unit.giveItem(GameServer.INSTANCE.getRegistry().makeItem(b)); |  | ||||||
|                             unit.setCurrentAction(Action.WITHDRAWING); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         } else if (a == LASER_DEPOSIT) { |  | ||||||
|             // TODO |  | ||||||
|         } else if (a == LASER_ATTACK) { |  | ||||||
| 
 |  | ||||||
|             if (unit.getCurrentAction() == Action.IDLE) { |  | ||||||
|                 if (unit.spendEnergy(70)) { |  | ||||||
| 
 |  | ||||||
|                     //Get object directly in front of the Cubot |  | ||||||
|                     Point frontTile = unit.getFrontTile(); |  | ||||||
|                     ArrayList<GameObject> objects = unit.getWorld().getGameObjectsAt(frontTile.x, frontTile.y); |  | ||||||
| 
 |  | ||||||
|                     //todo: Add option in config to allow PvP |  | ||||||
|                     if (objects.size() > 0 && objects.get(0) instanceof Attackable && !(objects.get(0) instanceof Cubot)) { |  | ||||||
|                         ((Attackable) objects.get(0)).damage(LASER_DAMAGE); |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 unit.setCurrentAction(Action.ATTACKING); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,74 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.Action; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import net.simon987.server.game.objects.Direction; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| public class CubotLeg extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 1; |  | ||||||
| 
 |  | ||||||
|     private static final int LEGS_SET_DIR = 1; |  | ||||||
|     private static final int LEGS_SET_DIR_AND_WALK = 2; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     static final char HWID = 0x0001; |  | ||||||
| 
 |  | ||||||
|     public CubotLeg(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotLeg(Document document, ControllableUnit unit) { |  | ||||||
|         super(document, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         if (unit.getCurrentAction() == Action.IDLE) { |  | ||||||
|             int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
|             int b = getCpu().getRegisterSet().getRegister("B").getValue(); |  | ||||||
| 
 |  | ||||||
|             if (a == LEGS_SET_DIR) { |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|                 Direction dir = Direction.getDirection(b); |  | ||||||
| 
 |  | ||||||
|                 if (dir != null) { |  | ||||||
|                     if (unit.spendEnergy(20)) { |  | ||||||
|                         unit.setDirection(Direction.getDirection(b)); |  | ||||||
|                         status.setErrorFlag(false); |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     status.setErrorFlag(true); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|             } else if (a == LEGS_SET_DIR_AND_WALK) { |  | ||||||
| 
 |  | ||||||
|                 if (unit.getMaxEnergy() >= 100) { |  | ||||||
|                     Direction dir = Direction.getDirection(b); |  | ||||||
| 
 |  | ||||||
|                     if (dir != null) { |  | ||||||
|                         unit.setDirection(Direction.getDirection(b)); |  | ||||||
|                         status.setErrorFlag(false); |  | ||||||
|                     } else { |  | ||||||
|                         status.setErrorFlag(true); |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     unit.setCurrentAction(Action.WALKING); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,134 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Memory; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import net.simon987.server.game.pathfinding.Node; |  | ||||||
| import net.simon987.server.game.pathfinding.Pathfinder; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| 
 |  | ||||||
| public class CubotLidar extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     public static final char HWID = 0x0003; |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 3; |  | ||||||
| 
 |  | ||||||
|     private static final int LIDAR_GET_POS = 1; |  | ||||||
|     private static final int LIDAR_GET_PATH = 2; |  | ||||||
|     private static final int LIDAR_GET_MAP = 3; |  | ||||||
|     private static final int LIDAR_GET_WORLD_POS = 4; |  | ||||||
|     private static final int LIDAR_GET_WORLD_SIZE = 5; |  | ||||||
| 
 |  | ||||||
|     public CubotLidar(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotLidar(Document document, ControllableUnit unit) { |  | ||||||
|         super(document, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         switch (a) { |  | ||||||
|             case LIDAR_GET_POS: |  | ||||||
|                 getCpu().getRegisterSet().getRegister("X").setValue(unit.getX()); |  | ||||||
|                 getCpu().getRegisterSet().getRegister("Y").setValue(unit.getY()); |  | ||||||
|                 break; |  | ||||||
|             case LIDAR_GET_PATH: |  | ||||||
|                 if (unit.spendEnergy(50)) { |  | ||||||
|                     int c = getCpu().getRegisterSet().getRegister("C").getValue(); |  | ||||||
|                     int b = getCpu().getRegisterSet().getRegister("B").getValue(); |  | ||||||
|                     int destX = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
|                     int destY = getCpu().getRegisterSet().getRegister("Y").getValue(); |  | ||||||
| 
 |  | ||||||
|                     //Get path |  | ||||||
|                     ArrayList<Node> nodes = Pathfinder.findPath(unit.getWorld(), unit.getX(), unit.getY(), |  | ||||||
|                             destX, destY, b); |  | ||||||
| 
 |  | ||||||
|                     //Write to memory |  | ||||||
|                     Memory mem = getCpu().getMemory(); |  | ||||||
| 
 |  | ||||||
|                     int counter = c; |  | ||||||
| 
 |  | ||||||
|                     if (nodes != null) { |  | ||||||
| 
 |  | ||||||
|                         Node lastNode = null; |  | ||||||
| 
 |  | ||||||
|                         for (Node n : nodes) { |  | ||||||
|                             //Store the path as a sequence of directions |  | ||||||
|                             if (lastNode == null) { |  | ||||||
|                                 lastNode = n; |  | ||||||
|                                 continue; |  | ||||||
|                             } |  | ||||||
| 
 |  | ||||||
|                             if (n.x < lastNode.x) { |  | ||||||
|                                 //West |  | ||||||
|                                 mem.set(counter++, 3); |  | ||||||
|                             } else if (n.x > lastNode.x) { |  | ||||||
|                                 //East |  | ||||||
|                                 mem.set(counter++, 1); |  | ||||||
|                             } else if (n.y < lastNode.y) { |  | ||||||
|                                 //North |  | ||||||
|                                 mem.set(counter++, 0); |  | ||||||
|                             } else if (n.y > lastNode.y) { |  | ||||||
|                                 //South |  | ||||||
|                                 mem.set(counter++, 2); |  | ||||||
|                             } |  | ||||||
| 
 |  | ||||||
|                             lastNode = n; |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         //Indicate end of path with 0xAAAA |  | ||||||
|                         mem.set(counter, 0xAAAA); |  | ||||||
|                     } else { |  | ||||||
|                         //Indicate invalid path 0xFFFF |  | ||||||
|                         mem.set(counter, 0xFFFF); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             case LIDAR_GET_MAP: |  | ||||||
|                 if (unit.spendEnergy(10)) { |  | ||||||
|                     char[][] mapInfo = unit.getWorld().getMapInfo(); |  | ||||||
| 
 |  | ||||||
|                     //Write map data to the location specified by register X |  | ||||||
|                     int i = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
|                     for (int y = 0; y < unit.getWorld().getWorldSize(); y++) { |  | ||||||
|                         for (int x = 0; x < unit.getWorld().getWorldSize(); x++) { |  | ||||||
|                             getCpu().getMemory().set(i++, mapInfo[x][y]); |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             case LIDAR_GET_WORLD_SIZE: |  | ||||||
|                 getCpu().getRegisterSet().getRegister("X").setValue(unit.getWorld().getWorldSize()); |  | ||||||
|                 getCpu().getRegisterSet().getRegister("Y").setValue(unit.getWorld().getWorldSize()); |  | ||||||
|                 break; |  | ||||||
| 
 |  | ||||||
|             case LIDAR_GET_WORLD_POS: |  | ||||||
|                 getCpu().getRegisterSet().getRegister("X").setValue(unit.getWorld().getX()); |  | ||||||
|                 getCpu().getRegisterSet().getRegister("Y").setValue(unit.getWorld().getY()); |  | ||||||
|                 break; |  | ||||||
|                  |  | ||||||
|             default: |  | ||||||
|                 	break; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,44 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.cubotplugin.event.*; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.game.objects.GameRegistry; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import net.simon987.server.plugin.ServerPlugin; |  | ||||||
| 
 |  | ||||||
| public class CubotPlugin extends ServerPlugin { |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void init(GameServer gameServer) { |  | ||||||
|         listeners.add(new CpuInitialisationListener()); |  | ||||||
|         listeners.add(new UserCreationListener()); |  | ||||||
|         //Debug commands |  | ||||||
|         listeners.add(new ChargeShieldCommandListener()); |  | ||||||
|         listeners.add(new SetInventoryPosition()); |  | ||||||
|         listeners.add(new PutItemCommandListener()); |  | ||||||
|         listeners.add(new PopItemCommandListener()); |  | ||||||
|         //Leaderboard |  | ||||||
|         listeners.add(new DeathListener()); |  | ||||||
|         listeners.add(new WalkListener()); |  | ||||||
| 
 |  | ||||||
|         GameRegistry registry = gameServer.getRegistry(); |  | ||||||
| 
 |  | ||||||
|         registry.registerGameObject(Cubot.class); |  | ||||||
| 
 |  | ||||||
|         registry.registerHardware(CubotLeg.class); |  | ||||||
|         registry.registerHardware(CubotLaser.class); |  | ||||||
|         registry.registerHardware(CubotLidar.class); |  | ||||||
|         registry.registerHardware(CubotDrill.class); |  | ||||||
|         registry.registerHardware(CubotInventory.class); |  | ||||||
|         registry.registerHardware(CubotKeyboard.class); |  | ||||||
|         registry.registerHardware(CubotHologram.class); |  | ||||||
|         registry.registerHardware(CubotBattery.class); |  | ||||||
|         registry.registerHardware(CubotFloppyDrive.class); |  | ||||||
|         registry.registerHardware(CubotComPort.class); |  | ||||||
|         registry.registerHardware(CubotShield.class); |  | ||||||
|         registry.registerHardware(CubotCore.class); |  | ||||||
| 
 |  | ||||||
|         LogManager.LOGGER.info("(Cubot Plugin) Initialised Cubot plugin"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,44 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| public class CubotShield extends CubotHardwareModule { |  | ||||||
| 
 |  | ||||||
|     public static final char DEFAULT_ADDRESS = 0x000F; |  | ||||||
| 
 |  | ||||||
|     static final char HWID = 0x000F; |  | ||||||
| 
 |  | ||||||
|     private static final int SHIELD_CHARGE = 1; |  | ||||||
|     private static final int SHIELD_POLL = 2; |  | ||||||
| 
 |  | ||||||
|     public static final int COST = GameServer.INSTANCE.getConfig().getInt("shield_energy_cost"); |  | ||||||
| 
 |  | ||||||
|     public CubotShield(Cubot cubot) { |  | ||||||
|         super(cubot); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public CubotShield(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 	@Override |  | ||||||
| 	public void handleInterrupt(Status status) { |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
|         // b = amount to charge |  | ||||||
|         if(a == SHIELD_CHARGE) { |  | ||||||
|             int b = getCpu().getRegisterSet().getRegister("B").getValue(); |  | ||||||
|             cubot.chargeShield(b); |  | ||||||
|         } else if (a == SHIELD_POLL) { |  | ||||||
|             int shield = cubot.getShield(); |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(shield); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,19 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Status of a Cubot (Special buff or debuff) |  | ||||||
|  */ |  | ||||||
| public enum CubotStatus { |  | ||||||
| 
 |  | ||||||
|     DEFAULT(0), |  | ||||||
|     RADIATED(1), |  | ||||||
|     DAMAGED(2), |  | ||||||
|     FACTORY_NEW(3); |  | ||||||
| 
 |  | ||||||
|     public char val; |  | ||||||
| 
 |  | ||||||
|     CubotStatus(int val) { |  | ||||||
|         this.val = (char) val; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,103 +0,0 @@ | |||||||
| package net.simon987.cubotplugin; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.Memory; |  | ||||||
| import net.simon987.server.io.MongoSerializable; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Represents a floppy disk that is inside a floppy drive. |  | ||||||
|  * Floppies contains 80 tracks with 18 sectors per track. |  | ||||||
|  * That's 1440 sectors of 512 words. (total 1,474,560 bytes / 737,280 words / 1.44Mb) |  | ||||||
|  */ |  | ||||||
| public class FloppyDisk implements MongoSerializable { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Contents of the disk |  | ||||||
|      */ |  | ||||||
|     private Memory memory; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Current location of the read/write head. |  | ||||||
|      * Used to calculate seek time |  | ||||||
|      */ |  | ||||||
|     private int rwHeadTrack = 0; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     public FloppyDisk() { |  | ||||||
|         this.memory = new Memory(512 * 1440); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public FloppyDisk(Document document) { |  | ||||||
|         this.rwHeadTrack = document.getInteger("rwHeadTrack"); |  | ||||||
|         this.memory = new Memory((Document) document.get("memory")); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Read 512 words from the specified sector to cpu memory at specified address |  | ||||||
|      * |  | ||||||
|      * @param sector     sector to read (0-1440) |  | ||||||
|      * @param cpuMemory  Cpu memory to write to |  | ||||||
|      * @param ramAddress address of the data to write in CPU memory |  | ||||||
|      * @return Whether or not the read operation was in the same track as the last r/w |  | ||||||
|      */ |  | ||||||
|     public boolean readSector(int sector, Memory cpuMemory, int ramAddress) { |  | ||||||
| 
 |  | ||||||
|         if (sector <= 1440) { |  | ||||||
|             cpuMemory.write(ramAddress, memory.getWords(), sector * 512, 512); |  | ||||||
| 
 |  | ||||||
|             //Calculate seek time |  | ||||||
|             int deltaTrack = (sector / 80) - rwHeadTrack; |  | ||||||
| 
 |  | ||||||
|             if (deltaTrack != 0) { |  | ||||||
|                 rwHeadTrack = (sector / 80); |  | ||||||
|                 return false; |  | ||||||
|             } else { |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Write 512 words to the specified sector from cpu memory at the specified address |  | ||||||
|      * |  | ||||||
|      * @param sector     sector to write (0-1440) |  | ||||||
|      * @param cpuMemory  Cpu memory to read from |  | ||||||
|      * @param ramAddress address of the data to read in CPU memory |  | ||||||
|      * @return Whether or not the read operation was in the same track as the last r/w |  | ||||||
|      */ |  | ||||||
|     public boolean writeSector(int sector, Memory cpuMemory, int ramAddress) { |  | ||||||
| 
 |  | ||||||
|         if (sector <= 1440) { |  | ||||||
|             memory.write(sector * 512, cpuMemory.getWords(), ramAddress, 512); |  | ||||||
| 
 |  | ||||||
|             //Calculate seek time |  | ||||||
|             int deltaTrack = (sector / 80) - rwHeadTrack; |  | ||||||
| 
 |  | ||||||
|             if (deltaTrack != 0) { |  | ||||||
|                 rwHeadTrack = (sector / 80); |  | ||||||
|                 return false; |  | ||||||
|             } else { |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document dbObject = new Document(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("rwHeadTrack", rwHeadTrack); |  | ||||||
|         dbObject.put("memory", memory.mongoSerialise()); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Memory getMemory() { |  | ||||||
|         return memory; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,48 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.cubotplugin.Cubot; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.event.DebugCommandEvent; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Debug command to add shield points to a Cubot |  | ||||||
|  */ |  | ||||||
| public class ChargeShieldCommandListener implements GameEventListener { |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return DebugCommandEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         DebugCommandEvent e = (DebugCommandEvent) event; |  | ||||||
| 
 |  | ||||||
|         if (e.getName().equals("chargeShield")) { |  | ||||||
| 
 |  | ||||||
|             GameObject cubot = GameServer.INSTANCE.getGameUniverse().getObject(e.getObjectId("objectId")); |  | ||||||
| 
 |  | ||||||
|             if (cubot != null) { |  | ||||||
| 
 |  | ||||||
|                 if (cubot instanceof Cubot) { |  | ||||||
| 
 |  | ||||||
|                     String hp = ((Cubot) cubot).getHp() + "/" + ((Cubot) cubot).getMaxHp(); |  | ||||||
|                     int oldShield = ((Cubot) cubot).getShield(); |  | ||||||
|                     ((Cubot) cubot).chargeShield(e.getInt("amount")); |  | ||||||
| 
 |  | ||||||
|                     e.reply("Success: " + hp + " (" + oldShield + ") -> " + hp + "(" + ((Cubot) cubot).getShield() + |  | ||||||
|                             ")"); |  | ||||||
|                 } else { |  | ||||||
|                     e.reply("Object is not a Cubot"); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|             } else { |  | ||||||
|                 e.reply("Object not found: " + e.getLong("objectId")); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,61 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.cubotplugin.*; |  | ||||||
| import net.simon987.server.assembly.CPU; |  | ||||||
| import net.simon987.server.event.CpuInitialisationEvent; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| 
 |  | ||||||
| public class CpuInitialisationListener implements GameEventListener { |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return CpuInitialisationEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         CPU cpu = (CPU) event.getSource(); |  | ||||||
|         Cubot cubot = (Cubot) ((CpuInitialisationEvent) event).getUnit(); |  | ||||||
|         cpu.setHardwareHost(cubot); |  | ||||||
| 
 |  | ||||||
|         CubotLeg legHw = new CubotLeg(cubot); |  | ||||||
|         legHw.setCpu(cpu); |  | ||||||
|         CubotLaser laserHw = new CubotLaser(cubot); |  | ||||||
|         laserHw.setCpu(cpu); |  | ||||||
|         CubotLidar radarHw = new CubotLidar(cubot); |  | ||||||
|         radarHw.setCpu(cpu); |  | ||||||
|         CubotKeyboard keyboard = new CubotKeyboard(cubot); |  | ||||||
|         keyboard.setCpu(cpu); |  | ||||||
|         CubotDrill drillHw = new CubotDrill(cubot); |  | ||||||
|         drillHw.setCpu(cpu); |  | ||||||
|         CubotInventory invHw = new CubotInventory(cubot); |  | ||||||
|         invHw.setCpu(cpu); |  | ||||||
|         CubotHologram emoteHw = new CubotHologram(cubot); |  | ||||||
|         emoteHw.setCpu(cpu); |  | ||||||
|         CubotBattery batteryHw = new CubotBattery(cubot); |  | ||||||
|         batteryHw.setCpu(cpu); |  | ||||||
|         CubotFloppyDrive floppyHw = new CubotFloppyDrive(cubot); |  | ||||||
|         floppyHw.setCpu(cpu); |  | ||||||
|         CubotComPort comPortHw = new CubotComPort(cubot); |  | ||||||
|         comPortHw.setCpu(cpu); |  | ||||||
|         CubotCore coreHw = new CubotCore(cubot); |  | ||||||
|         coreHw.setCpu(cpu); |  | ||||||
|         CubotShield shieldHw = new CubotShield(cubot); |  | ||||||
|         shieldHw.setCpu(cpu); |  | ||||||
| 
 |  | ||||||
|         cubot.attachHardware(legHw, CubotLeg.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(laserHw, CubotLaser.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(radarHw, CubotLidar.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(keyboard, CubotKeyboard.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(drillHw, CubotDrill.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(invHw, CubotInventory.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(invHw, CubotInventory.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(emoteHw, CubotHologram.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(batteryHw, CubotBattery.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(floppyHw, CubotFloppyDrive.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(comPortHw, CubotComPort.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(coreHw, CubotCore.DEFAULT_ADDRESS); |  | ||||||
|         cubot.attachHardware(shieldHw, CubotShield.DEFAULT_ADDRESS); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,17 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.cubotplugin.Cubot; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| 
 |  | ||||||
| public class CubotWalkEvent extends GameEvent { |  | ||||||
| 
 |  | ||||||
|     public CubotWalkEvent(Cubot cubot) { |  | ||||||
|         setSource(cubot); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Cubot getSource() { |  | ||||||
|         return (Cubot) super.getSource(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,16 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| 
 |  | ||||||
| public class DeathEvent extends GameEvent { |  | ||||||
| 
 |  | ||||||
|     public DeathEvent(GameObject object) { |  | ||||||
|         setSource(object); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public GameObject getSource() { |  | ||||||
|         return (GameObject) super.getSource(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,23 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| 
 |  | ||||||
| public class DeathListener implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return DeathEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
|         DeathEvent DeathEvent = (DeathEvent) event; |  | ||||||
|         GameObject object = DeathEvent.getSource(); |  | ||||||
|         if (object instanceof ControllableUnit) { |  | ||||||
|             ((ControllableUnit) object).getParent().getStats().incrementStat("death", 1); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,43 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.cubotplugin.Cubot; |  | ||||||
| import net.simon987.cubotplugin.CubotInventory; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.event.DebugCommandEvent; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| 
 |  | ||||||
| public class PopItemCommandListener implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return DebugCommandEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         DebugCommandEvent e = (DebugCommandEvent) event; |  | ||||||
| 
 |  | ||||||
|         if (e.getName().equals("clearItem")) { |  | ||||||
| 
 |  | ||||||
|             GameObject object = GameServer.INSTANCE.getGameUniverse().getObject(e.getObjectId("objectId")); |  | ||||||
| 
 |  | ||||||
|             if (object != null) { |  | ||||||
| 
 |  | ||||||
|                 if (object instanceof Cubot) { |  | ||||||
| 
 |  | ||||||
|                     CubotInventory inventory = (CubotInventory) ((Cubot) object).getHardware(CubotInventory.class); |  | ||||||
| 
 |  | ||||||
|                     e.reply("Removed item from inventory: " + inventory.clearItem()); |  | ||||||
|                 } else { |  | ||||||
|                     e.reply("Object is not a Cubot"); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|             } else { |  | ||||||
|                 e.reply("Object not found: " + e.getLong("objectId")); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,53 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.cubotplugin.Cubot; |  | ||||||
| import net.simon987.cubotplugin.CubotInventory; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.event.DebugCommandEvent; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.game.item.Item; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| public class PutItemCommandListener implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return DebugCommandEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         DebugCommandEvent e = (DebugCommandEvent) event; |  | ||||||
| 
 |  | ||||||
|         if (e.getName().equals("putItem")) { |  | ||||||
| 
 |  | ||||||
|             GameObject object = GameServer.INSTANCE.getGameUniverse().getObject(e.getObjectId("objectId")); |  | ||||||
| 
 |  | ||||||
|             if (object != null) { |  | ||||||
| 
 |  | ||||||
|                 if (object instanceof Cubot) { |  | ||||||
| 
 |  | ||||||
|                     CubotInventory inventory = (CubotInventory) ((Cubot) object).getHardware(CubotInventory.class); |  | ||||||
|                     Item item = GameServer.INSTANCE.getRegistry().deserializeItem(Document.parse(e.getString("item"))); |  | ||||||
| 
 |  | ||||||
|                     if (item != null) { |  | ||||||
|                         inventory.putItem(item); |  | ||||||
|                         e.reply("Set item to " + item.getClass().getSimpleName()); |  | ||||||
| 
 |  | ||||||
|                     } else { |  | ||||||
|                         e.reply("Couldn't deserialize item"); |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                 } else { |  | ||||||
|                     e.reply("Object is not a Cubot"); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|             } else { |  | ||||||
|                 e.reply("Object not found: " + e.getLong("objectId")); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,45 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.cubotplugin.Cubot; |  | ||||||
| import net.simon987.cubotplugin.CubotInventory; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.event.DebugCommandEvent; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| 
 |  | ||||||
| public class SetInventoryPosition implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return DebugCommandEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         DebugCommandEvent e = (DebugCommandEvent) event; |  | ||||||
| 
 |  | ||||||
|         if (e.getName().equals("setInventoryPosition")) { |  | ||||||
| 
 |  | ||||||
|             GameObject object = GameServer.INSTANCE.getGameUniverse().getObject(e.getObjectId("objectId")); |  | ||||||
| 
 |  | ||||||
|             if (object != null) { |  | ||||||
| 
 |  | ||||||
|                 if (object instanceof Cubot) { |  | ||||||
| 
 |  | ||||||
|                     int position = e.getInt("position"); |  | ||||||
|                     CubotInventory inventory = (CubotInventory) ((Cubot) object).getHardware(CubotInventory.class); |  | ||||||
| 
 |  | ||||||
|                     inventory.setPosition(position); |  | ||||||
|                     e.reply("Set inventory position to " + position); |  | ||||||
|                 } else { |  | ||||||
|                     e.reply("Object is not a Cubot"); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|             } else { |  | ||||||
|                 e.reply("Object not found: " + e.getLong("objectId")); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,83 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.cubotplugin.Cubot; |  | ||||||
| import net.simon987.cubotplugin.CubotStatus; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.IServerConfiguration; |  | ||||||
| import net.simon987.server.assembly.Assembler; |  | ||||||
| import net.simon987.server.assembly.AssemblyResult; |  | ||||||
| import net.simon987.server.assembly.CPU; |  | ||||||
| import net.simon987.server.assembly.exception.CancelledException; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.event.UserCreationEvent; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import net.simon987.server.user.User; |  | ||||||
| import org.bson.types.ObjectId; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.Random; |  | ||||||
| 
 |  | ||||||
| public class UserCreationListener implements GameEventListener { |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return UserCreationEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         Random random = new Random(); |  | ||||||
| 
 |  | ||||||
|         User user = (User) event.getSource(); |  | ||||||
|         Cubot cubot = new Cubot(); |  | ||||||
|         cubot.addStatus(CubotStatus.FACTORY_NEW); |  | ||||||
|         cubot.setObjectId(new ObjectId()); |  | ||||||
|         IServerConfiguration config = GameServer.INSTANCE.getConfig(); |  | ||||||
| 
 |  | ||||||
|         Point point = null; |  | ||||||
|         while (point == null || cubot.getWorld() == null) { |  | ||||||
|             int spawnX = config.getInt("new_user_worldX") + random.nextInt(5); |  | ||||||
|             int spawnY = config.getInt("new_user_worldY") + random.nextInt(5); |  | ||||||
|             String dimension = config.getString("new_user_dimension"); |  | ||||||
|             cubot.setWorld(GameServer.INSTANCE.getGameUniverse().getWorld(spawnX, spawnY, true, dimension)); |  | ||||||
| 
 |  | ||||||
|             point = cubot.getWorld().getRandomPassableTile(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         cubot.setX(point.x); |  | ||||||
|         cubot.setY(point.y); |  | ||||||
|         cubot.getWorld().addObject(cubot); |  | ||||||
|         cubot.getWorld().incUpdatable(); |  | ||||||
| 
 |  | ||||||
|         cubot.setParent(user); |  | ||||||
|         user.setControlledUnit(cubot); |  | ||||||
| 
 |  | ||||||
|         //Create CPU |  | ||||||
|         try { |  | ||||||
|             cubot.setCpu(new CPU(GameServer.INSTANCE.getConfig(), cubot)); |  | ||||||
|             cubot.getCpu().setHardwareHost(cubot); |  | ||||||
|             user.setUserCode(config.getString("new_user_code")); |  | ||||||
| 
 |  | ||||||
|             //Compile user code |  | ||||||
|             AssemblyResult ar = new Assembler(cubot.getCpu().getInstructionSet(), cubot.getCpu().getRegisterSet(), |  | ||||||
|                     GameServer.INSTANCE.getConfig()).parse(user.getUserCode()); |  | ||||||
| 
 |  | ||||||
|             cubot.getCpu().getMemory().clear(); |  | ||||||
| 
 |  | ||||||
|             //Write assembled code to mem |  | ||||||
|             char[] assembledCode = ar.getWords(); |  | ||||||
| 
 |  | ||||||
|             cubot.getCpu().getMemory().write((char) ar.origin, assembledCode, 0, assembledCode.length); |  | ||||||
|             cubot.getCpu().setCodeSectionOffset(ar.getCodeSectionOffset()); |  | ||||||
|         } catch (CancelledException e) { |  | ||||||
|             e.printStackTrace(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         cubot.setHp(config.getInt("cubot_max_hp")); |  | ||||||
|         cubot.setMaxHp(config.getInt("cubot_max_hp")); |  | ||||||
|         cubot.setMaxShield(config.getInt("cubot_max_shield")); |  | ||||||
| 
 |  | ||||||
|         LogManager.LOGGER.fine("(Plugin) Handled User creation event (Cubot Plugin)"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,18 +0,0 @@ | |||||||
| package net.simon987.cubotplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| 
 |  | ||||||
| public class WalkListener implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return CubotWalkEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
|         CubotWalkEvent walkEvent = (CubotWalkEvent) event; |  | ||||||
|         walkEvent.getSource().getParent().getStats().incrementStat("walkDistance", 1); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
							
								
								
									
										131
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/Cubot.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/Cubot.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | |||||||
|  | package net.simon987.cubotplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.game.*; | ||||||
|  | import net.simon987.server.user.User; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | 
 | ||||||
|  | public class Cubot extends GameObject implements Updatable, ControllableUnit { | ||||||
|  | 
 | ||||||
|  |     private static final char MAP_INFO = 0x0080; | ||||||
|  |     public static final int ID = 1; | ||||||
|  | 
 | ||||||
|  |     private EffectType currentEmote = null; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Hit points | ||||||
|  |      */ | ||||||
|  |     private int hp; | ||||||
|  |     private int heldItem; | ||||||
|  | 
 | ||||||
|  |     private CubotAction currentAction = CubotAction.IDLE; | ||||||
|  |     private CubotAction lastAction = CubotAction.IDLE; | ||||||
|  | 
 | ||||||
|  |     private ArrayList<Integer> keyboardBuffer = new ArrayList<>(); | ||||||
|  | 
 | ||||||
|  |     private User parent; | ||||||
|  | 
 | ||||||
|  |     public Cubot() { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public char getMapInfo() { | ||||||
|  |         return MAP_INFO; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void update() { | ||||||
|  | 
 | ||||||
|  |         if (currentAction == CubotAction.WALKING) { | ||||||
|  |             if (!incrementLocation()) { | ||||||
|  |                 //Couldn't walk | ||||||
|  |                 currentAction = CubotAction.IDLE; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if (currentEmote != null) { | ||||||
|  |            // getWorld().getQueuedGameEffects().add(new GameEffect(currentEmote, getX(), getY())); | ||||||
|  |             currentEmote = null; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /* | ||||||
|  |          * CurrentAction is set during the code execution and this function is called right after | ||||||
|  |          * If no action as been set, the action sent to the client is the action in currentAction that | ||||||
|  |          * was set last tick (IDLE) | ||||||
|  |          */ | ||||||
|  |         lastAction = currentAction; | ||||||
|  |         currentAction = CubotAction.IDLE; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public JSONObject serialise() { | ||||||
|  |         JSONObject json = new JSONObject(); | ||||||
|  |         json.put("id", getObjectId()); | ||||||
|  |         json.put("type", ID); | ||||||
|  |         json.put("x", getX()); | ||||||
|  |         json.put("y", getY()); | ||||||
|  |         json.put("direction", getDirection().ordinal()); | ||||||
|  |         json.put("heldItem", heldItem); | ||||||
|  |         json.put("hp", hp); | ||||||
|  |         json.put("action", lastAction.ordinal()); | ||||||
|  |         if (parent != null) { | ||||||
|  |             json.put("parent", parent.getUsername()); //Only used client-side for now | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return json; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static Cubot deserialize(JSONObject json) { | ||||||
|  | 
 | ||||||
|  |         Cubot cubot = new Cubot(); | ||||||
|  |         cubot.setObjectId((int)(long)json.get("id")); | ||||||
|  |         cubot.setX((int)(long)json.get("x")); | ||||||
|  |         cubot.setY((int)(long)json.get("y")); | ||||||
|  |         cubot.hp = (int)(long)json.get("hp"); | ||||||
|  |         cubot.setDirection(Direction.getDirection((int)(long)json.get("direction"))); | ||||||
|  |         cubot.heldItem = (int)(long)json.get("heldItem"); | ||||||
|  | 
 | ||||||
|  |         return cubot; | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setHeldItem(int heldItem) { | ||||||
|  |         this.heldItem = heldItem; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public int getHeldItem() { | ||||||
|  |         return heldItem; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void setKeyboardBuffer(ArrayList<Integer> kbBuffer) { | ||||||
|  |         keyboardBuffer = kbBuffer; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public ArrayList<Integer> getKeyboardBuffer() { | ||||||
|  |         return keyboardBuffer; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void clearKeyboardBuffer(){ | ||||||
|  |         keyboardBuffer.clear(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setCurrentAction(CubotAction currentAction) { | ||||||
|  |         this.currentAction = currentAction; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public User getParent() { | ||||||
|  |         return parent; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setParent(User parent) { | ||||||
|  |         this.parent = parent; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public CubotAction getAction() { | ||||||
|  |         return lastAction; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotAction.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotAction.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,10 @@ | |||||||
|  | package net.simon987.cubotplugin; | ||||||
|  | 
 | ||||||
|  | public enum CubotAction { | ||||||
|  |     IDLE, | ||||||
|  |     DIGGING, | ||||||
|  |     WALKING, | ||||||
|  |     WITHDRAWING, | ||||||
|  |     DEPOSITING | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										75
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotDrill.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotDrill.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,75 @@ | |||||||
|  | package net.simon987.cubotplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.assembly.CpuHardware; | ||||||
|  | import net.simon987.server.assembly.Status; | ||||||
|  | import net.simon987.server.game.TileMap; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | public class CubotDrill extends CpuHardware { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Hardware ID (Should be unique) | ||||||
|  |      */ | ||||||
|  |     static final char HWID = 0x0005; | ||||||
|  | 
 | ||||||
|  |     public static final int DEFAULT_ADDRESS = 5; | ||||||
|  | 
 | ||||||
|  |     private static final int POLL = 1; | ||||||
|  |     private static final int GATHER_SLOW = 2; | ||||||
|  |     private static final int GATHER_FAST = 3; | ||||||
|  | 
 | ||||||
|  |     private Cubot cubot; | ||||||
|  | 
 | ||||||
|  |     public CubotDrill(Cubot cubot) { | ||||||
|  |         this.cubot = cubot; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public char getId() { | ||||||
|  |         return HWID; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void handleInterrupt(Status status) { | ||||||
|  |         int a = getCpu().getRegisterSet().getRegister("A").getValue(); | ||||||
|  | 
 | ||||||
|  |         if (a == POLL) { | ||||||
|  | 
 | ||||||
|  |             getCpu().getRegisterSet().getRegister("B").setValue(0); | ||||||
|  | 
 | ||||||
|  |         } else if (a == GATHER_SLOW || a == GATHER_FAST) { | ||||||
|  | 
 | ||||||
|  |             if (cubot.getAction() != CubotAction.IDLE) { | ||||||
|  |                 int tile = cubot.getWorld().getTileMap().getTileAt(cubot.getX(), cubot.getY()); | ||||||
|  | 
 | ||||||
|  |                 if (tile == TileMap.IRON_TILE) { | ||||||
|  |                     cubot.setHeldItem(TileMap.ITEM_IRON); | ||||||
|  |                     cubot.setCurrentAction(CubotAction.DIGGING); | ||||||
|  | 
 | ||||||
|  |                 } else if (tile == TileMap.COPPER_TILE) { | ||||||
|  |                     cubot.setHeldItem(TileMap.ITEM_COPPER); | ||||||
|  |                     cubot.setCurrentAction(CubotAction.DIGGING); | ||||||
|  | 
 | ||||||
|  |                 } else { | ||||||
|  |                     //System.out.println("FAILED: dig"); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public JSONObject serialise() { | ||||||
|  |         JSONObject json = new JSONObject(); | ||||||
|  |         json.put("hwid", (int) HWID); | ||||||
|  |         json.put("cubot", cubot.getObjectId()); | ||||||
|  | 
 | ||||||
|  |         return json; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static CubotDrill deserialize(JSONObject hwJSON){ | ||||||
|  |         return new CubotDrill((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((int)(long)hwJSON.get("cubot"))); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,59 @@ | |||||||
|  | package net.simon987.cubotplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.assembly.CpuHardware; | ||||||
|  | import net.simon987.server.assembly.Status; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | public class CubotInventory extends CpuHardware { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Hardware ID (Should be unique) | ||||||
|  |      */ | ||||||
|  |     static final char HWID = 0x0006; | ||||||
|  | 
 | ||||||
|  |     public static final int DEFAULT_ADDRESS = 6; | ||||||
|  | 
 | ||||||
|  |     private Cubot cubot; | ||||||
|  | 
 | ||||||
|  |     private static final int POLL = 1; | ||||||
|  |     private static final int CLEAR = 2; | ||||||
|  | 
 | ||||||
|  |     public CubotInventory(Cubot cubot) { | ||||||
|  |         this.cubot = cubot; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public char getId() { | ||||||
|  |         return HWID; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void handleInterrupt(Status status) { | ||||||
|  | 
 | ||||||
|  |         int a = getCpu().getRegisterSet().getRegister("A").getValue(); | ||||||
|  | 
 | ||||||
|  |         if(a == POLL) { | ||||||
|  | 
 | ||||||
|  |             getCpu().getRegisterSet().getRegister("B").setValue(cubot.getHeldItem()); | ||||||
|  | 
 | ||||||
|  |         } else if (a == CLEAR) { | ||||||
|  |             cubot.setHeldItem(0); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public JSONObject serialise() { | ||||||
|  | 
 | ||||||
|  |         JSONObject json = new JSONObject(); | ||||||
|  |         json.put("hwid", (int) HWID); | ||||||
|  |         json.put("cubot", cubot.getObjectId()); | ||||||
|  | 
 | ||||||
|  |         return json; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static CubotInventory deserialize(JSONObject hwJSON){ | ||||||
|  |         return new CubotInventory((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((int)(long)hwJSON.get("cubot"))); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										89
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotLaser.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotLaser.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | |||||||
|  | package net.simon987.cubotplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.assembly.CpuHardware; | ||||||
|  | import net.simon987.server.assembly.Status; | ||||||
|  | import net.simon987.server.game.GameObject; | ||||||
|  | import net.simon987.server.game.InventoryHolder; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | import java.awt.*; | ||||||
|  | import java.util.ArrayList; | ||||||
|  | 
 | ||||||
|  | public class CubotLaser extends CpuHardware { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Hardware ID (Should be unique) | ||||||
|  |      */ | ||||||
|  |     static final char HWID = 0x0002; | ||||||
|  | 
 | ||||||
|  |     public static final int DEFAULT_ADDRESS = 2; | ||||||
|  | 
 | ||||||
|  |     private Cubot cubot; | ||||||
|  | 
 | ||||||
|  |     private static final int WITHDRAW = 1; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     public CubotLaser(Cubot cubot) { | ||||||
|  |         this.cubot = cubot; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public char getId() { | ||||||
|  |         return HWID; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void handleInterrupt(Status status) { | ||||||
|  | 
 | ||||||
|  |         int a = getCpu().getRegisterSet().getRegister("A").getValue(); | ||||||
|  |         int b = getCpu().getRegisterSet().getRegister("B").getValue(); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         if(a == WITHDRAW) { | ||||||
|  | 
 | ||||||
|  |             //System.out.println("withdraw"); | ||||||
|  | 
 | ||||||
|  |             Point frontTile = cubot.getFrontTile(); | ||||||
|  |             ArrayList<GameObject> objects = cubot.getWorld().getGameObjectsAt(frontTile.x, frontTile.y); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |             if (cubot.getAction() != CubotAction.IDLE && objects.size() > 0) { | ||||||
|  | 
 | ||||||
|  |                 if (objects.get(0) instanceof InventoryHolder) { | ||||||
|  |                     //Take the item | ||||||
|  |                     if (((InventoryHolder) objects.get(0)).takeItem(b)) { | ||||||
|  | 
 | ||||||
|  |                         cubot.setHeldItem(b); | ||||||
|  |                         //System.out.println("took " + b); | ||||||
|  |                         cubot.setCurrentAction(CubotAction.WITHDRAWING); | ||||||
|  | 
 | ||||||
|  |                     } else { | ||||||
|  |                         //The inventory holder can't provide this item | ||||||
|  |                         //todo Add emote here | ||||||
|  |                         //  System.out.println("DEBUG: FAILED: take (The inventory holder can't provide this item)"); | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 //Nothing in front | ||||||
|  |                 //    System.out.println("DEBUG: FAILED: take (Nothing in front or Cubot is busy)"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public JSONObject serialise() { | ||||||
|  | 
 | ||||||
|  |         JSONObject json = new JSONObject(); | ||||||
|  |         json.put("hwid", (int) HWID); | ||||||
|  |         json.put("cubot", cubot.getObjectId()); | ||||||
|  | 
 | ||||||
|  |         return json; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static CubotLaser deserialize(JSONObject hwJSON){ | ||||||
|  |         return new CubotLaser((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((int)(long)hwJSON.get("cubot"))); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										82
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotLeg.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotLeg.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | |||||||
|  | package net.simon987.cubotplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.assembly.CpuHardware; | ||||||
|  | import net.simon987.server.assembly.Status; | ||||||
|  | import net.simon987.server.game.Direction; | ||||||
|  | import net.simon987.server.io.JSONSerialisable; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | public class CubotLeg extends CpuHardware implements JSONSerialisable { | ||||||
|  | 
 | ||||||
|  |     public static final int DEFAULT_ADDRESS = 1; | ||||||
|  | 
 | ||||||
|  |     public static final String NAME = "Cubot Leg"; | ||||||
|  | 
 | ||||||
|  |     private static final int SET_DIR = 1; | ||||||
|  |     private static final int SET_DIR_AND_WALK = 2; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Hardware ID (Should be unique) | ||||||
|  |      */ | ||||||
|  |     static final char HWID = 0x0001; | ||||||
|  | 
 | ||||||
|  |     private Cubot cubot; | ||||||
|  | 
 | ||||||
|  |     public CubotLeg(Cubot cubot) { | ||||||
|  |         this.cubot = cubot; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public char getId() { | ||||||
|  |         return HWID; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void handleInterrupt(Status status) { | ||||||
|  |         int a = getCpu().getRegisterSet().getRegister("A").getValue(); | ||||||
|  |         int b = getCpu().getRegisterSet().getRegister("B").getValue(); | ||||||
|  | 
 | ||||||
|  |         if(a == SET_DIR){ | ||||||
|  | 
 | ||||||
|  |             Direction dir = Direction.getDirection(b); | ||||||
|  | 
 | ||||||
|  |             if(dir != null){ | ||||||
|  |                 cubot.setDirection(Direction.getDirection(b)); | ||||||
|  |                 status.setErrorFlag(false); | ||||||
|  |             } else { | ||||||
|  |                 status.setErrorFlag(true); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |         } else if(a == SET_DIR_AND_WALK){ | ||||||
|  | 
 | ||||||
|  |             Direction dir = Direction.getDirection(b); | ||||||
|  | 
 | ||||||
|  |             if(dir != null){ | ||||||
|  |                 cubot.setDirection(Direction.getDirection(b)); | ||||||
|  |                 status.setErrorFlag(false); | ||||||
|  |             } else { | ||||||
|  |                 status.setErrorFlag(true); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             cubot.setCurrentAction(CubotAction.WALKING); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public JSONObject serialise() { | ||||||
|  | 
 | ||||||
|  |         JSONObject json = new JSONObject(); | ||||||
|  |         json.put("hwid", (int) HWID); | ||||||
|  |         json.put("cubot", cubot.getObjectId()); | ||||||
|  | 
 | ||||||
|  |         return json; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static CubotLeg deserialize(JSONObject hwJSON){ | ||||||
|  |         return new CubotLeg((Cubot)GameServer.INSTANCE.getGameUniverse().getObject((int)(long)hwJSON.get("cubot"))); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										141
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotLidar.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotLidar.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,141 @@ | |||||||
|  | package net.simon987.cubotplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.assembly.CpuHardware; | ||||||
|  | import net.simon987.server.assembly.Status; | ||||||
|  | import net.simon987.server.game.World; | ||||||
|  | import net.simon987.server.game.pathfinding.Node; | ||||||
|  | import net.simon987.server.game.pathfinding.Pathfinder; | ||||||
|  | import net.simon987.server.io.JSONSerialisable; | ||||||
|  | import net.simon987.server.logging.LogManager; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | import java.util.ArrayList; | ||||||
|  | 
 | ||||||
|  | public class CubotLidar extends CpuHardware implements JSONSerialisable { | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Hardware ID (Should be unique) | ||||||
|  |      */ | ||||||
|  |     public static final char HWID = 0x0003; | ||||||
|  | 
 | ||||||
|  |     public static final int DEFAULT_ADDRESS = 3; | ||||||
|  | 
 | ||||||
|  |     private Cubot cubot; | ||||||
|  | 
 | ||||||
|  |     private static final int GET_POS = 1; | ||||||
|  |     private static final int GET_PATH = 2; | ||||||
|  |     private static final int GET_MAP = 3; | ||||||
|  | 
 | ||||||
|  |     private static final int MEMORY_MAP_START = 0x0100; | ||||||
|  |     private static final int MEMORY_PATH_START = 0x0000; | ||||||
|  | 
 | ||||||
|  |     public CubotLidar(Cubot cubot) { | ||||||
|  |         this.cubot = cubot; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public char getId() { | ||||||
|  |         return HWID; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void handleInterrupt(Status status) { | ||||||
|  | 
 | ||||||
|  |         int a = getCpu().getRegisterSet().getRegister("A").getValue(); | ||||||
|  | 
 | ||||||
|  |         switch (a){ | ||||||
|  |             case GET_POS: | ||||||
|  |                 getCpu().getRegisterSet().getRegister("X").setValue(cubot.getX()); | ||||||
|  |                 getCpu().getRegisterSet().getRegister("Y").setValue(cubot.getY()); | ||||||
|  |                 break; | ||||||
|  |             case GET_PATH: | ||||||
|  |                 int b = getCpu().getRegisterSet().getRegister("B").getValue(); | ||||||
|  |                 int destX = getCpu().getRegisterSet().getRegister("X").getValue(); | ||||||
|  |                 int destY = getCpu().getRegisterSet().getRegister("Y").getValue(); | ||||||
|  | 
 | ||||||
|  |                 //Get path | ||||||
|  |                 ArrayList<Node> nodes = Pathfinder.findPath(cubot.getWorld(), cubot.getX(), cubot.getY(), | ||||||
|  |                         destX, destY, b); | ||||||
|  | 
 | ||||||
|  | //                System.out.println(nodes.size() + " nodes"); | ||||||
|  | 
 | ||||||
|  |                 //Write to memory | ||||||
|  |                 byte[] mem = getCpu().getMemory().getBytes(); | ||||||
|  | 
 | ||||||
|  |                 int counter = 0; //todo get memory address from config/constant | ||||||
|  | 
 | ||||||
|  |                 if (nodes != null) { | ||||||
|  | 
 | ||||||
|  |                     Node lastNode = null; | ||||||
|  | 
 | ||||||
|  |                     for (Node n : nodes) { | ||||||
|  |                         //Store the path as a sequence of directions | ||||||
|  | 
 | ||||||
|  |                         if (lastNode == null) { | ||||||
|  |                             lastNode = n; | ||||||
|  |                             continue; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         if (n.x < lastNode.x) { | ||||||
|  |                             //West | ||||||
|  |                             mem[counter++] = 0; | ||||||
|  |                             mem[counter++] = 3; | ||||||
|  |                         } else if (n.x > lastNode.x) { | ||||||
|  |                             //East | ||||||
|  |                             mem[counter++] = 0; | ||||||
|  |                             mem[counter++] = 1; | ||||||
|  |                         } else if (n.y < lastNode.y) { | ||||||
|  |                             //North | ||||||
|  |                             mem[counter++] = 0; | ||||||
|  |                             mem[counter++] = 0; | ||||||
|  |                         } else if (n.y > lastNode.y) { | ||||||
|  |                             //South | ||||||
|  |                             mem[counter++] = 0; | ||||||
|  |                             mem[counter++] = 2; | ||||||
|  |                         } | ||||||
|  | 
 | ||||||
|  |                         lastNode = n; | ||||||
|  |                     } | ||||||
|  | 
 | ||||||
|  |                     //Indicate end of path with 0xAAAA | ||||||
|  |                     mem[counter++] = -86; | ||||||
|  |                     mem[counter] = -86; | ||||||
|  |                 } else { | ||||||
|  |                     //Indicate invalid path 0xFFFF | ||||||
|  |                     mem[counter++] = -1; | ||||||
|  |                     mem[counter] = -1; | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 LogManager.LOGGER.fine("DEBUG: path to" + destX + "," + destY); | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             case GET_MAP: | ||||||
|  |                 char[][] mapInfo = cubot.getWorld().getMapInfo(); | ||||||
|  | 
 | ||||||
|  |                 int i = MEMORY_MAP_START; | ||||||
|  |                 for (int y = 0; y < World.WORLD_SIZE; y++) { | ||||||
|  |                     for (int x = 0; x < World.WORLD_SIZE; x++) { | ||||||
|  |                         getCpu().getMemory().set(i++, mapInfo[x][y]); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public JSONObject serialise() { | ||||||
|  | 
 | ||||||
|  |         JSONObject json = new JSONObject(); | ||||||
|  |         json.put("hwid", (int) HWID); | ||||||
|  |         json.put("cubot", cubot.getObjectId()); | ||||||
|  | 
 | ||||||
|  |         return json; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static CubotLidar deserialize(JSONObject hwJSON) { | ||||||
|  |         return new CubotLidar((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((int) (long) hwJSON.get("cubot"))); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										58
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotPlugin.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/CubotPlugin.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | |||||||
|  | package net.simon987.cubotplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.cubotplugin.event.CpuInitialisationListener; | ||||||
|  | import net.simon987.cubotplugin.event.UserCreationListener; | ||||||
|  | import net.simon987.server.assembly.CpuHardware; | ||||||
|  | import net.simon987.server.game.GameObject; | ||||||
|  | import net.simon987.server.io.CpuHardwareDeserializer; | ||||||
|  | import net.simon987.server.io.GameObjectDeserializer; | ||||||
|  | import net.simon987.server.logging.LogManager; | ||||||
|  | import net.simon987.server.plugin.ServerPlugin; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | public class CubotPlugin extends ServerPlugin implements GameObjectDeserializer, CpuHardwareDeserializer{ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void init() { | ||||||
|  |         listeners.add(new CpuInitialisationListener()); | ||||||
|  |         listeners.add(new UserCreationListener()); | ||||||
|  | 
 | ||||||
|  |         LogManager.LOGGER.info("Initialised Cubot plugin"); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public GameObject deserializeObject(JSONObject object) { | ||||||
|  | 
 | ||||||
|  |         int objType = (int)(long)object.get("type"); | ||||||
|  | 
 | ||||||
|  |         if(objType == Cubot.ID) { | ||||||
|  | 
 | ||||||
|  |             return Cubot.deserialize(object); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public CpuHardware deserializeHardware(JSONObject hwJson) { | ||||||
|  |         int hwid = (int)(long)hwJson.get("hwid"); | ||||||
|  | 
 | ||||||
|  |         switch (hwid){ | ||||||
|  |             case CubotLeg.HWID: | ||||||
|  |                 return CubotLeg.deserialize(hwJson); | ||||||
|  |             case CubotLaser.HWID: | ||||||
|  |                 return CubotLaser.deserialize(hwJson); | ||||||
|  |             case CubotLidar.HWID: | ||||||
|  |                 return CubotLidar.deserialize(hwJson); | ||||||
|  |             case CubotDrill.HWID: | ||||||
|  |                 return CubotDrill.deserialize(hwJson); | ||||||
|  |             case CubotInventory.HWID: | ||||||
|  |                 return CubotInventory.deserialize(hwJson); | ||||||
|  |             case Keyboard.HWID: | ||||||
|  |                 return Keyboard.deserialize(hwJson); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										70
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/Keyboard.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								Plugin Cubot/src/net/simon987/cubotplugin/Keyboard.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | |||||||
|  | package net.simon987.cubotplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.assembly.CpuHardware; | ||||||
|  | import net.simon987.server.assembly.Status; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | public class Keyboard extends CpuHardware { | ||||||
|  | 
 | ||||||
|  |     public static final int DEFAULT_ADDRESS = 4; | ||||||
|  | 
 | ||||||
|  |     public static final String NAME = "Wireless Keyboard"; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     private static final int CLEAR_BUFFER = 0; | ||||||
|  |     private static final int FETCH_KEY = 1; | ||||||
|  |      | ||||||
|  |     /** | ||||||
|  |      * Hardware ID (Should be unique) | ||||||
|  |      */ | ||||||
|  |     public static final char HWID = 0x0004; | ||||||
|  | 
 | ||||||
|  |     private Cubot cubot; | ||||||
|  | 
 | ||||||
|  |     public Keyboard(Cubot cubot) { | ||||||
|  |         this.cubot = cubot; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public char getId() { | ||||||
|  |         return HWID; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void handleInterrupt(Status status) { | ||||||
|  | 
 | ||||||
|  |         int a = getCpu().getRegisterSet().getRegister("A").getValue(); | ||||||
|  | 
 | ||||||
|  |         if(a == CLEAR_BUFFER){ | ||||||
|  | 
 | ||||||
|  |             cubot.clearKeyboardBuffer(); | ||||||
|  | 
 | ||||||
|  |         } else if (a == FETCH_KEY){ | ||||||
|  |             //pop | ||||||
|  |             int key = 0; | ||||||
|  |             if(cubot.getKeyboardBuffer().size() > 0){ | ||||||
|  |                 key = cubot.getKeyboardBuffer().get(0); | ||||||
|  |                 cubot.getKeyboardBuffer().remove(0); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             getCpu().getRegisterSet().getRegister("B").setValue(key); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public JSONObject serialise() { | ||||||
|  | 
 | ||||||
|  |         JSONObject json = new JSONObject(); | ||||||
|  |         json.put("hwid", (int) HWID); | ||||||
|  |         json.put("cubot", cubot.getObjectId()); | ||||||
|  | 
 | ||||||
|  |         return json; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static Keyboard deserialize(JSONObject hwJSON){ | ||||||
|  |         return new Keyboard((Cubot) GameServer.INSTANCE.getGameUniverse().getObject((int)(long)hwJSON.get("cubot"))); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,44 @@ | |||||||
|  | package net.simon987.cubotplugin.event; | ||||||
|  | 
 | ||||||
|  | import net.simon987.cubotplugin.*; | ||||||
|  | import net.simon987.server.assembly.CPU; | ||||||
|  | import net.simon987.server.event.CpuInitialisationEvent; | ||||||
|  | import net.simon987.server.event.GameEvent; | ||||||
|  | import net.simon987.server.event.GameEventListener; | ||||||
|  | import net.simon987.server.logging.LogManager; | ||||||
|  | import net.simon987.server.user.User; | ||||||
|  | 
 | ||||||
|  | public class CpuInitialisationListener implements GameEventListener { | ||||||
|  |     @Override | ||||||
|  |     public Class getListenedEventType() { | ||||||
|  |         return CpuInitialisationEvent.class; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void handle(GameEvent event) { | ||||||
|  |         LogManager.LOGGER.fine("(Plugin) Handled CPU Initialisation event (Cubot Plugin)"); | ||||||
|  | 
 | ||||||
|  |         CPU cpu = (CPU)event.getSource(); | ||||||
|  |         User user = ((CpuInitialisationEvent)event).getUser(); | ||||||
|  | 
 | ||||||
|  |         CubotLeg legHw = new CubotLeg((Cubot) user.getControlledUnit()); | ||||||
|  |         legHw.setCpu(cpu); | ||||||
|  |         CubotLaser laserHw = new CubotLaser((Cubot) user.getControlledUnit()); | ||||||
|  |         laserHw.setCpu(cpu); | ||||||
|  |         CubotLidar radarHw = new CubotLidar((Cubot) user.getControlledUnit()); | ||||||
|  |         radarHw.setCpu(cpu); | ||||||
|  |         Keyboard keyboard = new Keyboard((Cubot) user.getControlledUnit()); | ||||||
|  |         keyboard.setCpu(cpu); | ||||||
|  |         CubotDrill drillHw = new CubotDrill((Cubot) user.getControlledUnit()); | ||||||
|  |         drillHw.setCpu(cpu); | ||||||
|  |         CubotInventory invHw = new CubotInventory((Cubot) user.getControlledUnit()); | ||||||
|  |         invHw.setCpu(cpu); | ||||||
|  | 
 | ||||||
|  |         cpu.attachHardware(legHw, CubotLeg.DEFAULT_ADDRESS); | ||||||
|  |         cpu.attachHardware(laserHw, CubotLaser.DEFAULT_ADDRESS); | ||||||
|  |         cpu.attachHardware(radarHw, CubotLidar.DEFAULT_ADDRESS); | ||||||
|  |         cpu.attachHardware(keyboard, Keyboard.DEFAULT_ADDRESS); | ||||||
|  |         cpu.attachHardware(drillHw, CubotDrill.DEFAULT_ADDRESS); | ||||||
|  |         cpu.attachHardware(invHw, CubotInventory.DEFAULT_ADDRESS); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,47 @@ | |||||||
|  | package net.simon987.cubotplugin.event; | ||||||
|  | 
 | ||||||
|  | import net.simon987.cubotplugin.Cubot; | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.event.GameEvent; | ||||||
|  | import net.simon987.server.event.GameEventListener; | ||||||
|  | import net.simon987.server.event.UserCreationEvent; | ||||||
|  | import net.simon987.server.logging.LogManager; | ||||||
|  | import net.simon987.server.user.User; | ||||||
|  | 
 | ||||||
|  | import java.awt.*; | ||||||
|  | 
 | ||||||
|  | public class UserCreationListener implements GameEventListener { | ||||||
|  |     @Override | ||||||
|  |     public Class getListenedEventType() { | ||||||
|  |         return UserCreationEvent.class; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void handle(GameEvent event) { | ||||||
|  | 
 | ||||||
|  |         User user = (User)event.getSource(); | ||||||
|  | 
 | ||||||
|  |         LogManager.LOGGER.fine("(Plugin) Handled User creation event (Cubot Plugin)"); | ||||||
|  | 
 | ||||||
|  |         Cubot cubot = new Cubot(); | ||||||
|  | 
 | ||||||
|  |         cubot.setWorld(GameServer.INSTANCE.getGameUniverse().getWorld( | ||||||
|  |                 GameServer.INSTANCE.getConfig().getInt("new_user_worldX"), | ||||||
|  |                 GameServer.INSTANCE.getConfig().getInt("new_user_worldY"))); | ||||||
|  |         cubot.getWorld().getGameObjects().add(cubot); | ||||||
|  | 
 | ||||||
|  |         cubot.setObjectId(GameServer.INSTANCE.getGameUniverse().getNextObjectId()); | ||||||
|  | 
 | ||||||
|  |         cubot.setHeldItem(GameServer.INSTANCE.getConfig().getInt("new_user_item")); | ||||||
|  | 
 | ||||||
|  |         cubot.setParent(user); | ||||||
|  | 
 | ||||||
|  |         Point point = cubot.getWorld().getRandomPassableTile(); | ||||||
|  | 
 | ||||||
|  |         cubot.setX(point.x); | ||||||
|  |         cubot.setY(point.y); | ||||||
|  | 
 | ||||||
|  |         user.setControlledUnit(cubot); | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -3,10 +3,17 @@ package net.simon987.cubotplugin; | |||||||
| 
 | 
 | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| 
 | 
 | ||||||
|  | import static org.junit.Assert.assertEquals; | ||||||
|  | 
 | ||||||
| public class CubotTest { | public class CubotTest { | ||||||
| 
 | 
 | ||||||
|     @Test |     @Test | ||||||
|     public void test(){ |     public void test(){ | ||||||
| 
 |         try { | ||||||
|  |             Thread.sleep(1000); | ||||||
|  |         } catch (InterruptedException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |         assertEquals(1,2); | ||||||
|     } |     } | ||||||
| } | } | ||||||
							
								
								
									
										3
									
								
								Plugin Kiln/plugin.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Plugin Kiln/plugin.properties
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | classpath=net.simon987.kilnplugin.KilnPlugin | ||||||
|  | name=Kiln Plugin | ||||||
|  | version=1.0 | ||||||
							
								
								
									
										21
									
								
								Plugin Kiln/src/net/simon987/kilnplugin/KilnPlugin.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								Plugin Kiln/src/net/simon987/kilnplugin/KilnPlugin.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | package net.simon987.kilnplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.game.GameObject; | ||||||
|  | import net.simon987.server.io.GameObjectDeserializer; | ||||||
|  | import net.simon987.server.plugin.ServerPlugin; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | public class KilnPlugin extends ServerPlugin implements GameObjectDeserializer { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void init() { | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public GameObject deserializeObject(JSONObject object) { | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -1,58 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> |  | ||||||
|   <component name="FacetManager"> |  | ||||||
|     <facet type="Spring" name="Spring"> |  | ||||||
|       <configuration /> |  | ||||||
|     </facet> |  | ||||||
|   </component> |  | ||||||
|   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> |  | ||||||
|     <output url="file://$MODULE_DIR$/target/classes" /> |  | ||||||
|     <output-test url="file://$MODULE_DIR$/target/test-classes" /> |  | ||||||
|     <content url="file://$MODULE_DIR$"> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> |  | ||||||
|       <excludeFolder url="file://$MODULE_DIR$/target" /> |  | ||||||
|     </content> |  | ||||||
|     <orderEntry type="inheritedJdk" /> |  | ||||||
|     <orderEntry type="sourceFolder" forTests="false" /> |  | ||||||
|     <orderEntry type="module" module-name="Server" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.6" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-sync:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:bson:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-core:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.1.5.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.sparkjava:spark-core:2.8.0" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-server:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-webapp:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-servlet:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-security:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-server:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.sparkjava:spark-template-velocity:2.7.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.25" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: junit:junit:4.10" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" /> |  | ||||||
|   </component> |  | ||||||
| </module> |  | ||||||
| @ -1,32 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" |  | ||||||
|          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |  | ||||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |  | ||||||
|     <modelVersion>4.0.0</modelVersion> |  | ||||||
| 
 |  | ||||||
| 	<parent> |  | ||||||
| 		<groupId>net.simon987.server</groupId> |  | ||||||
| 		<artifactId>server_root</artifactId> |  | ||||||
|         <version>1.4a</version> |  | ||||||
|     </parent> |  | ||||||
| 	 |  | ||||||
|     <groupId>net.simon987.pluginmischw</groupId> |  | ||||||
|     <artifactId>plugin-misc-hw</artifactId> |  | ||||||
|     <version>1.4a</version> |  | ||||||
| 
 |  | ||||||
|     <dependencies> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>net.simon987.server</groupId> |  | ||||||
|             <artifactId>server</artifactId> |  | ||||||
|             <version>1.4a</version> |  | ||||||
|         </dependency> |  | ||||||
| 
 |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>com.googlecode.json-simple</groupId> |  | ||||||
|             <artifactId>json-simple</artifactId> |  | ||||||
|             <version>1.1.1</version> |  | ||||||
|         </dependency> |  | ||||||
| 
 |  | ||||||
|     </dependencies> |  | ||||||
| 
 |  | ||||||
| </project> |  | ||||||
| @ -1,52 +0,0 @@ | |||||||
| package net.simon987.mischwplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.assembly.Util; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Hardware to get game time |  | ||||||
|  */ |  | ||||||
| public class Clock extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     private static final char HWID = 0x0008; |  | ||||||
| 
 |  | ||||||
|     public static final char DEFAULT_ADDRESS = 0x0008; |  | ||||||
| 
 |  | ||||||
|     public Clock() { |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Clock(Document document, ControllableUnit unit) { |  | ||||||
|         super(document, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int time = (int) GameServer.INSTANCE.getGameUniverse().getTime(); |  | ||||||
| 
 |  | ||||||
|         //Will need to be changed to quadword in about 136 years |  | ||||||
|         getCpu().getRegisterSet().getRegister("B").setValue(Util.getHigherWord(time)); |  | ||||||
|         getCpu().getRegisterSet().getRegister("C").setValue(Util.getLowerWord(time)); |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
| 
 |  | ||||||
|         Document dbObject = new Document(); |  | ||||||
|         dbObject.put("type", getClass().getCanonicalName()); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,26 +0,0 @@ | |||||||
| package net.simon987.mischwplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.mischwplugin.event.CpuInitialisationListener; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.game.objects.GameRegistry; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import net.simon987.server.plugin.ServerPlugin; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Plugin that adds miscellaneous hardware to the game |  | ||||||
|  */ |  | ||||||
| public class MiscHWPlugin extends ServerPlugin { |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void init(GameServer gameServer) { |  | ||||||
|         listeners.add(new CpuInitialisationListener()); |  | ||||||
| 
 |  | ||||||
|         GameRegistry registry = gameServer.getRegistry(); |  | ||||||
| 
 |  | ||||||
|         registry.registerHardware(RandomNumberGenerator.class); |  | ||||||
|         registry.registerHardware(Clock.class); |  | ||||||
| 
 |  | ||||||
|         LogManager.LOGGER.info("(Mist HW Plugin) Initialised Misc Hardware Plugin"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,50 +0,0 @@ | |||||||
| package net.simon987.mischwplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| import java.util.Random; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Hardware to generate random numbers |  | ||||||
|  */ |  | ||||||
| public class RandomNumberGenerator extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     private static final char HWID = 0x0007; |  | ||||||
| 
 |  | ||||||
|     public static final char DEFAULT_ADDRESS = 0x0007; |  | ||||||
| 
 |  | ||||||
|     private Random random; |  | ||||||
| 
 |  | ||||||
|     public RandomNumberGenerator() { |  | ||||||
|         random = new Random(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public RandomNumberGenerator(Document document, ControllableUnit unit) { |  | ||||||
|         super(document, unit); |  | ||||||
|         random = new Random(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         getCpu().getRegisterSet().getRegister("B").setValue(random.nextInt(0xFFFF)); |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
| 
 |  | ||||||
|         Document dbObject = new Document(); |  | ||||||
|         dbObject.put("type", getClass().getCanonicalName()); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,33 +0,0 @@ | |||||||
| package net.simon987.mischwplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.mischwplugin.Clock; |  | ||||||
| import net.simon987.mischwplugin.RandomNumberGenerator; |  | ||||||
| import net.simon987.server.assembly.CPU; |  | ||||||
| import net.simon987.server.event.CpuInitialisationEvent; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.game.objects.HardwareHost; |  | ||||||
| 
 |  | ||||||
| public class CpuInitialisationListener implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return CpuInitialisationEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         CPU cpu = (CPU) event.getSource(); |  | ||||||
|         HardwareHost cubot = (HardwareHost) ((CpuInitialisationEvent) event).getUnit(); |  | ||||||
|         cpu.setHardwareHost(cubot); |  | ||||||
| 
 |  | ||||||
|         RandomNumberGenerator rngHW = new RandomNumberGenerator(); |  | ||||||
|         rngHW.setCpu(cpu); |  | ||||||
|         Clock clock = new Clock(); |  | ||||||
|         clock.setCpu(cpu); |  | ||||||
| 
 |  | ||||||
|         cpu.getHardwareHost().attachHardware(rngHW, RandomNumberGenerator.DEFAULT_ADDRESS); |  | ||||||
|         cpu.getHardwareHost().attachHardware(clock, Clock.DEFAULT_ADDRESS); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,3 +0,0 @@ | |||||||
| classpath=net.simon987.mischwplugin.MiscHWPlugin |  | ||||||
| name=Misc HW Plugin |  | ||||||
| version=1.0 |  | ||||||
| @ -1,58 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> |  | ||||||
|   <component name="FacetManager"> |  | ||||||
|     <facet type="Spring" name="Spring"> |  | ||||||
|       <configuration /> |  | ||||||
|     </facet> |  | ||||||
|   </component> |  | ||||||
|   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> |  | ||||||
|     <output url="file://$MODULE_DIR$/target/classes" /> |  | ||||||
|     <output-test url="file://$MODULE_DIR$/target/test-classes" /> |  | ||||||
|     <content url="file://$MODULE_DIR$"> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> |  | ||||||
|       <excludeFolder url="file://$MODULE_DIR$/target" /> |  | ||||||
|     </content> |  | ||||||
|     <orderEntry type="inheritedJdk" /> |  | ||||||
|     <orderEntry type="sourceFolder" forTests="false" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: junit:junit:4.10" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" /> |  | ||||||
|     <orderEntry type="module" module-name="Server" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.6" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-sync:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:bson:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-core:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.1.5.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.sparkjava:spark-core:2.8.0" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-server:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-webapp:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-servlet:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-security:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-server:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.sparkjava:spark-template-velocity:2.7.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.25" level="project" /> |  | ||||||
|   </component> |  | ||||||
| </module> |  | ||||||
| @ -1,31 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" |  | ||||||
|          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |  | ||||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |  | ||||||
|     <modelVersion>4.0.0</modelVersion> |  | ||||||
| 	 |  | ||||||
| 	<parent> |  | ||||||
| 		<groupId>net.simon987.server</groupId> |  | ||||||
| 		<artifactId>server_root</artifactId> |  | ||||||
|         <version>1.4a</version> |  | ||||||
|     </parent> |  | ||||||
| 
 |  | ||||||
|     <groupId>net.simon987.pluginnpc</groupId> |  | ||||||
|     <artifactId>plugin-npc</artifactId> |  | ||||||
|     <version>1.4a</version> |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     <dependencies> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>com.googlecode.json-simple</groupId> |  | ||||||
|             <artifactId>json-simple</artifactId> |  | ||||||
|             <version>1.1.1</version> |  | ||||||
|         </dependency> |  | ||||||
| 
 |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>net.simon987.server</groupId> |  | ||||||
|             <artifactId>server</artifactId> |  | ||||||
|             <version>1.4a</version> |  | ||||||
|         </dependency> |  | ||||||
|     </dependencies> |  | ||||||
| </project> |  | ||||||
| @ -1,162 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.Util; |  | ||||||
| import net.simon987.server.game.objects.Attackable; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import net.simon987.server.game.objects.Rechargeable; |  | ||||||
| import net.simon987.server.game.objects.Updatable; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Game object that deals damage to nearby objects and gives them energy |  | ||||||
|  */ |  | ||||||
| public class ElectricBox extends GameObject implements Updatable, Attackable { |  | ||||||
| 
 |  | ||||||
|     private static final char MAP_INFO = 0x0301; |  | ||||||
|     /** |  | ||||||
|      * Hit points |  | ||||||
|      */ |  | ||||||
|     private int hp; |  | ||||||
|     /** |  | ||||||
|      * Maximum hit points |  | ||||||
|      */ |  | ||||||
|     private static final int maxHp = GameServer.INSTANCE.getConfig().getInt("electric_box_hp"); |  | ||||||
|     /** |  | ||||||
|      * Number of hit points dealt to nearby objects each tick |  | ||||||
|      */ |  | ||||||
|     private static final int damageDealt = GameServer.INSTANCE.getConfig().getInt("electric_box_damage"); |  | ||||||
|     /** |  | ||||||
|      * Number of energy points given to nearby objects each tick |  | ||||||
|      */ |  | ||||||
|     private static final int energyGiven = GameServer.INSTANCE.getConfig().getInt("electric_box_energy_given"); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * List of nearby objects. Is updated every tick |  | ||||||
|      */ |  | ||||||
|     private ArrayList<Attackable> nearObjects = new ArrayList<>(); |  | ||||||
| 
 |  | ||||||
|     public ElectricBox() { |  | ||||||
|         hp = maxHp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public ElectricBox(Document document) { |  | ||||||
|         super(document); |  | ||||||
|         hp = document.getInteger("hp"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Currently has no effect |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void setHealRate(int hp) { |  | ||||||
|         //no op |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getHp() { |  | ||||||
|         return hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setHp(int hp) { |  | ||||||
|         this.hp = hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getMaxHp() { |  | ||||||
|         return hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Currently has no effect |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void setMaxHp(int hp) { |  | ||||||
|         //No op |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Currently has no effect |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void heal(int amount) { |  | ||||||
|         //No op |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void damage(int amount) { |  | ||||||
|         hp -= amount; |  | ||||||
| 
 |  | ||||||
|         //YOU ARE DEAD |  | ||||||
|         if (hp <= 0) { |  | ||||||
|             setDead(true); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getMapInfo() { |  | ||||||
|         return MAP_INFO; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Updates the current list nearby objects |  | ||||||
|      * <br>An object is considered 'nearby' if its Manhattan distance is {@literal <= @} 1 and is Attackable |  | ||||||
|      */ |  | ||||||
|     private void updateNearObjects() { |  | ||||||
| 
 |  | ||||||
|         nearObjects.clear(); |  | ||||||
| 
 |  | ||||||
|         for (GameObject object : getWorld().getGameObjects()) { |  | ||||||
|             if (object != this && object instanceof Attackable && Util.manhattanDist(object.getX(), object.getY(), |  | ||||||
|                     getX(), getY()) <= 1) { |  | ||||||
|                 nearObjects.add((Attackable) object); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Called every tick |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
| 
 |  | ||||||
|         updateNearObjects(); |  | ||||||
| 
 |  | ||||||
|         for (Attackable obj : nearObjects) { |  | ||||||
|             obj.damage(damageDealt); |  | ||||||
| 
 |  | ||||||
|             if (obj instanceof Rechargeable) { |  | ||||||
|                 ((Rechargeable) obj).storeEnergy(energyGiven); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject jsonSerialise() { |  | ||||||
|         JSONObject json = super.jsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         json.put("hp", hp); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("hp", getHp()); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean onDeadCallback() { |  | ||||||
|         getWorld().decUpdatable(); |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,38 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.game.objects.Action; |  | ||||||
| 
 |  | ||||||
| public class ExecuteCpuTask extends NPCTask { |  | ||||||
| 
 |  | ||||||
|     private static final int MAX_EXEC_TIME = GameServer.INSTANCE.getConfig().getInt("npc_exec_time"); |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean checkCompleted() { |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void tick(NonPlayerCharacter npc) { |  | ||||||
| 
 |  | ||||||
|         HackedNPC hNpc = (HackedNPC) npc; |  | ||||||
| 
 |  | ||||||
|         //Execute code |  | ||||||
|         int timeout = Math.min(hNpc.getEnergy(), MAX_EXEC_TIME); |  | ||||||
|         hNpc.getCpu().reset(); |  | ||||||
|         int cost = hNpc.getCpu().execute(timeout); |  | ||||||
|         hNpc.spendEnergy(cost); |  | ||||||
| 
 |  | ||||||
|         if (hNpc.getCurrentAction() == Action.WALKING) { |  | ||||||
|             if (hNpc.spendEnergy(100)) { |  | ||||||
|                 if (hNpc.incrementLocation()) { |  | ||||||
|                     //Couldn't walk |  | ||||||
|                     hNpc.setCurrentAction(Action.IDLE); |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
|                 hNpc.setCurrentAction(Action.IDLE); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,157 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.game.objects.MessageReceiver; |  | ||||||
| import net.simon987.server.game.objects.Structure; |  | ||||||
| import net.simon987.server.game.objects.Updatable; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.bson.types.ObjectId; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.Arrays; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Game objects that regularly creates NonPlayerCharacters |  | ||||||
|  */ |  | ||||||
| public class Factory extends Structure implements Updatable, MessageReceiver { |  | ||||||
| 
 |  | ||||||
|     private static final int MAP_INFO = 0x0401; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum number of NonPlayerCharacters assigned to this Factory |  | ||||||
|      */ |  | ||||||
|     private static final int MAX_NPC_COUNT = GameServer.INSTANCE.getConfig().getInt("factory_max_npc_count"); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Number of ticks to wait after creating a NonPlayerCharacter |  | ||||||
|      */ |  | ||||||
|     private static final int NPC_CREATION_COOLDOWN = NonPlayerCharacter.LIFETIME / MAX_NPC_COUNT; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Number of ticks to wait until the Factory can spawn a new NPC |  | ||||||
|      */ |  | ||||||
|     private int cooldown = 0; |  | ||||||
| 
 |  | ||||||
|     private boolean locked = true; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * If non-null, the next spawned NPC will be a HackedNPC and the program will be |  | ||||||
|      * injected in its memory |  | ||||||
|      */ |  | ||||||
|     private char[] program; |  | ||||||
|     private int programIndex = 0; |  | ||||||
| 
 |  | ||||||
|     private static final int PROGRAM_SIZE = GameServer.INSTANCE.getConfig().getInt("factory_program_size"); |  | ||||||
| 
 |  | ||||||
|     public Factory() { |  | ||||||
|         super(2, 2); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Factory(Document document) { |  | ||||||
|         super(document, 2, 2); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getMapInfo() { |  | ||||||
|         return MAP_INFO; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Called every tick |  | ||||||
|      * <br>The fist time this is called, NPCs retrieved from the database are linked to the Factory |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
| 
 |  | ||||||
|         Settlement settlement = NpcPlugin.settlementMap.get(getWorld().getId()); |  | ||||||
| 
 |  | ||||||
|         if (settlement == null) { |  | ||||||
|             //Only happens when server is killed during save function |  | ||||||
|             getWorld().decUpdatable(); |  | ||||||
|             setDead(true); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (cooldown == 0) { |  | ||||||
|             if (settlement.getNpcs().size() < MAX_NPC_COUNT) { |  | ||||||
|                 Point p = getAdjacentTile(); |  | ||||||
| 
 |  | ||||||
|                 if (p != null) { |  | ||||||
|                     NonPlayerCharacter npc = spawnNPC(p); |  | ||||||
|                     settlement.addNpc(npc); |  | ||||||
| 
 |  | ||||||
|                     getWorld().addObject(npc); |  | ||||||
|                     getWorld().incUpdatable(); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             cooldown += NPC_CREATION_COOLDOWN; |  | ||||||
| 
 |  | ||||||
|         } else { |  | ||||||
|             cooldown--; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private NonPlayerCharacter spawnNPC(Point p) { |  | ||||||
| 
 |  | ||||||
|         NonPlayerCharacter npc; |  | ||||||
| 
 |  | ||||||
|         if (programIndex == 0) { |  | ||||||
|             npc = spawnRandomNpc(p); |  | ||||||
|         } else { |  | ||||||
|             npc = spawnHackedNpc(p); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return npc; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private NonPlayerCharacter spawnRandomNpc(Point p) { |  | ||||||
|         NonPlayerCharacter npc; |  | ||||||
|         npc = new HarvesterNPC(); |  | ||||||
|         npc.setWorld(getWorld()); |  | ||||||
|         npc.setObjectId(new ObjectId()); |  | ||||||
|         npc.setX(p.x); |  | ||||||
|         npc.setY(p.y); |  | ||||||
|         return npc; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private NonPlayerCharacter spawnHackedNpc(Point p) { |  | ||||||
|         NonPlayerCharacter npc; |  | ||||||
|         npc = new HackedNPC(program); |  | ||||||
|         npc.setWorld(getWorld()); |  | ||||||
|         npc.setObjectId(new ObjectId()); |  | ||||||
|         npc.setX(p.x); |  | ||||||
|         npc.setY(p.y); |  | ||||||
| 
 |  | ||||||
|         this.locked = true; |  | ||||||
|         this.programIndex = 0; |  | ||||||
| 
 |  | ||||||
|         return npc; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean sendMessage(char[] message) { |  | ||||||
| 
 |  | ||||||
|         if (locked) { |  | ||||||
|             Settlement settlement = NpcPlugin.settlementMap.get(getWorld().getId()); |  | ||||||
| 
 |  | ||||||
|             if (Arrays.equals(settlement.getPassword(), message)) { |  | ||||||
|                 this.locked = false; |  | ||||||
| 
 |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } else if (programIndex <= PROGRAM_SIZE) { |  | ||||||
| 
 |  | ||||||
|             if (programIndex == 0) { |  | ||||||
|                 program = new char[PROGRAM_SIZE]; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             System.arraycopy(message, 0, program, programIndex, message.length); |  | ||||||
|             programIndex += message.length; |  | ||||||
| 
 |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,339 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.*; |  | ||||||
| import net.simon987.server.event.ObjectDeathEvent; |  | ||||||
| import net.simon987.server.game.item.Item; |  | ||||||
| import net.simon987.server.game.item.ItemVoid; |  | ||||||
| import net.simon987.server.game.objects.Action; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import net.simon987.server.game.objects.Direction; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import net.simon987.server.user.User; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.List; |  | ||||||
| import java.util.Map; |  | ||||||
| 
 |  | ||||||
| public class HackedNPC extends NonPlayerCharacter implements ControllableUnit { |  | ||||||
| 
 |  | ||||||
|     private static final int MEM_SIZE = GameServer.INSTANCE.getConfig().getInt("hacked_npc_mem_size"); |  | ||||||
|     private static final boolean DIE_ON_NO_ENERGY = GameServer.INSTANCE.getConfig().getInt("hacked_npc_die_on_no_energy") != 0; |  | ||||||
| 
 |  | ||||||
|     private CPU cpu; |  | ||||||
|     /** |  | ||||||
|      * List of attached hardware, 'modules' |  | ||||||
|      */ |  | ||||||
|     private Map<Integer, HardwareModule> hardwareAddresses = new HashMap<>(); |  | ||||||
|     private Map<Class<? extends HardwareModule>, Integer> hardwareModules = new HashMap<>(); |  | ||||||
| 
 |  | ||||||
|     private Action currentAction = Action.IDLE; |  | ||||||
|     private Action lastAction = Action.IDLE; |  | ||||||
|     private ArrayList<char[]> consoleMessagesBuffer = new ArrayList<>(30); //todo load from conf |  | ||||||
|     private ArrayList<char[]> lastConsoleMessagesBuffer = new ArrayList<>(30); |  | ||||||
| 
 |  | ||||||
|     HackedNPC(char[] program) { |  | ||||||
| 
 |  | ||||||
|         cpu = new CPU(); |  | ||||||
| 
 |  | ||||||
|         cpu.setMemory(new Memory(MEM_SIZE)); |  | ||||||
|         cpu.setHardwareHost(this); |  | ||||||
|         cpu.getMemory().write(cpu.getCodeSectionOffset(), program, 0, program.length); |  | ||||||
| 
 |  | ||||||
|         for (Object serialisedHw : (List) NpcPlugin.DEFAULT_HACKED_NPC.get("hardware")) { |  | ||||||
|             HardwareModule hardware = GameServer.INSTANCE.getRegistry().deserializeHardware((Document) serialisedHw, this); |  | ||||||
|             hardware.setCpu(cpu); |  | ||||||
|             attachHardware(hardware, ((Document) serialisedHw).getInteger("address")); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         setTask(new ExecuteCpuTask()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public HackedNPC(Document document) { |  | ||||||
|         super(document); |  | ||||||
| 
 |  | ||||||
|         setHp(document.getInteger("hp")); |  | ||||||
|         setDirection(Direction.getDirection(document.getInteger("direction"))); |  | ||||||
| 
 |  | ||||||
|         cpu = new CPU(); |  | ||||||
|         cpu.setHardwareHost(this); |  | ||||||
|         cpu.setMemory(new Memory((Document) document.get("memory"))); |  | ||||||
|         cpu.setRegisterSet(RegisterSet.deserialize((Document) document.get("registerSet"))); |  | ||||||
| 
 |  | ||||||
|         ArrayList hardwareList = (ArrayList) document.get("hardware"); |  | ||||||
| 
 |  | ||||||
|         for (Object serialisedHw : hardwareList) { |  | ||||||
|             HardwareModule hardware = GameServer.INSTANCE.getRegistry().deserializeHardware((Document) serialisedHw, this); |  | ||||||
|             hardware.setCpu(cpu); |  | ||||||
|             attachHardware(hardware, ((Document) serialisedHw).getInteger("address")); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         setTask(new ExecuteCpuTask()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
|         super.update(); |  | ||||||
| 
 |  | ||||||
|         lastAction = currentAction; |  | ||||||
|         currentAction = Action.IDLE; |  | ||||||
| 
 |  | ||||||
|         lastConsoleMessagesBuffer = new ArrayList<>(consoleMessagesBuffer); |  | ||||||
|         consoleMessagesBuffer.clear(); |  | ||||||
| 
 |  | ||||||
|         for (HardwareModule module : hardwareAddresses.values()) { |  | ||||||
|             module.update(); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //Self-destroy when age limit is reached |  | ||||||
|         if (getAge() >= NonPlayerCharacter.LIFETIME) { |  | ||||||
|             setDead(true); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //Don't bother calling checkCompleted() |  | ||||||
|         getTask().tick(this); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setKeyboardBuffer(ArrayList<Integer> kbBuffer) { |  | ||||||
|         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no keyboard module" + |  | ||||||
|                 "@HackedNPC::setKeyBoardBuffer()"); |  | ||||||
|         Thread.dumpStack(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setParent(User user) { |  | ||||||
|         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no parent" + |  | ||||||
|                 "@HackedNPC::setParent()"); |  | ||||||
|         Thread.dumpStack(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public User getParent() { |  | ||||||
|         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no parent" + |  | ||||||
|                 "@HackedNPC::getParent()"); |  | ||||||
|         Thread.dumpStack(); |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public ArrayList<Integer> getKeyboardBuffer() { |  | ||||||
|         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no keyboard module" + |  | ||||||
|                 "@HackedNPC::getKeyBoardBuffer()"); |  | ||||||
|         Thread.dumpStack(); |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Memory getFloppyData() { |  | ||||||
|         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has floppy data." + |  | ||||||
|                 "@HackedNPC::getFloppyData()"); |  | ||||||
|         Thread.dumpStack(); |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setAction(Action action) { |  | ||||||
|         currentAction = action; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public ArrayList<char[]> getConsoleMessagesBuffer() { |  | ||||||
|         return lastConsoleMessagesBuffer; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getConsoleMode() { |  | ||||||
|         LogManager.LOGGER.warning("Something went wrong here: Hacked NPC has no console UI." + |  | ||||||
|                 "@HackedNPC::getConsoleMode()"); |  | ||||||
|         Thread.dumpStack(); |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public CPU getCpu() { |  | ||||||
|         return cpu; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void giveItem(Item item) { |  | ||||||
|         //Overwrite item at current position |  | ||||||
|         ((NpcInventory) getHardware(NpcInventory.class)).putItem(item); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void attachHardware(HardwareModule hardware, int address) { |  | ||||||
|         hardwareAddresses.put(address, hardware); |  | ||||||
|         hardwareModules.put(hardware.getClass(), address); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void detachHardware(int address) { |  | ||||||
|         hardwareAddresses.remove(address); |  | ||||||
| 
 |  | ||||||
|         Class<? extends HardwareModule> toRemove = null; |  | ||||||
|         for (Class<? extends HardwareModule> clazz : hardwareModules.keySet()) { |  | ||||||
|             if (hardwareModules.get(clazz) == address) { |  | ||||||
|                 toRemove = clazz; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         hardwareModules.remove(toRemove); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean hardwareInterrupt(int address, Status status) { |  | ||||||
|         HardwareModule hardware = hardwareAddresses.get(address); |  | ||||||
| 
 |  | ||||||
|         if (hardware != null) { |  | ||||||
|             hardware.handleInterrupt(status); |  | ||||||
|             return true; |  | ||||||
|         } else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int hardwareQuery(int address) { |  | ||||||
|         HardwareModule hardware = hardwareAddresses.get(address); |  | ||||||
| 
 |  | ||||||
|         if (hardware != null) { |  | ||||||
|             return hardware.getId(); |  | ||||||
|         } else { |  | ||||||
|             return 0; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getEnergy() { |  | ||||||
|         NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class); |  | ||||||
|         return battery.getEnergy(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setEnergy(int energy) { |  | ||||||
|         NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class); |  | ||||||
|         battery.setEnergy(energy); |  | ||||||
| 
 |  | ||||||
|         if (energy == 0 && DIE_ON_NO_ENERGY) { |  | ||||||
|             setDead(true); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public boolean spendEnergy(int amount) { |  | ||||||
| 
 |  | ||||||
|         NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class); |  | ||||||
| 
 |  | ||||||
|         if (battery.getEnergy() - amount < 0) { |  | ||||||
|             if (DIE_ON_NO_ENERGY) { |  | ||||||
|                 setDead(true); |  | ||||||
|             } |  | ||||||
|             return false; |  | ||||||
|         } else { |  | ||||||
|             battery.setEnergy(battery.getEnergy() - amount); |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("direction", getDirection().ordinal()); |  | ||||||
|         dbObject.put("hp", getHp()); |  | ||||||
|         dbObject.put("action", lastAction.ordinal()); |  | ||||||
| 
 |  | ||||||
|         List<Document> hardwareList = new ArrayList<>(); |  | ||||||
| 
 |  | ||||||
|         for (Integer address : hardwareAddresses.keySet()) { |  | ||||||
| 
 |  | ||||||
|             HardwareModule hardware = hardwareAddresses.get(address); |  | ||||||
| 
 |  | ||||||
|             Document serialisedHw = hardware.mongoSerialise(); |  | ||||||
|             serialisedHw.put("address", address); |  | ||||||
|             hardwareList.add(serialisedHw); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         dbObject.put("hardware", hardwareList); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("memory", cpu.getMemory().mongoSerialise()); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("registerSet", cpu.getRegisterSet().mongoSerialise()); |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void storeEnergy(int amount) { |  | ||||||
| 
 |  | ||||||
|         NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class); |  | ||||||
|         battery.setEnergy(Math.min(battery.getEnergy() + amount, battery.getMaxEnergy())); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private HardwareModule getHardware(Class<? extends HardwareModule> clazz) { |  | ||||||
|         return hardwareAddresses.get(hardwareModules.get(clazz)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setMaxEnergy(int maxEnergy) { |  | ||||||
|         NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class); |  | ||||||
|         battery.setMaxEnergy(maxEnergy); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getMaxEnergy() { |  | ||||||
|         NpcBattery battery = (NpcBattery) getHardware(NpcBattery.class); |  | ||||||
|         return battery.getMaxEnergy(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean sendMessage(char[] message) { |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setCurrentAction(Action action) { |  | ||||||
|         currentAction = action; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Action getCurrentAction() { |  | ||||||
|         return currentAction; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject jsonSerialise() { |  | ||||||
|         JSONObject json = super.jsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         for (HardwareModule module : hardwareAddresses.values()) { |  | ||||||
|             JSONObject hwJson = module.jsonSerialise(); |  | ||||||
|             if (hwJson != null) { |  | ||||||
|                 json.put(module.getClass().getName(), hwJson); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         json.put("direction", getDirection().ordinal()); |  | ||||||
|         NpcInventory inv = (NpcInventory) getHardware(NpcInventory.class); |  | ||||||
|         Item item = inv.getItem(); |  | ||||||
|         json.put("heldItem", item == null ? new ItemVoid().getId() : item.getId()); |  | ||||||
|         json.put("hp", getHp()); |  | ||||||
|         json.put("action", lastAction.ordinal()); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean onDeadCallback() { |  | ||||||
| 
 |  | ||||||
|         getWorld().decUpdatable(); |  | ||||||
| 
 |  | ||||||
|         if (getSettlement() != null && getSettlement().getNpcs() != null) { |  | ||||||
|             getSettlement().getNpcs().remove(this); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         GameServer.INSTANCE.getEventDispatcher().dispatch(new ObjectDeathEvent(this)); |  | ||||||
| 
 |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject debugJsonSerialise() { |  | ||||||
|         return jsonSerialise(); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,107 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.Util; |  | ||||||
| import net.simon987.server.game.objects.Direction; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import net.simon987.server.game.objects.InventoryHolder; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Random; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Find Biomass, move towards it, collect it, repeat |  | ||||||
|  */ |  | ||||||
| public class HarvestTask extends NPCTask { |  | ||||||
| 
 |  | ||||||
|     private Random random; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Number of ticks to wait before continuing |  | ||||||
|      */ |  | ||||||
|     private int pause; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Direction of the next world to visit (randomly chosen) |  | ||||||
|      */ |  | ||||||
|     private Direction nextWorldDirection = null; |  | ||||||
| 
 |  | ||||||
|     public HarvestTask() { |  | ||||||
|         random = new Random(); |  | ||||||
|         pause = 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * This task never finishes |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public boolean checkCompleted() { |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void tick(NonPlayerCharacter npc) { |  | ||||||
| 
 |  | ||||||
|         if (pause == 0) { |  | ||||||
|             //Get biomass |  | ||||||
|             ArrayList<GameObject> biomass = npc.getWorld().findGameObjects("net.simon987.biomassplugin.BiomassBlob"); |  | ||||||
| 
 |  | ||||||
|             //Get closest one |  | ||||||
|             int minDist = Integer.MAX_VALUE; |  | ||||||
|             GameObject minBiomass = null; |  | ||||||
| 
 |  | ||||||
|             for (GameObject plant : biomass) { |  | ||||||
| 
 |  | ||||||
|                 int dist = Util.manhattanDist(npc.getX(), npc.getY(), plant.getX(), plant.getY()); |  | ||||||
| 
 |  | ||||||
|                 if (dist < minDist) { |  | ||||||
|                     minDist = dist; |  | ||||||
|                     minBiomass = plant; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             //Move towards it |  | ||||||
|             if (minBiomass != null && minDist == 1) { |  | ||||||
|                 //Reached biomass, change direction to face it |  | ||||||
|                 Direction newDirection = Direction.getFacing(npc.getX(), npc.getY(), |  | ||||||
|                         minBiomass.getX(), minBiomass.getY()); |  | ||||||
| 
 |  | ||||||
|                 if (newDirection != null) { |  | ||||||
|                     npc.setDirection(newDirection); |  | ||||||
| 
 |  | ||||||
|                     //Reached biomass, harvest it |  | ||||||
|                     if (minBiomass instanceof InventoryHolder) { |  | ||||||
|                         ((InventoryHolder) minBiomass).takeItem(1); |  | ||||||
|                         pause += 6; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|                 } else { |  | ||||||
|                     LogManager.LOGGER.severe("FIXME: tick:HarvestTask, Direction is null"); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 nextWorldDirection = null; |  | ||||||
|             } else if (minBiomass != null && npc.moveTo(minBiomass.getX(), minBiomass.getY(), 1)) { |  | ||||||
|                 //Moving towards biomass... |  | ||||||
|                 nextWorldDirection = null; |  | ||||||
|             } else { |  | ||||||
| 
 |  | ||||||
|                 if (nextWorldDirection == null) { |  | ||||||
| 
 |  | ||||||
|                     while (!npc.gotoWorld(nextWorldDirection)) { |  | ||||||
|                         nextWorldDirection = Direction.getDirection(random.nextInt(4)); |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     pause += 6; |  | ||||||
|                 } else { |  | ||||||
|                     npc.gotoWorld(nextWorldDirection); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         } else { |  | ||||||
|             pause--; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,95 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.event.ObjectDeathEvent; |  | ||||||
| import net.simon987.server.game.objects.Direction; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| public class HarvesterNPC extends NonPlayerCharacter { |  | ||||||
| 
 |  | ||||||
|     public static final int MAX_HEALTH = GameServer.INSTANCE.getConfig().getInt("harvester_hp_max"); |  | ||||||
|     public static final int HEAL_RATE = GameServer.INSTANCE.getConfig().getInt("harvester_regen"); |  | ||||||
| 
 |  | ||||||
|     public HarvesterNPC() { |  | ||||||
|         setTask(new HarvestTask()); |  | ||||||
| 
 |  | ||||||
|         setHp(MAX_HEALTH); |  | ||||||
|         setMaxHp(MAX_HEALTH); |  | ||||||
|         setHealRate(HEAL_RATE); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public HarvesterNPC(Document document) { |  | ||||||
|         super(document); |  | ||||||
| 
 |  | ||||||
|         setTask(new HarvestTask()); |  | ||||||
| 
 |  | ||||||
|         setDirection(Direction.getDirection(document.getInteger("direction"))); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
|         super.update(); |  | ||||||
| 
 |  | ||||||
|         if (getSettlement() != null) { |  | ||||||
|             if (getTask().checkCompleted()) { |  | ||||||
| 
 |  | ||||||
|                 setTask(new HarvestTask()); |  | ||||||
| 
 |  | ||||||
|             } else { |  | ||||||
|                 getTask().tick(this); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             //Self-destroy when age limit is reached |  | ||||||
|             if (getAge() >= NonPlayerCharacter.LIFETIME) { |  | ||||||
|                 setDead(true); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean onDeadCallback() { |  | ||||||
| 
 |  | ||||||
|         getWorld().decUpdatable(); |  | ||||||
| 
 |  | ||||||
|         if (getSettlement() != null && getSettlement().getNpcs() != null) { |  | ||||||
|             getSettlement().getNpcs().remove(this); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         GameServer.INSTANCE.getEventDispatcher().dispatch(new ObjectDeathEvent(this)); |  | ||||||
| 
 |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject jsonSerialise() { |  | ||||||
|         JSONObject json = super.jsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         json.put("direction", getDirection().ordinal()); |  | ||||||
|         json.put("hp", getHp()); |  | ||||||
|         json.put("action", getAction().ordinal()); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject debugJsonSerialise() { |  | ||||||
|         JSONObject json = jsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         json.put("taskCompleted", getTask().checkCompleted()); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("direction", getDirection().ordinal()); |  | ||||||
|         dbObject.put("hp", getHp()); |  | ||||||
|         dbObject.put("action", getAction().ordinal()); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,10 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| public abstract class NPCTask { |  | ||||||
| 
 |  | ||||||
|     public abstract boolean checkCompleted(); |  | ||||||
| 
 |  | ||||||
|     public abstract void tick(NonPlayerCharacter npc); |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,255 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.Util; |  | ||||||
| import net.simon987.server.game.objects.*; |  | ||||||
| import net.simon987.server.game.pathfinding.Node; |  | ||||||
| import net.simon987.server.game.pathfinding.Pathfinder; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Game object that actively interacts with the game world by doing tasks |  | ||||||
|  */ |  | ||||||
| public abstract class NonPlayerCharacter extends GameObject implements Updatable, Attackable { |  | ||||||
| 
 |  | ||||||
|     private static final char MAP_INFO = 0x0501; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum distance to travel from its factory, in Worlds |  | ||||||
|      */ |  | ||||||
|     private static final int MAX_FACTORY_DISTANCE = GameServer.INSTANCE.getConfig().getInt("npc_max_factory_distance"); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Number of ticks to live |  | ||||||
|      */ |  | ||||||
|     public static final int LIFETIME = GameServer.INSTANCE.getConfig().getInt("npc_lifetime"); |  | ||||||
| 
 |  | ||||||
|     // Set these just in case they aren't overridden in the subclass |  | ||||||
|     public static final int HP_MAX_DEFAULT = 100; |  | ||||||
|     public static final int HP_REGEN_RATE_DEFAULT = 0; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Current task |  | ||||||
|      */ |  | ||||||
|     private NPCTask task; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Action at the end of the last tick |  | ||||||
|      */ |  | ||||||
|     private Action lastAction = Action.IDLE; |  | ||||||
| 
 |  | ||||||
|     private Settlement settlement; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Age of the npc, in ticks |  | ||||||
|      */ |  | ||||||
|     private int age = 0; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Current health of the npc |  | ||||||
|      */ |  | ||||||
|     private int hp = HP_MAX_DEFAULT; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Health regeneration rate of the npc |  | ||||||
|      */ |  | ||||||
|     private int hpRegenerationRate = HP_REGEN_RATE_DEFAULT; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum health of the npc |  | ||||||
|      */ |  | ||||||
|     private int maxHp = HP_MAX_DEFAULT; |  | ||||||
| 
 |  | ||||||
|     public NonPlayerCharacter() { |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public NonPlayerCharacter(Document document) { |  | ||||||
|         super(document); |  | ||||||
| 
 |  | ||||||
|         hp = document.getInteger("hp"); |  | ||||||
|         setDirection(Direction.getDirection(document.getInteger("direction"))); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getMapInfo() { |  | ||||||
|         return MAP_INFO; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
| 
 |  | ||||||
|         age++; |  | ||||||
| 
 |  | ||||||
|         //Destroy NPCs that are not linked with a Settlement |  | ||||||
|         if (settlement == null) { |  | ||||||
|             setDead(true); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //Heal the NPC |  | ||||||
|         heal(hpRegenerationRate); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Attempt to move the NPC to the specified coordinates |  | ||||||
|      * |  | ||||||
|      * @param range distance to the desired coordinates, in tiles |  | ||||||
|      * @return true if the path is passable |  | ||||||
|      */ |  | ||||||
|     boolean moveTo(int x, int y, int range) { |  | ||||||
| 
 |  | ||||||
|         ArrayList<Node> path = Pathfinder.findPath(getWorld(), getX(), getY(), x, y, range); |  | ||||||
| 
 |  | ||||||
|         if (path != null && path.size() > 0) { |  | ||||||
| 
 |  | ||||||
|             Node nextTile = path.get(1); |  | ||||||
| 
 |  | ||||||
|             Direction newDirection = Direction.getFacing(getX(), getY(), nextTile.x, nextTile.y); |  | ||||||
| 
 |  | ||||||
|             if (newDirection != null) { |  | ||||||
|                 setDirection(newDirection); |  | ||||||
|             } else { |  | ||||||
|                 LogManager.LOGGER.severe("FIXME: moveTo:NonPlayerCharacter, Direction is null"); |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (incrementLocation()) { |  | ||||||
|                 lastAction = Action.WALKING; |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         lastAction = Action.IDLE; |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Go to the next World in the specified Direction. |  | ||||||
|      * |  | ||||||
|      * @return true if the World in the specified Direction is within the max. distance from the Factory |  | ||||||
|      */ |  | ||||||
|     boolean gotoWorld(Direction direction) { |  | ||||||
| 
 |  | ||||||
|         if (direction == Direction.NORTH) { |  | ||||||
| 
 |  | ||||||
|             if (Util.manhattanDist(settlement.getWorld().getX(), settlement.getWorld().getY(), |  | ||||||
|                     getWorld().getX(), getWorld().getY() - 1) <= MAX_FACTORY_DISTANCE) { |  | ||||||
|                 if (!moveTo(8, 0, 0)) { |  | ||||||
|                     setDirection(Direction.NORTH); |  | ||||||
|                     incrementLocation(); |  | ||||||
|                 } |  | ||||||
|                 return true; |  | ||||||
|             } else { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|         } else if (direction == Direction.EAST) { |  | ||||||
|             if (Util.manhattanDist(settlement.getWorld().getX(), settlement.getWorld().getY(), |  | ||||||
|                     getWorld().getX() + 1, getWorld().getY()) <= MAX_FACTORY_DISTANCE) { |  | ||||||
|                 if (!moveTo(15, 7, 0)) { |  | ||||||
|                     setDirection(Direction.EAST); |  | ||||||
|                     incrementLocation(); |  | ||||||
|                 } |  | ||||||
|                 return true; |  | ||||||
|             } else { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|         } else if (direction == Direction.SOUTH) { |  | ||||||
|             if (Util.manhattanDist(settlement.getWorld().getX(), settlement.getWorld().getY(), |  | ||||||
|                     getWorld().getX(), getWorld().getY() + 1) <= MAX_FACTORY_DISTANCE) { |  | ||||||
|                 if (!moveTo(8, 15, 0)) { |  | ||||||
|                     setDirection(Direction.SOUTH); |  | ||||||
|                     incrementLocation(); |  | ||||||
|                 } |  | ||||||
|                 return true; |  | ||||||
|             } else { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|         } else if (direction == Direction.WEST) { |  | ||||||
|             if (Util.manhattanDist(settlement.getWorld().getX(), settlement.getWorld().getY(), |  | ||||||
|                     getWorld().getX() - 1, getWorld().getY()) <= MAX_FACTORY_DISTANCE) { |  | ||||||
|                 if (!moveTo(0, 7, 0)) { |  | ||||||
|                     setDirection(Direction.WEST); |  | ||||||
|                     incrementLocation(); |  | ||||||
|                 } |  | ||||||
|                 return true; |  | ||||||
|             } else { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|         } else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setHealRate(int hp) { |  | ||||||
|         hpRegenerationRate = hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getHp() { |  | ||||||
|         return hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setHp(int hp) { |  | ||||||
|         this.hp = hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getMaxHp() { |  | ||||||
|         return maxHp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setMaxHp(int hp) { |  | ||||||
|         this.maxHp = hp; |  | ||||||
|         this.hp = hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void heal(int amount) { |  | ||||||
|         hp += amount; |  | ||||||
| 
 |  | ||||||
|         //Can't heal above max |  | ||||||
|         if (hp > maxHp) { |  | ||||||
|             hp = maxHp; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void damage(int amount) { |  | ||||||
|         hp -= amount; |  | ||||||
| 
 |  | ||||||
|         //YOU ARE DEAD |  | ||||||
|         if (hp <= 0) { |  | ||||||
|             setDead(true); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public NPCTask getTask() { |  | ||||||
|         return task; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setTask(NPCTask task) { |  | ||||||
|         this.task = task; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Action getAction() { |  | ||||||
|         return lastAction; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getAge() { |  | ||||||
|         return age; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Settlement getSettlement() { |  | ||||||
|         return settlement; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setSettlement(Settlement settlement) { |  | ||||||
|         this.settlement = settlement; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,109 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| public class NpcBattery extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 0x010A; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     public static final char HWID = 0x010A; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Energy units in kJ |  | ||||||
|      */ |  | ||||||
|     private int energy; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum energy units in kJ |  | ||||||
|      */ |  | ||||||
|     private int maxEnergy; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     private static final int BATTERY_POLL = 1; |  | ||||||
|     private static final int BATTERY_GET_MAX_CAPACITY = 2; |  | ||||||
| 
 |  | ||||||
|     public NpcBattery(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
| 
 |  | ||||||
|         energy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy"); |  | ||||||
|         maxEnergy = GameServer.INSTANCE.getConfig().getInt("battery_max_energy"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public NpcBattery(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
| 
 |  | ||||||
|         energy = document.getInteger("energy"); |  | ||||||
|         maxEnergy = document.getInteger("max_energy"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == BATTERY_POLL) { |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(unit.getEnergy()); |  | ||||||
| 
 |  | ||||||
|         } else if (a == BATTERY_GET_MAX_CAPACITY) { |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(unit.getMaxEnergy()); |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject jsonSerialise() { |  | ||||||
|         JSONObject json = new JSONObject(); |  | ||||||
| 
 |  | ||||||
|         json.put("energy", energy); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject debugJsonSerialise() { |  | ||||||
|         JSONObject json = jsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         json.put("max_energy", maxEnergy); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document document = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         document.put("energy", energy); |  | ||||||
|         document.put("max_energy", maxEnergy); |  | ||||||
| 
 |  | ||||||
|         return document; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getEnergy() { |  | ||||||
|         return energy; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setEnergy(int energy) { |  | ||||||
|         this.energy = energy; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getMaxEnergy() { |  | ||||||
|         return maxEnergy; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setMaxEnergy(int maxEnergy) { |  | ||||||
|         this.maxEnergy = maxEnergy; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,109 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.game.item.Item; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| public class NpcInventory extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Hardware ID (Should be unique) |  | ||||||
|      */ |  | ||||||
|     static final char HWID = 0x0106; |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 0x0106; |  | ||||||
| 
 |  | ||||||
|     private static final int INV_CLEAR = 0; |  | ||||||
|     private static final int INV_POLL = 1; |  | ||||||
|     private static final int INV_SCAN = 3; |  | ||||||
| 
 |  | ||||||
|     private Item item; |  | ||||||
| 
 |  | ||||||
|     public NpcInventory(ControllableUnit unit) { |  | ||||||
|         super(null, unit); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public NpcInventory(Document document, ControllableUnit cubot) { |  | ||||||
|         super(document, cubot); |  | ||||||
| 
 |  | ||||||
|         Document itemDoc = (Document) document.get("item"); |  | ||||||
|         if (itemDoc != null) { |  | ||||||
|             item = GameServer.INSTANCE.getRegistry().deserializeItem(itemDoc); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void putItem(Item item) { |  | ||||||
|         this.item = item; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private void scanItem() { |  | ||||||
|         int x = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
|         item.digitize(unit.getCpu().getMemory(), x); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Item clearItem() { |  | ||||||
| 
 |  | ||||||
|         Item oldItem = item; |  | ||||||
|         item.clear(unit); |  | ||||||
|         item = null; |  | ||||||
| 
 |  | ||||||
|         return oldItem; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Item getItem() { |  | ||||||
|         return item; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
| 
 |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == INV_POLL) { |  | ||||||
|             char result; |  | ||||||
|             if (item == null) { |  | ||||||
|                 result = 0; |  | ||||||
|             } else { |  | ||||||
|                 result = item.poll(); |  | ||||||
|             } |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(result); |  | ||||||
| 
 |  | ||||||
|         } else if (a == INV_CLEAR) { |  | ||||||
|             if (unit.spendEnergy(100)) { |  | ||||||
|                 clearItem(); |  | ||||||
|             } |  | ||||||
|         } else if (a == INV_SCAN) { |  | ||||||
|             if (unit.spendEnergy(200)) { |  | ||||||
|                 scanItem(); |  | ||||||
|                 clearItem(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document document = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         if (item != null) { |  | ||||||
|             document.put("item", item.mongoSerialise()); |  | ||||||
|         } else { |  | ||||||
|             document.put("item", null); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return document; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public String toString() { |  | ||||||
|         return String.format("{NpcInventory [%s]}", item); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,93 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.npcplugin.event.CpuInitialisationListener; |  | ||||||
| import net.simon987.npcplugin.event.VaultCompleteListener; |  | ||||||
| import net.simon987.npcplugin.event.VaultWorldUpdateListener; |  | ||||||
| import net.simon987.npcplugin.event.WorldCreationListener; |  | ||||||
| import net.simon987.npcplugin.world.TileVaultFloor; |  | ||||||
| import net.simon987.npcplugin.world.TileVaultWall; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.IServerConfiguration; |  | ||||||
| import net.simon987.server.game.objects.GameRegistry; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import net.simon987.server.plugin.ServerPlugin; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| import java.io.InputStream; |  | ||||||
| import java.util.Map; |  | ||||||
| import java.util.Scanner; |  | ||||||
| import java.util.concurrent.ConcurrentHashMap; |  | ||||||
| 
 |  | ||||||
| public class NpcPlugin extends ServerPlugin { |  | ||||||
| 
 |  | ||||||
|     public static Map<String, Settlement> settlementMap; |  | ||||||
| 
 |  | ||||||
|     public static Document DEFAULT_HACKED_NPC; |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void init(GameServer gameServer) { |  | ||||||
| 
 |  | ||||||
|         IServerConfiguration configuration = gameServer.getConfig(); |  | ||||||
|         GameRegistry registry = gameServer.getRegistry(); |  | ||||||
| 
 |  | ||||||
|         listeners.add(new WorldCreationListener(configuration.getInt("settlement_spawn_rate"))); |  | ||||||
|         listeners.add(new CpuInitialisationListener()); |  | ||||||
|         listeners.add(new VaultWorldUpdateListener(configuration)); |  | ||||||
|         listeners.add(new VaultCompleteListener()); |  | ||||||
| 
 |  | ||||||
|         registry.registerGameObject(HarvesterNPC.class); |  | ||||||
|         registry.registerGameObject(Factory.class); |  | ||||||
|         registry.registerGameObject(RadioTower.class); |  | ||||||
|         registry.registerGameObject(VaultDoor.class); |  | ||||||
|         registry.registerGameObject(Obstacle.class); |  | ||||||
|         registry.registerGameObject(ElectricBox.class); |  | ||||||
|         registry.registerGameObject(Portal.class); |  | ||||||
|         registry.registerGameObject(VaultExitPortal.class); |  | ||||||
|         registry.registerGameObject(HackedNPC.class); |  | ||||||
| 
 |  | ||||||
|         registry.registerHardware(RadioReceiverHardware.class); |  | ||||||
|         registry.registerHardware(NpcBattery.class); |  | ||||||
|         registry.registerHardware(NpcInventory.class); |  | ||||||
| 
 |  | ||||||
|         registry.registerTile(TileVaultFloor.ID, TileVaultFloor.class); |  | ||||||
|         registry.registerTile(TileVaultWall.ID, TileVaultWall.class); |  | ||||||
| 
 |  | ||||||
|         settlementMap = new ConcurrentHashMap<>(); |  | ||||||
| 
 |  | ||||||
|         LogManager.LOGGER.fine("(NPC Plugin) Loading default HackedNPC settings from" + |  | ||||||
|                 " defaultHackedCubotHardware.json"); |  | ||||||
|         InputStream is = getClass().getClassLoader().getResourceAsStream("defaultHackedCubotHardware.json"); |  | ||||||
|         Scanner scanner = new Scanner(is).useDelimiter("\\A"); |  | ||||||
|         String json = scanner.next(); |  | ||||||
|         DEFAULT_HACKED_NPC = Document.parse(json); |  | ||||||
| 
 |  | ||||||
|         LogManager.LOGGER.info("(NPC Plugin) Initialised NPC plugin"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document document = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         Document settlements = new Document(); |  | ||||||
|         for (String world : settlementMap.keySet()) { |  | ||||||
|             settlements.put(world, settlementMap.get(world).mongoSerialise()); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         document.put("settlement_map", settlements); |  | ||||||
| 
 |  | ||||||
|         return document; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void load(Document document) { |  | ||||||
|         super.load(document); |  | ||||||
| 
 |  | ||||||
|         Document settlements = (Document) document.get("settlement_map"); |  | ||||||
| 
 |  | ||||||
|         for (String world : settlements.keySet()) { |  | ||||||
|             settlementMap.put(world, new Settlement((Document) settlements.get(world))); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         LogManager.LOGGER.fine(String.format("(%s) Loaded %d settlements", name, settlementMap.size())); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,113 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.game.objects.Attackable; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Generic game object that blocks the path. |  | ||||||
|  */ |  | ||||||
| public class Obstacle extends GameObject implements Attackable { |  | ||||||
| 
 |  | ||||||
|     public static final int MAP_INFO = 0x0701; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Style of the obstacle. Will tell the client which sprite to display |  | ||||||
|      */ |  | ||||||
|     private int style = 0; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Current health of the npc |  | ||||||
|      */ |  | ||||||
|     private int hp; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Maximum health of the npc |  | ||||||
|      */ |  | ||||||
|     private int maxHp; |  | ||||||
| 
 |  | ||||||
|     public Obstacle(int hp) { |  | ||||||
|         this.hp = hp; |  | ||||||
|         this.maxHp = hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Obstacle(Document document) { |  | ||||||
|         super(document); |  | ||||||
|         style = document.getInteger("style"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setHealRate(int hp) { |  | ||||||
|         //No op |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void heal(int amount) { |  | ||||||
|         //No op |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getHp() { |  | ||||||
|         return hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setHp(int hp) { |  | ||||||
|         this.hp = hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getMaxHp() { |  | ||||||
|         return maxHp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void setMaxHp(int hp) { |  | ||||||
|         this.maxHp = hp; |  | ||||||
|         this.hp = hp; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void damage(int amount) { |  | ||||||
|         hp -= amount; |  | ||||||
| 
 |  | ||||||
|         //YOU ARE DEAD |  | ||||||
|         if (hp <= 0) { |  | ||||||
|             setDead(true); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getMapInfo() { |  | ||||||
|         return MAP_INFO; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getStyle() { |  | ||||||
|         return style; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setStyle(int style) { |  | ||||||
|         this.style = style; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("hp", hp); |  | ||||||
|         dbObject.put("style", style); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject jsonSerialise() { |  | ||||||
|         JSONObject json = super.jsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         json.put("hp", hp); |  | ||||||
|         json.put("style", style); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,89 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.game.objects.Enterable; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import net.simon987.server.game.objects.Structure; |  | ||||||
| import net.simon987.server.game.objects.Updatable; |  | ||||||
| import net.simon987.server.game.world.Location; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| public class Portal extends Structure implements Enterable { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Destination location |  | ||||||
|      */ |  | ||||||
|     private Location destination; |  | ||||||
| 
 |  | ||||||
|     public static final int MAP_INFO = 0x0801; |  | ||||||
| 
 |  | ||||||
|     public Portal() { |  | ||||||
|         super(1, 1); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Portal(Document document) { |  | ||||||
|         super(document, 1, 1); |  | ||||||
| 
 |  | ||||||
|         destination = new Location( |  | ||||||
|                 document.getInteger("dstWorldX"), |  | ||||||
|                 document.getInteger("dstWorldY"), |  | ||||||
|                 document.getString("dstDimension"), |  | ||||||
|                 document.getInteger("dstX"), |  | ||||||
|                 document.getInteger("dstY")); |  | ||||||
|         setX(document.getInteger("x")); |  | ||||||
|         setY(document.getInteger("y")); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Called when an object attempts to walk directly into a Enterable object |  | ||||||
|      * |  | ||||||
|      * @param object The game object that attempted to enter |  | ||||||
|      * @return true if successful, false to block the object |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public boolean enter(GameObject object) { |  | ||||||
| 
 |  | ||||||
|         World world = GameServer.INSTANCE.getGameUniverse().getWorld(destination.worldX, destination.worldY, false, destination.dimension); |  | ||||||
| 
 |  | ||||||
|         if (object instanceof Updatable) { |  | ||||||
|             object.getWorld().decUpdatable(); |  | ||||||
|             world.incUpdatable(); |  | ||||||
|         } |  | ||||||
|         object.getWorld().removeObject(object); |  | ||||||
|         object.setWorld(world); |  | ||||||
|         world.addObject(object); |  | ||||||
| 
 |  | ||||||
|         object.setX(destination.x); |  | ||||||
|         object.setY(destination.y); |  | ||||||
| 
 |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getMapInfo() { |  | ||||||
|         return MAP_INFO; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("dstWorldX", destination.worldX); |  | ||||||
|         dbObject.put("dstWorldY", destination.worldY); |  | ||||||
|         dbObject.put("dstX", destination.x); |  | ||||||
|         dbObject.put("dstY", destination.y); |  | ||||||
|         dbObject.put("dstDimension", destination.dimension); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Location getDestination() { |  | ||||||
|         return destination; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setDestination(Location destination) { |  | ||||||
|         this.destination = destination; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,86 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.assembly.HardwareModule; |  | ||||||
| import net.simon987.server.assembly.Status; |  | ||||||
| import net.simon987.server.assembly.Util; |  | ||||||
| import net.simon987.server.game.objects.Action; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
| 
 |  | ||||||
| public class RadioReceiverHardware extends HardwareModule { |  | ||||||
| 
 |  | ||||||
|     public static final char HWID = 0xC; //12 |  | ||||||
| 
 |  | ||||||
|     private static final int LISTEN = 1; |  | ||||||
| 
 |  | ||||||
|     public static final int DEFAULT_ADDRESS = 0xC; |  | ||||||
| 
 |  | ||||||
|     private ControllableUnit cubot; |  | ||||||
| 
 |  | ||||||
|     public RadioReceiverHardware(ControllableUnit cubot) { |  | ||||||
|         this.cubot = cubot; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public RadioReceiverHardware(Document document, ControllableUnit unit) { |  | ||||||
|         super(document, unit); |  | ||||||
| 
 |  | ||||||
|         this.cubot = unit; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handleInterrupt(Status status) { |  | ||||||
|         int x = getCpu().getRegisterSet().getRegister("X").getValue(); |  | ||||||
|         int a = getCpu().getRegisterSet().getRegister("A").getValue(); |  | ||||||
| 
 |  | ||||||
|         if (a == LISTEN) { |  | ||||||
| 
 |  | ||||||
|             //Find the nearest Radio Tower and query it |  | ||||||
|             cubot.setAction(Action.LISTENING); |  | ||||||
| 
 |  | ||||||
|             List<char[]> messages = new ArrayList<>(6); |  | ||||||
| 
 |  | ||||||
|             for (String world : NpcPlugin.settlementMap.keySet()) { |  | ||||||
|                 RadioTower tower = NpcPlugin.settlementMap.get(world).getRadioTower(); |  | ||||||
| 
 |  | ||||||
|                 if (tower != null && Util.manhattanDist( |  | ||||||
|                         tower.getWorld().getX(), tower.getWorld().getY(), |  | ||||||
|                         cubot.getWorld().getX(), cubot.getWorld().getY()) <= RadioTower.MAX_RANGE) { |  | ||||||
|                     //Tower is in range |  | ||||||
|                     messages.addAll(tower.getMessages()); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             //Write messages to memory |  | ||||||
|             int offset = 0; |  | ||||||
| 
 |  | ||||||
|             for (char[] message : messages) { |  | ||||||
| 
 |  | ||||||
|                 getCpu().getMemory().write(x + offset, message, 0, message.length); |  | ||||||
|                 offset += message.length; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             //Write the amount of messages received to B |  | ||||||
|             getCpu().getRegisterSet().getRegister("B").setValue(messages.size()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getId() { |  | ||||||
|         return HWID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
| 
 |  | ||||||
|         Document dbObject = new Document(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("type", getClass().getCanonicalName()); |  | ||||||
|         dbObject.put("cubot", cubot.getObjectId()); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,79 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.game.objects.MessageReceiver; |  | ||||||
| import net.simon987.server.game.objects.Structure; |  | ||||||
| import net.simon987.server.game.objects.Updatable; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONArray; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| 
 |  | ||||||
| public class RadioTower extends Structure implements MessageReceiver, Updatable { |  | ||||||
| 
 |  | ||||||
|     private static final int MAP_INFO = 0x0901; |  | ||||||
| 
 |  | ||||||
|     public static final int MAX_RANGE = GameServer.INSTANCE.getConfig().getInt("radio_tower_range"); |  | ||||||
| 
 |  | ||||||
|     private static final int MAX_MESSAGES = 16; |  | ||||||
| 
 |  | ||||||
|     public RadioTower() { |  | ||||||
|         super(1, 1); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public RadioTower(Document document) { |  | ||||||
|         super(document, 1, 1); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getMapInfo() { |  | ||||||
|         return MAP_INFO; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Messages from the current tick |  | ||||||
|      */ |  | ||||||
|     private ArrayList<char[]> messages = new ArrayList<>(4); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Messages from the last tick |  | ||||||
|      */ |  | ||||||
|     private ArrayList<char[]> lastMessages = new ArrayList<>(4); |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
|         lastMessages = new ArrayList<>(messages); |  | ||||||
|         messages.clear(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean sendMessage(char[] message) { |  | ||||||
| 
 |  | ||||||
|         if (message.length < MAX_MESSAGES) { |  | ||||||
|             messages.add(message); |  | ||||||
|             return true; |  | ||||||
|         } else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     ArrayList<char[]> getMessages() { |  | ||||||
|         return lastMessages; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject debugJsonSerialise() { |  | ||||||
|         JSONObject json = super.debugJsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         JSONArray messages = new JSONArray(); |  | ||||||
| 
 |  | ||||||
|         for (char[] message : this.messages) { |  | ||||||
|             messages.add(new String(message)); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         json.put("messages", messages); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,222 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.game.world.TilePlain; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| import net.simon987.server.game.world.WorldGenerationException; |  | ||||||
| import net.simon987.server.io.MongoSerializable; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.bson.types.ObjectId; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; |  | ||||||
| 
 |  | ||||||
| public class Settlement implements MongoSerializable { |  | ||||||
| 
 |  | ||||||
|     private Factory factory = null; |  | ||||||
|     private RadioTower radioTower = null; |  | ||||||
|     private VaultDoor vaultDoor = null; |  | ||||||
|     private World world; |  | ||||||
|     private DifficultyLevel difficultyLevel; |  | ||||||
| 
 |  | ||||||
|     private List<NonPlayerCharacter> npcs = new ArrayList<>(); |  | ||||||
| 
 |  | ||||||
|     private char[] password; |  | ||||||
| 
 |  | ||||||
|     public Settlement(Document document) { |  | ||||||
| 
 |  | ||||||
|         world = GameServer.INSTANCE.getGameUniverse().getWorld(document.getString("world"), false); |  | ||||||
|         ObjectId radioTowerId = document.getObjectId("radio_tower"); |  | ||||||
|         if (radioTowerId != null) { |  | ||||||
|             radioTower = (RadioTower) GameServer.INSTANCE.getGameUniverse().getObject(radioTowerId); |  | ||||||
|         } |  | ||||||
|         ObjectId vaultDoorId = document.getObjectId("vault_door"); |  | ||||||
|         if (vaultDoorId != null) { |  | ||||||
|             vaultDoor = (VaultDoor) GameServer.INSTANCE.getGameUniverse().getObject(vaultDoorId); |  | ||||||
|         } |  | ||||||
|         ObjectId factoryId = document.getObjectId("factory"); |  | ||||||
|         factory = (Factory) GameServer.INSTANCE.getGameUniverse().getObject(factoryId); |  | ||||||
| 
 |  | ||||||
|         difficultyLevel = DifficultyLevel.values()[document.getInteger("difficulty_level")]; |  | ||||||
| 
 |  | ||||||
|         Object[] npcArray = ((ArrayList) document.get("npcs")).toArray(); |  | ||||||
|         for (Object id : npcArray) { |  | ||||||
| 
 |  | ||||||
|             NonPlayerCharacter npc = (NonPlayerCharacter) GameServer.INSTANCE.getGameUniverse().getObject((ObjectId) id); |  | ||||||
| 
 |  | ||||||
|             if (npc != null) { |  | ||||||
|                 addNpc(npc); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         password = document.getString("password").toCharArray(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Settlement(World world) throws WorldGenerationException { |  | ||||||
| 
 |  | ||||||
|         this.world = world; |  | ||||||
|         this.difficultyLevel = DifficultyLevel.NORMAL; //TODO randomize ? |  | ||||||
|         this.password = "12345678".toCharArray(); |  | ||||||
| 
 |  | ||||||
|         outerLoopFactory: |  | ||||||
|         for (int x = 2; x < 12; x++) { |  | ||||||
|             for (int y = 2; y < 12; y++) { |  | ||||||
| 
 |  | ||||||
|                 if ((!world.isTileBlocked(x, y) && !world.isTileBlocked(x + 1, y) && |  | ||||||
|                         !world.isTileBlocked(x, y + 1) && !world.isTileBlocked(x + 1, y + 1))) { |  | ||||||
| 
 |  | ||||||
|                     Factory factory = new Factory(); |  | ||||||
| 
 |  | ||||||
|                     factory.setWorld(world); |  | ||||||
|                     factory.setObjectId(new ObjectId()); |  | ||||||
|                     factory.setX(x); |  | ||||||
|                     factory.setY(y); |  | ||||||
| 
 |  | ||||||
|                     if (factory.getAdjacentTile() == null) { |  | ||||||
|                         //Factory has no non-blocked adjacent tiles |  | ||||||
|                         continue; |  | ||||||
|                     } |  | ||||||
| 
 |  | ||||||
|                     world.addObject(factory); |  | ||||||
|                     world.incUpdatable(); |  | ||||||
|                     this.factory = factory; |  | ||||||
| 
 |  | ||||||
|                     break outerLoopFactory; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|         if (factory == null) { |  | ||||||
|             throw new WorldGenerationException("Could not place Factory"); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //Also spawn a radio tower in the same World |  | ||||||
|         Point p = world.getRandomTileWithAdjacent(8, TilePlain.ID); |  | ||||||
|         if (p != null) { |  | ||||||
|             while (p.x == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1 || p.y == 0) { |  | ||||||
|                 p = world.getRandomPassableTile(); |  | ||||||
| 
 |  | ||||||
|                 if (p == null) { |  | ||||||
|                     //World is full |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             RadioTower radioTower = new RadioTower(); |  | ||||||
| 
 |  | ||||||
|             radioTower.setWorld(world); |  | ||||||
|             radioTower.setObjectId(new ObjectId()); |  | ||||||
|             radioTower.setX(p.x); |  | ||||||
|             radioTower.setY(p.y); |  | ||||||
| 
 |  | ||||||
|             if (radioTower.getAdjacentTile() != null) { |  | ||||||
|                 //Radio Tower has adjacent tiles |  | ||||||
|                 world.addObject(radioTower); |  | ||||||
|                 world.incUpdatable(); //In case the Factory couldn't be spawned. |  | ||||||
| 
 |  | ||||||
|                 this.radioTower = radioTower; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //Also spawn a Vault in the same World |  | ||||||
|         p = world.getRandomPassableTile(); |  | ||||||
|         if (p != null) { |  | ||||||
| 
 |  | ||||||
|             VaultDoor vaultDoor = new VaultDoor(); |  | ||||||
|             vaultDoor.setWorld(world); |  | ||||||
| 
 |  | ||||||
|             int counter = 700; |  | ||||||
|             while (p.x == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1 || p.y == 0 |  | ||||||
|                     || vaultDoor.getAdjacentTileCount(true) < 8) { |  | ||||||
|                 p = world.getRandomPassableTile(); |  | ||||||
| 
 |  | ||||||
|                 if (p == null) { |  | ||||||
|                     //World is full |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 vaultDoor.setX(p.x); |  | ||||||
|                 vaultDoor.setY(p.y); |  | ||||||
| 
 |  | ||||||
|                 counter--; |  | ||||||
| 
 |  | ||||||
|                 if (counter <= 0) { |  | ||||||
|                     //Reached maximum amount of retries |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             vaultDoor.setObjectId(new ObjectId()); |  | ||||||
|             world.addObject(vaultDoor); |  | ||||||
|             world.incUpdatable(); //In case the Factory & Radio Tower couldn't be spawned. |  | ||||||
|             vaultDoor.setWorld(world); |  | ||||||
| 
 |  | ||||||
|             vaultDoor.initialize(); |  | ||||||
|             this.vaultDoor = vaultDoor; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void addNpc(NonPlayerCharacter npc) { |  | ||||||
|         npcs.add(npc); |  | ||||||
|         npc.setSettlement(this); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document document = new Document(); |  | ||||||
| 
 |  | ||||||
|         document.put("world", world.getId()); |  | ||||||
|         if (radioTower != null) { |  | ||||||
|             document.put("radio_tower", radioTower.getObjectId()); |  | ||||||
|         } |  | ||||||
|         if (vaultDoor != null) { |  | ||||||
|             document.put("vault_door", vaultDoor.getObjectId()); |  | ||||||
|         } |  | ||||||
|         document.put("factory", factory.getObjectId()); |  | ||||||
|         document.put("difficulty_level", difficultyLevel.ordinal()); |  | ||||||
|         document.put("password", String.valueOf(password)); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         List<ObjectId> npcArray = new ArrayList<>(npcs.size()); |  | ||||||
|         for (NonPlayerCharacter npc : npcs) { |  | ||||||
|             npcArray.add(npc.getObjectId()); |  | ||||||
|         } |  | ||||||
|         document.put("npcs", npcArray); |  | ||||||
| 
 |  | ||||||
|         return document; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public enum DifficultyLevel { |  | ||||||
|         NORMAL(0); |  | ||||||
| 
 |  | ||||||
|         public int cypherId; |  | ||||||
| 
 |  | ||||||
|         DifficultyLevel(int cypherId) { |  | ||||||
|             this.cypherId = cypherId; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public Factory getFactory() { |  | ||||||
|         return factory; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public RadioTower getRadioTower() { |  | ||||||
|         return radioTower; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public VaultDoor getVaultDoor() { |  | ||||||
|         return vaultDoor; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public World getWorld() { |  | ||||||
|         return world; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public List<NonPlayerCharacter> getNpcs() { |  | ||||||
|         return npcs; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public char[] getPassword() { |  | ||||||
|         return password; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,261 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.npcplugin.world.TileVaultFloor; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.IServerConfiguration; |  | ||||||
| import net.simon987.server.game.objects.Direction; |  | ||||||
| import net.simon987.server.game.world.Location; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import org.bson.types.ObjectId; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Collection; |  | ||||||
| import java.util.HashMap; |  | ||||||
| import java.util.Random; |  | ||||||
| 
 |  | ||||||
| public class VaultDimension { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Name of the dimension |  | ||||||
|      */ |  | ||||||
|     private String name; |  | ||||||
| 
 |  | ||||||
|     private World homeWorld; |  | ||||||
| 
 |  | ||||||
|     private int homeX; |  | ||||||
|     private int homeY; |  | ||||||
| 
 |  | ||||||
|     public VaultDimension(VaultDoor vaultDoor) { |  | ||||||
| 
 |  | ||||||
|         name = "v" + vaultDoor.getObjectId(); |  | ||||||
| 
 |  | ||||||
|         /* |  | ||||||
|          * Creates a group of vault worlds and pieces them together with openings. |  | ||||||
|          * For a set number of passes, a random number of vault worlds are added to each world in the |  | ||||||
|          * previous 'layer' of worlds in a random direction. Openings are added to allow movement from a |  | ||||||
|          * layer to the next, meaning that adjacent worlds are not necessarily connected, and one would |  | ||||||
|          * necessarily need to travel through 5 openings to reach the 6th layer, even when that layer is |  | ||||||
|          * less than 5 worlds away from the origin/home vault world (the one containing the exit door). |  | ||||||
|          * |  | ||||||
|          * 1. Create home world (layer 0) |  | ||||||
|          * 2. For each world in the current layer, attach a random number of new worlds |  | ||||||
|          * 3. Repeat the same step for the newly added layer |  | ||||||
|          * 4. Choose a random world from the last layer and create the vault box there (objective) |  | ||||||
|          * 5. Create an exit portal in the home world |  | ||||||
|          * |  | ||||||
|          * This process is done in 2 passes, in the first pass, worlds are defined |  | ||||||
|          * as a set of coordinates + a list of opening directions, then they are actually generated |  | ||||||
|          */ |  | ||||||
| 
 |  | ||||||
|         IServerConfiguration config = GameServer.INSTANCE.getConfig(); |  | ||||||
| 
 |  | ||||||
|         int minLayerCount = config.getInt("vault_wg_min_layer_count"); |  | ||||||
|         int maxLayerCount = config.getInt("vault_wg_max_layer_count"); |  | ||||||
|         int minAttachedWorld = config.getInt("vault_wg_min_attached_world"); |  | ||||||
|         int maxAttachedWorld = Math.min(config.getInt("vault_wg_max_attached_world"), 4); |  | ||||||
|         int minElectricBoxCount = config.getInt("vault_wg_min_electric_box_count"); |  | ||||||
|         int maxElectricBoxCount = config.getInt("vault_wg_max_electric_box_count"); |  | ||||||
| 
 |  | ||||||
|         HashMap<Integer, ArrayList<WorldBluePrint>> worldLayers = new HashMap<>(); |  | ||||||
|         VaultWorldGenerator generator = new VaultWorldGenerator(); |  | ||||||
|         Random random = new Random(); |  | ||||||
| 
 |  | ||||||
|         int layerCount = random.nextInt(maxLayerCount - minLayerCount) + minLayerCount; |  | ||||||
| 
 |  | ||||||
|         //1. Create home world |  | ||||||
|         WorldBluePrint homeWorldBluePrint = new WorldBluePrint(); |  | ||||||
|         homeWorldBluePrint.coords.x = 0x7FFF; |  | ||||||
|         homeWorldBluePrint.coords.y = 0x7FFF; |  | ||||||
|         worldLayers.put(0, new ArrayList<>()); |  | ||||||
|         worldLayers.get(0).add(homeWorldBluePrint); |  | ||||||
| 
 |  | ||||||
|         //2. For each world in the current layer, attach a random number of new worlds |  | ||||||
|         for (int i = 1; i <= layerCount; i++) { |  | ||||||
| 
 |  | ||||||
|             worldLayers.put(i, new ArrayList<>()); |  | ||||||
| 
 |  | ||||||
|             for (WorldBluePrint world : worldLayers.get(i - 1)) { |  | ||||||
| 
 |  | ||||||
|                 int attachedWorlds; |  | ||||||
|                 if (i == 1) { |  | ||||||
|                     attachedWorlds = 4; // The home world should have 4 attached worlds |  | ||||||
|                 } else { |  | ||||||
|                     attachedWorlds = random.nextInt(maxAttachedWorld - minAttachedWorld) + minAttachedWorld; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 for (int j = 0; j < attachedWorlds; j++) { |  | ||||||
| 
 |  | ||||||
|                     int randDirIndex = random.nextInt(4); |  | ||||||
| 
 |  | ||||||
|                     //Try 4 directions (wrap around 0..3) |  | ||||||
|                     for (int attemptCount = 0; attemptCount < 4; attemptCount++) { |  | ||||||
|                         Direction randomDirection = Direction.getDirection(randDirIndex); |  | ||||||
| 
 |  | ||||||
|                         //Don't attach a world at the same spot twice |  | ||||||
|                         if (!worldExists(world.coordinatesOf(randomDirection), worldLayers)) { |  | ||||||
|                             WorldBluePrint attachedWorld = world.attachWorld(randomDirection); |  | ||||||
|                             worldLayers.get(i).add(attachedWorld); |  | ||||||
|                         } |  | ||||||
|                         randDirIndex = (randDirIndex + 1) % 4; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         ArrayList<World> lastLayerWorlds = new ArrayList<>(); |  | ||||||
| 
 |  | ||||||
|         //Generate worlds |  | ||||||
|         for (Integer key : worldLayers.keySet()) { |  | ||||||
| 
 |  | ||||||
|             ArrayList<WorldBluePrint> layer = worldLayers.get(key); |  | ||||||
| 
 |  | ||||||
|             for (WorldBluePrint bp : layer) { |  | ||||||
|                 World vWorld = generator.generateVaultWorld(bp.coords.x, bp.coords.y, bp.openings, name); |  | ||||||
|                 GameServer.INSTANCE.getGameUniverse().addWorld(vWorld); |  | ||||||
| 
 |  | ||||||
|                 ArrayList<ElectricBox> newBoxes = VaultWorldUtils.generateElectricBoxes(vWorld, minElectricBoxCount, |  | ||||||
|                         maxElectricBoxCount); |  | ||||||
|                 for (ElectricBox blob : newBoxes) { |  | ||||||
|                     vWorld.addObject(blob); |  | ||||||
|                     vWorld.incUpdatable(); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if (key == layerCount) { |  | ||||||
|                     lastLayerWorlds.add(vWorld); |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if (key == 0) { |  | ||||||
|                     this.homeWorld = vWorld; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         Point exitCoords = vaultDoor.getAdjacentTile(); |  | ||||||
|         Location exitLocation = new Location(vaultDoor.getWorld().getX(), vaultDoor.getWorld().getY(), vaultDoor |  | ||||||
|                 .getWorld().getDimension(), exitCoords.x, exitCoords.y); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         //4. Choose a random world from the last layer and create the vault box there (objective) |  | ||||||
|         World objectiveWorld = lastLayerWorlds.get(random.nextInt(lastLayerWorlds.size())); |  | ||||||
| 
 |  | ||||||
|         Point exitPortalPt = objectiveWorld.getRandomTileWithAdjacent(8, TileVaultFloor.ID); |  | ||||||
| 
 |  | ||||||
|         if (exitPortalPt != null) { |  | ||||||
| 
 |  | ||||||
|             VaultExitPortal exitPortal = new VaultExitPortal(); |  | ||||||
|             exitPortal.setDestination(exitLocation); |  | ||||||
|             exitPortal.setX(exitPortalPt.x); |  | ||||||
|             exitPortal.setY(exitPortalPt.y); |  | ||||||
|             exitPortal.setWorld(objectiveWorld); |  | ||||||
|             exitPortal.setObjectId(new ObjectId()); |  | ||||||
|             objectiveWorld.addObject(exitPortal); |  | ||||||
| 
 |  | ||||||
| //            LogManager.LOGGER.severe("Objective: " + objectiveWorld.getId()); |  | ||||||
| 
 |  | ||||||
|         } else { |  | ||||||
|             LogManager.LOGGER.severe("FIXME: Couldn't create exit portal for world " + homeWorld.getId()); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //5. Create an exit portal in the home World |  | ||||||
|         Point homePortalPt = homeWorld.getRandomTileWithAdjacent(8, TileVaultFloor.ID); |  | ||||||
|         if (homePortalPt != null) { |  | ||||||
| 
 |  | ||||||
|             Portal homePortal = new Portal(); |  | ||||||
|             homePortal.setDestination(exitLocation); |  | ||||||
|             homePortal.setX(homePortalPt.x); |  | ||||||
|             homePortal.setY(homePortalPt.y); |  | ||||||
|             homePortal.setWorld(homeWorld); |  | ||||||
|             homePortal.setObjectId(new ObjectId()); |  | ||||||
|             homeWorld.addObject(homePortal); |  | ||||||
| 
 |  | ||||||
|             Point entryCoords = homePortal.getAdjacentTile(); |  | ||||||
|             homeX = entryCoords.x; |  | ||||||
|             homeY = entryCoords.y; |  | ||||||
| 
 |  | ||||||
|         } else { |  | ||||||
|             LogManager.LOGGER.severe("FIXME: Couldn't create home exit portal for world " + homeWorld.getId()); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private boolean worldExists(Point coords, HashMap<Integer, ArrayList<WorldBluePrint>> worldLayers) { |  | ||||||
| 
 |  | ||||||
|         //Auto-generated by IntelliJ Idea |  | ||||||
|         return worldLayers.values().stream().flatMap(Collection::stream).anyMatch(bp -> bp.coords.equals(coords)); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     World getHomeWorld() { |  | ||||||
|         return homeWorld; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getHomeX() { |  | ||||||
|         return homeX; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getHomeY() { |  | ||||||
|         return homeY; |  | ||||||
|     } |  | ||||||
|     /** |  | ||||||
|      * Helper class to plan the layout of a vault dimension |  | ||||||
|      */ |  | ||||||
|     private class WorldBluePrint { |  | ||||||
| 
 |  | ||||||
|         ArrayList<Direction> openings = new ArrayList<>(4); |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Coordinates of the world |  | ||||||
|          */ |  | ||||||
|         Point coords = new Point(); |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Update the blueprint's openings to allow traveling to the newly attached world |  | ||||||
|          * |  | ||||||
|          * @param direction direction of the world to attach (relative to this one) |  | ||||||
|          * @return The blueprint of the attached world |  | ||||||
|          */ |  | ||||||
|         WorldBluePrint attachWorld(Direction direction) { |  | ||||||
| 
 |  | ||||||
|             WorldBluePrint attachedWorld = new WorldBluePrint(); |  | ||||||
| 
 |  | ||||||
|             switch (direction) { |  | ||||||
|                 case NORTH: |  | ||||||
|                     openings.add(Direction.NORTH); |  | ||||||
|                     attachedWorld.openings.add(Direction.SOUTH); |  | ||||||
|                     break; |  | ||||||
|                 case EAST: |  | ||||||
|                     openings.add(Direction.EAST); |  | ||||||
|                     attachedWorld.openings.add(Direction.WEST); |  | ||||||
|                     break; |  | ||||||
|                 case SOUTH: |  | ||||||
|                     openings.add(Direction.SOUTH); |  | ||||||
|                     attachedWorld.openings.add(Direction.NORTH); |  | ||||||
|                     break; |  | ||||||
|                 case WEST: |  | ||||||
|                     openings.add(Direction.WEST); |  | ||||||
|                     attachedWorld.openings.add(Direction.EAST); |  | ||||||
|                     break; |  | ||||||
|                 default: |  | ||||||
|                 	break; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             attachedWorld.coords.x = coords.x + direction.dX; |  | ||||||
|             attachedWorld.coords.y = coords.y + direction.dY; |  | ||||||
| 
 |  | ||||||
|             return attachedWorld; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         /** |  | ||||||
|          * Get the coordinates of a world that would be attached to this world |  | ||||||
|          * |  | ||||||
|          * @param direction direction of the attached world |  | ||||||
|          */ |  | ||||||
|         Point coordinatesOf(Direction direction) { |  | ||||||
| 
 |  | ||||||
|             return new Point(coords.x + direction.dX, coords.y + direction.dY); |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,164 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.game.objects.*; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| import java.util.Arrays; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| public class VaultDoor extends Structure implements MessageReceiver, Enterable, Updatable { |  | ||||||
| 
 |  | ||||||
|     private static final int MAP_INFO = 0x0B00; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Whether or not the vault door is opened |  | ||||||
|      */ |  | ||||||
|     private boolean open = false; |  | ||||||
| 
 |  | ||||||
|     private int homeX; |  | ||||||
|     private int homeY; |  | ||||||
|     private World homeWorld; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Number of ticks to remain the door open |  | ||||||
|      */ |  | ||||||
|     private int OPEN_TIME = GameServer.INSTANCE.getConfig().getInt("vault_door_open_time"); |  | ||||||
| 
 |  | ||||||
|     private int openedTimer = 0; |  | ||||||
| 
 |  | ||||||
|     public VaultDoor() { |  | ||||||
|         super(1, 1); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public VaultDoor(Document document) { |  | ||||||
|         super(document, 1, 1); |  | ||||||
| 
 |  | ||||||
|         setX(document.getInteger("x")); |  | ||||||
|         setY(document.getInteger("y")); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|         if (document.containsKey("homeX") && document.containsKey("homeY")) { |  | ||||||
|             homeX = document.getInteger("homeX"); |  | ||||||
|             homeY = document.getInteger("homeY"); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void update() { |  | ||||||
|         if (open){ |  | ||||||
|             if (openedTimer <= 0) { |  | ||||||
|                 //Door was open for OPEN_TIME, close it |  | ||||||
|                 open = false; |  | ||||||
|                 openedTimer = 0; |  | ||||||
|                 LogManager.LOGGER.fine("Closed Vault door ID: " + getObjectId()); |  | ||||||
|             } else { |  | ||||||
|                 openedTimer--; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean sendMessage(char[] message) { |  | ||||||
| 
 |  | ||||||
|         Settlement settlement = NpcPlugin.settlementMap.get(getWorld().getId()); |  | ||||||
| 
 |  | ||||||
|         System.out.println("message: " + new String(message)); |  | ||||||
|         System.out.println("password: " + new String(settlement.getPassword())); |  | ||||||
| 
 |  | ||||||
|         if (Arrays.equals(message, settlement.getPassword())) { |  | ||||||
|             if (!open) { |  | ||||||
|                 openVault(); |  | ||||||
|             } else { |  | ||||||
|                 keepVaultOpen(); |  | ||||||
|             } |  | ||||||
|             return true; |  | ||||||
|         } else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private void openVault() { |  | ||||||
|         open = true; |  | ||||||
|         openedTimer = OPEN_TIME; |  | ||||||
|         LogManager.LOGGER.fine("Opened Vault door ID: " + getObjectId()); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private void keepVaultOpen() { |  | ||||||
|         open = true; |  | ||||||
|         openedTimer = OPEN_TIME; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean enter(GameObject object) { |  | ||||||
| 
 |  | ||||||
| //        LogManager.LOGGER.fine("VAULT enter " + open); |  | ||||||
| 
 |  | ||||||
|         if (open) { |  | ||||||
| 
 |  | ||||||
|             object.getWorld().decUpdatable(); |  | ||||||
|             object.getWorld().removeObject(object); |  | ||||||
| 
 |  | ||||||
|             homeWorld.incUpdatable(); |  | ||||||
|             homeWorld.addObject(object); |  | ||||||
|             object.setWorld(homeWorld); |  | ||||||
|             object.setX(homeX); |  | ||||||
|             object.setY(homeY); |  | ||||||
| 
 |  | ||||||
|             return true; |  | ||||||
|         } else { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getMapInfo() { |  | ||||||
|         return MAP_INFO; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("homeX", getHomeX()); |  | ||||||
|         dbObject.put("homeY", getHomeY()); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void initialize() { |  | ||||||
|         //Get or generate vault world |  | ||||||
|         homeWorld = GameServer.INSTANCE.getGameUniverse().getWorld(0x7FFF, 0x7FFF, |  | ||||||
|                 false, "v" + getObjectId() + "-"); |  | ||||||
| 
 |  | ||||||
|         if (homeWorld == null) { |  | ||||||
|             VaultDimension vaultDimension = new VaultDimension(this); |  | ||||||
|             homeWorld = vaultDimension.getHomeWorld(); |  | ||||||
|             homeX = vaultDimension.getHomeX(); |  | ||||||
|             homeY = vaultDimension.getHomeY(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getHomeX() { |  | ||||||
|         return homeX; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setHomeX(int homeX) { |  | ||||||
|         this.homeX = homeX; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getHomeY() { |  | ||||||
|         return homeY; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setHomeY(int homeY) { |  | ||||||
|         this.homeY = homeY; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,35 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import net.simon987.server.game.world.Location; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Final exit portal located in the 'last' World of a Vault dimension |  | ||||||
|  */ |  | ||||||
| public class VaultExitPortal extends Portal { |  | ||||||
| 
 |  | ||||||
|     public VaultExitPortal() { |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public VaultExitPortal(Document document) { |  | ||||||
|         super(document); |  | ||||||
| 
 |  | ||||||
|         setDestination(new Location( |  | ||||||
|                 document.getInteger("dstWorldX"), |  | ||||||
|                 document.getInteger("dstWorldY"), |  | ||||||
|                 document.getString("dstDimension"), |  | ||||||
|                 document.getInteger("dstX"), |  | ||||||
|                 document.getInteger("dstY"))); |  | ||||||
|         setX(document.getInteger("x")); |  | ||||||
|         setY(document.getInteger("y")); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean enter(GameObject object) { |  | ||||||
| 
 |  | ||||||
|         //TODO: Trigger vault complete event instead |  | ||||||
|         return super.enter(object); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,265 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.game.objects.Direction; |  | ||||||
| import net.simon987.server.game.world.TileMap; |  | ||||||
| import net.simon987.server.game.world.TileVoid; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Comparator; |  | ||||||
| import java.util.Random; |  | ||||||
| 
 |  | ||||||
| public class VaultWorldGenerator { |  | ||||||
| 
 |  | ||||||
|     public World generateVaultWorld(int worldX, int worldY, ArrayList<Direction> openings, String dimension) { |  | ||||||
| 
 |  | ||||||
| //        LogManager.LOGGER.info("Generating vault World"); |  | ||||||
| 
 |  | ||||||
|         /* |  | ||||||
|          * Openings are always at the same spot (marked by '?') |  | ||||||
|          * 1. Rectangles of random size are generated |  | ||||||
|          * 2. Openings are generated (if another vault world is connected on this direction) |  | ||||||
|          * 3. They are connected with tunnels from bottom to top, |  | ||||||
|          *  by their roomCenter, alternating between horizontal first |  | ||||||
|          *  tunnels and vertical first |  | ||||||
|          * 4. Tiles adjacent to floor tiles are set to wall tiles |  | ||||||
|          * Example map: |  | ||||||
|          * |  | ||||||
|          *  # # # # # # # - - - # ? ? # - - - - - - - - - - |  | ||||||
|          *  # o o o o o # - - - # ? ? # - - - - - - - - - - |  | ||||||
|          *  # o o o o o # # # # # # o # - - - - - - - - - - |  | ||||||
|          *  # o o o o o o o o o o o o # - - - - - - - - - - |  | ||||||
|          *  # o o o o o # # # # # # # # # # # - - - - - - - |  | ||||||
|          *  # o o o o o # - - - - # o o o o # - - - - - - - |  | ||||||
|          *  # o o o o o # # # # # # o o o o # - - - - - - - |  | ||||||
|          *  # # o o o o o o o o o o o o o o # - - - - - - - |  | ||||||
|          *  - # o # # # # # # # # # o o o o # - - - - - - - |  | ||||||
|          *  - # o # - - - - - - - # # # # # # - - - - - - - |  | ||||||
|          *  # # o # - - - - - - - - - - - - - - - - - # # # |  | ||||||
|          *  ? ? o # # # # # # # # # # # # # # # # # # # ? ? |  | ||||||
|          *  ? ? o o o o o o o o o o o o o o o o o o o o ? ? |  | ||||||
|          *  # # # # # # # # # # # # # # # # # # o # # # # # |  | ||||||
|          *  - - - - - - - - - - - - - - - - - # o # - - - - |  | ||||||
|          *  - # # # # # # # # # - - - - - - - # o # - - - - |  | ||||||
|          *  - # o o o o o o o # - - - # # # # # o # # # # - |  | ||||||
|          *  - # o o o o o o o # # # # # o o o o o o o o # - |  | ||||||
|          *  - # o o o o o o o o o o o # o o o o o o o o # - |  | ||||||
|          *  - # o o o o o o o # # # o # o o o o o o o o # - |  | ||||||
|          *  - # o o o o o o o # - # o # # # # # # # # # # - |  | ||||||
|          *  - # o o o o o o o # # # o # - - - - - - - - - - |  | ||||||
|          *  - # # # # # # # # # # ? ? # - - - - - - - - - - |  | ||||||
|          *  - - - - - - - - - - # ? ? # - - - - - - - - - - |  | ||||||
|          */ |  | ||||||
| 
 |  | ||||||
|         Random random = new Random(); |  | ||||||
| 
 |  | ||||||
|         int worldSize = 20; |  | ||||||
|         int floorTile = 4; |  | ||||||
|         int wallTile = 5; |  | ||||||
|         int minRoomCount = 5; |  | ||||||
|         int maxRoomCount = 8; |  | ||||||
|         int minRoomWidth = 4; |  | ||||||
|         int minRoomHeight = 4; |  | ||||||
|         int maxRoomWidth = 8; |  | ||||||
|         int maxRoomHeight = 8; |  | ||||||
| 
 |  | ||||||
|         ArrayList<Point> roomCenters = new ArrayList<>(maxRoomCount + 4); |  | ||||||
|         ArrayList<Rectangle> rooms = new ArrayList<>(maxRoomCount); |  | ||||||
| 
 |  | ||||||
|         World world = new World(worldX, worldY, new TileMap(worldSize, worldSize), dimension); |  | ||||||
| 
 |  | ||||||
|         TileMap map = world.getTileMap(); |  | ||||||
| 
 |  | ||||||
|         //Generate rectangles of random size |  | ||||||
|         int roomCount = random.nextInt(maxRoomCount - minRoomCount) + minRoomCount; |  | ||||||
| 
 |  | ||||||
|         for (int i = 0; i < roomCount; i++) { |  | ||||||
| 
 |  | ||||||
|             int roomWidth = random.nextInt(maxRoomWidth - minRoomWidth) + minRoomWidth; |  | ||||||
|             int roomHeight = random.nextInt(maxRoomHeight - minRoomHeight) + minRoomHeight; |  | ||||||
| 
 |  | ||||||
|             int attempts = 35; |  | ||||||
|             Point roomCorner; |  | ||||||
|             Rectangle room = null; |  | ||||||
| 
 |  | ||||||
|             //Try to find a spot that doesn't intersect another room |  | ||||||
|             attemptsLoop: |  | ||||||
|             while (true) { |  | ||||||
| 
 |  | ||||||
|                 if (attempts < 0) { |  | ||||||
|                     roomCorner = null; |  | ||||||
|                     break; |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 roomCorner = new Point(random.nextInt((worldSize - roomWidth) - 2) + 2, |  | ||||||
|                         random.nextInt((worldSize - roomHeight) - 2) + 2); |  | ||||||
| 
 |  | ||||||
|                 room = new Rectangle(roomCorner.x, roomCorner.y, roomWidth, roomHeight); |  | ||||||
| 
 |  | ||||||
|                 for (Rectangle otherRoom : rooms) { |  | ||||||
|                     if (otherRoom.intersects(room)) { |  | ||||||
|                         attempts--; |  | ||||||
|                         continue attemptsLoop; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             if (roomCorner != null) { |  | ||||||
|                 for (int x = roomCorner.x; x < roomCorner.x + roomWidth; x++) { |  | ||||||
|                     for (int y = roomCorner.y; y < roomCorner.y + roomHeight; y++) { |  | ||||||
|                         map.setTileAt(floorTile, x, y); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 rooms.add(room); |  | ||||||
|                 roomCenters.add(new Point(roomCorner.x + roomWidth / 2, roomCorner.y + roomHeight / 2)); |  | ||||||
|             } else { |  | ||||||
|                 break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //Create openings |  | ||||||
|         for (Direction opening : openings) { |  | ||||||
|             switch (opening) { |  | ||||||
|                 case NORTH: |  | ||||||
| 
 |  | ||||||
|                     map.setTileAt(floorTile, worldSize / 2, 0); |  | ||||||
|                     map.setTileAt(floorTile, worldSize / 2, 1); |  | ||||||
|                     map.setTileAt(floorTile, worldSize / 2 - 1, 0); |  | ||||||
|                     map.setTileAt(floorTile, worldSize / 2 - 1, 1); |  | ||||||
|                     roomCenters.add(new Point(worldSize / 2, 1)); |  | ||||||
|                     break; |  | ||||||
|                 case EAST: |  | ||||||
| 
 |  | ||||||
|                     map.setTileAt(floorTile, worldSize - 1, worldSize / 2); |  | ||||||
|                     map.setTileAt(floorTile, worldSize - 1, worldSize / 2 - 1); |  | ||||||
|                     map.setTileAt(floorTile, worldSize - 2, worldSize / 2); |  | ||||||
|                     map.setTileAt(floorTile, worldSize - 2, worldSize / 2 - 1); |  | ||||||
|                     roomCenters.add(new Point(worldSize - 2, worldSize / 2 - 1)); |  | ||||||
|                     break; |  | ||||||
|                 case SOUTH: |  | ||||||
| 
 |  | ||||||
|                     map.setTileAt(floorTile, worldSize / 2, worldSize - 1); |  | ||||||
|                     map.setTileAt(floorTile, worldSize / 2, worldSize - 2); |  | ||||||
|                     map.setTileAt(floorTile, worldSize / 2 - 1, worldSize - 1); |  | ||||||
|                     map.setTileAt(floorTile, worldSize / 2 - 1, worldSize - 2); |  | ||||||
|                     roomCenters.add(new Point(worldSize / 2, worldSize - 2)); |  | ||||||
|                     break; |  | ||||||
|                 case WEST: |  | ||||||
| 
 |  | ||||||
|                     map.setTileAt(floorTile, 0, worldSize / 2); |  | ||||||
|                     map.setTileAt(floorTile, 0, worldSize / 2 - 1); |  | ||||||
|                     map.setTileAt(floorTile, 1, worldSize / 2); |  | ||||||
|                     map.setTileAt(floorTile, 1, worldSize / 2 - 1); |  | ||||||
|                     roomCenters.add(new Point(1, worldSize / 2 - 1)); |  | ||||||
|                     break; |  | ||||||
|                 default: |  | ||||||
|                      |  | ||||||
|                 	break; |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //Connect rooms together, from bottom to top |  | ||||||
|         roomCenters.sort(new RoomCenterComparator()); |  | ||||||
|         boolean xFirst = true; //Start the tunnel horizontally |  | ||||||
| 
 |  | ||||||
|         for (int i = 0; i < roomCenters.size() - 1; i++) { |  | ||||||
|             //Note to self: I wouldn't bother trying to understand what's in this for loop, |  | ||||||
|             //If this needs to be modified just trash it and start over |  | ||||||
| 
 |  | ||||||
|             if (xFirst) { |  | ||||||
|                 if (roomCenters.get(i + 1).x - roomCenters.get(i).x < 0) { |  | ||||||
|                     for (int x = roomCenters.get(i).x; x > roomCenters.get(i + 1).x; x--) { |  | ||||||
|                         map.setTileAt(floorTile, x, roomCenters.get(i).y); |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     for (int x = roomCenters.get(i).x; x < roomCenters.get(i + 1).x; x++) { |  | ||||||
|                         map.setTileAt(floorTile, x, roomCenters.get(i).y); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if (roomCenters.get(i + 1).y - roomCenters.get(i).y < 0) { |  | ||||||
|                     for (int y = roomCenters.get(i).y; y > roomCenters.get(i + 1).y; y--) { |  | ||||||
|                         map.setTileAt(floorTile, roomCenters.get(i + 1).x, y); |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     for (int y = roomCenters.get(i).y; y < roomCenters.get(i + 1).y; y++) { |  | ||||||
|                         map.setTileAt(floorTile, roomCenters.get(i + 1).x, y); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } else { |  | ||||||
| 
 |  | ||||||
|                 if (roomCenters.get(i + 1).x - roomCenters.get(i).x < 0) { |  | ||||||
|                     for (int x = roomCenters.get(i).x; x > roomCenters.get(i + 1).x; x--) { |  | ||||||
|                         map.setTileAt(floorTile, x, roomCenters.get(i + 1).y); |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     for (int x = roomCenters.get(i).x; x < roomCenters.get(i + 1).x; x++) { |  | ||||||
|                         map.setTileAt(floorTile, x, roomCenters.get(i + 1).y); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 if (roomCenters.get(i + 1).y - roomCenters.get(i).y < 0) { |  | ||||||
|                     for (int y = roomCenters.get(i).y; y > roomCenters.get(i + 1).y; y--) { |  | ||||||
|                         map.setTileAt(floorTile, roomCenters.get(i).x, y); |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     for (int y = roomCenters.get(i).y; y < roomCenters.get(i + 1).y; y++) { |  | ||||||
|                         map.setTileAt(floorTile, roomCenters.get(i).x, y); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             xFirst = !xFirst; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //Tiles adjacent to floor tiles are set to wall tiles |  | ||||||
|         for (int x = 0; x < worldSize; x++) { |  | ||||||
|             for (int y = 0; y < worldSize; y++) { |  | ||||||
| 
 |  | ||||||
|                 if (map.getTileIdAt(x, y) != floorTile && hasTileAdjacent(x, y, map, floorTile)) { |  | ||||||
|                     map.setTileAt(wallTile, x, y); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         //Set other tiles to 'void' |  | ||||||
|         for (int x = 0; x < worldSize; x++) { |  | ||||||
|             for (int y = 0; y < worldSize; y++) { |  | ||||||
| 
 |  | ||||||
|                 if (map.getTileIdAt(x, y) != floorTile && map.getTileIdAt(x, y) != wallTile) { |  | ||||||
|                     map.setTileAt(new TileVoid(), x, y); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return world; |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private boolean hasTileAdjacent(int x, int y, TileMap map, int tile) { |  | ||||||
| 
 |  | ||||||
|         for (int dX = -1; dX <= 1; dX++) { |  | ||||||
|             for (int dY = -1; dY <= 1; dY++) { |  | ||||||
| 
 |  | ||||||
|                 if (map.getTileIdAt(x + dX, y + dY) == tile) { |  | ||||||
|                     return true; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private class RoomCenterComparator implements Comparator<Point> { |  | ||||||
|         @Override |  | ||||||
|         public int compare(Point o1, Point o2) { |  | ||||||
|             return o1.y - o2.y; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,76 +0,0 @@ | |||||||
| package net.simon987.npcplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.npcplugin.world.TileVaultFloor; |  | ||||||
| import net.simon987.server.game.world.TileMap; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| import org.bson.types.ObjectId; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Random; |  | ||||||
| 
 |  | ||||||
| public class VaultWorldUtils { |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     public static ArrayList<ElectricBox> generateElectricBoxes(World world, int minCount, int maxCount) { |  | ||||||
| 
 |  | ||||||
|         Random random = new Random(); |  | ||||||
|         int boxesCount = random.nextInt(maxCount - minCount) + minCount; |  | ||||||
|         ArrayList<ElectricBox> electricBoxes = new ArrayList<>(boxesCount); |  | ||||||
| 
 |  | ||||||
|         //Count number of floor tiles. If there is less plain tiles than desired amount of boxes, |  | ||||||
|         //set the desired amount of blobs to the plain tile count |  | ||||||
|         TileMap m = world.getTileMap(); |  | ||||||
|         int floorCount = 0; |  | ||||||
|         for (int y = 0; y < world.getWorldSize(); y++) { |  | ||||||
|             for (int x = 0; x < world.getWorldSize(); x++) { |  | ||||||
| 
 |  | ||||||
|                 if (m.getTileIdAt(x, y) == TileVaultFloor.ID) { |  | ||||||
|                     floorCount++; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (boxesCount > floorCount) { |  | ||||||
|             boxesCount = floorCount; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         outerLoop: |  | ||||||
|         for (int i = 0; i < boxesCount; i++) { |  | ||||||
| 
 |  | ||||||
|             Point p = m.getRandomTile(TileVaultFloor.ID); |  | ||||||
|             if (p != null) { |  | ||||||
| 
 |  | ||||||
|                 //Don't block worlds |  | ||||||
|                 int counter = 0; |  | ||||||
|                 while (p.x == 0 || p.y == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1 || |  | ||||||
|                         world.getGameObjectsAt(p.x, p.y).size() != 0) { |  | ||||||
|                     p = m.getRandomTile(TileVaultFloor.ID); |  | ||||||
|                     counter++; |  | ||||||
| 
 |  | ||||||
|                     if (counter > 25) { |  | ||||||
|                         continue outerLoop; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 for (ElectricBox box : electricBoxes) { |  | ||||||
|                     if (box.getX() == p.x && box.getY() == p.y) { |  | ||||||
|                         //There is already a box here |  | ||||||
|                         continue outerLoop; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 ElectricBox box = new ElectricBox(); |  | ||||||
|                 box.setObjectId(new ObjectId()); |  | ||||||
|                 box.setX(p.x); |  | ||||||
|                 box.setY(p.y); |  | ||||||
|                 box.setWorld(world); |  | ||||||
| 
 |  | ||||||
|                 electricBoxes.add(box); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return electricBoxes; |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,29 +0,0 @@ | |||||||
| package net.simon987.npcplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.npcplugin.RadioReceiverHardware; |  | ||||||
| import net.simon987.server.assembly.CPU; |  | ||||||
| import net.simon987.server.event.CpuInitialisationEvent; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import net.simon987.server.game.objects.HardwareHost; |  | ||||||
| 
 |  | ||||||
| public class CpuInitialisationListener implements GameEventListener { |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return CpuInitialisationEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
|         CPU cpu = (CPU) event.getSource(); |  | ||||||
|         ControllableUnit controllableUnit = ((CpuInitialisationEvent) event).getUnit(); |  | ||||||
|         cpu.setHardwareHost((HardwareHost) controllableUnit); |  | ||||||
| 
 |  | ||||||
|         RadioReceiverHardware radioHw = new RadioReceiverHardware(controllableUnit); |  | ||||||
|         radioHw.setCpu(cpu); |  | ||||||
| 
 |  | ||||||
|         cpu.getHardwareHost().attachHardware(radioHw, RadioReceiverHardware.DEFAULT_ADDRESS); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,26 +0,0 @@ | |||||||
| package net.simon987.npcplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.npcplugin.VaultExitPortal; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| 
 |  | ||||||
| public class VaultCompleteEvent extends GameEvent { |  | ||||||
| 
 |  | ||||||
|     private VaultExitPortal portal; |  | ||||||
| 
 |  | ||||||
|     public VaultCompleteEvent(GameObject object, VaultExitPortal portal) { |  | ||||||
| 
 |  | ||||||
|         //TODO: Add completion time? |  | ||||||
|         setSource(object); |  | ||||||
|         this.portal = portal; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public GameObject getSource() { |  | ||||||
|         return (GameObject) super.getSource(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public VaultExitPortal getPortal() { |  | ||||||
|         return portal; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,27 +0,0 @@ | |||||||
| package net.simon987.npcplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| 
 |  | ||||||
| public class VaultCompleteListener implements GameEventListener { |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return VaultCompleteEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
|         VaultCompleteEvent vaultCompleteEvent = (VaultCompleteEvent) event; |  | ||||||
|         GameObject object = vaultCompleteEvent.getSource(); |  | ||||||
|         if (object instanceof ControllableUnit) { |  | ||||||
|             LogManager.LOGGER.info(((ControllableUnit) object).getParent().getUsername() + " Completed vault " + |  | ||||||
|                     object.getWorld().getDimension()); |  | ||||||
| 
 |  | ||||||
|             ((ControllableUnit) object).getParent().getStats().addToStringSet("completedVaults", |  | ||||||
|                     vaultCompleteEvent.getPortal().getWorld().getDimension()); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,86 +0,0 @@ | |||||||
| package net.simon987.npcplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.npcplugin.ElectricBox; |  | ||||||
| import net.simon987.npcplugin.VaultWorldUtils; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.IServerConfiguration; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.event.WorldUpdateEvent; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.HashMap; |  | ||||||
| 
 |  | ||||||
| public class VaultWorldUpdateListener implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Map of worlds and their time to wait until next respawn event |  | ||||||
|      */ |  | ||||||
|     private HashMap<World, Long> worldWaitMap = new HashMap<>(200); |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Lower bound of ElectricBox to be created on a respawn event |  | ||||||
|      */ |  | ||||||
|     private static int minElectricBoxCount; |  | ||||||
|     /** |  | ||||||
|      * Upper bound of ElectricBox to be created on a respawn event |  | ||||||
|      */ |  | ||||||
|     private static int maxElectricBoxCount; |  | ||||||
|     /** |  | ||||||
|      * Number of game ticks to wait after the threshold has been met |  | ||||||
|      */ |  | ||||||
|     private static int waitTime; |  | ||||||
|     /** |  | ||||||
|      * Threshold before starting the |  | ||||||
|      */ |  | ||||||
|     private static int electricBoxThreshold; |  | ||||||
| 
 |  | ||||||
|     public VaultWorldUpdateListener(IServerConfiguration config) { |  | ||||||
| 
 |  | ||||||
|         minElectricBoxCount = config.getInt("min_electric_box_respawn_count"); |  | ||||||
|         maxElectricBoxCount = config.getInt("max_electric_box_respawn_count"); |  | ||||||
|         waitTime = config.getInt("electric_box_respawnTime"); |  | ||||||
|         electricBoxThreshold = config.getInt("min_electric_box_count"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return WorldUpdateEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         //TODO: Move this and the Biomass UpdateListener to a 'RespawnManager' kind of deal |  | ||||||
|         World world = ((WorldUpdateEvent) event).getWorld(); |  | ||||||
| 
 |  | ||||||
|         if (world.getDimension().startsWith("v")) { |  | ||||||
|             //If there is less than the respawn threshold, |  | ||||||
|             if (world.findObjects(ElectricBox.class).size() < electricBoxThreshold) { |  | ||||||
| 
 |  | ||||||
|                 //Set a timer for respawn_time ticks |  | ||||||
|                 if (!worldWaitMap.containsKey(world) || worldWaitMap.get(world) == 0L) { |  | ||||||
|                     worldWaitMap.put(world, GameServer.INSTANCE.getGameUniverse().getTime() + waitTime); |  | ||||||
|                 } else { |  | ||||||
| 
 |  | ||||||
|                     long waitUntil = worldWaitMap.get(world); |  | ||||||
| 
 |  | ||||||
|                     if (GameServer.INSTANCE.getGameUniverse().getTime() >= waitUntil) { |  | ||||||
| 
 |  | ||||||
|                         //If the timer was set less than respawn_time ticks ago, respawn the blobs |  | ||||||
|                         ArrayList<ElectricBox> newBoxes = VaultWorldUtils.generateElectricBoxes(world, minElectricBoxCount, |  | ||||||
|                                 maxElectricBoxCount); |  | ||||||
|                         for (ElectricBox blob : newBoxes) { |  | ||||||
|                             world.addObject(blob); |  | ||||||
|                             world.incUpdatable(); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         //Set the 'waitUntil' time to 0 to indicate that we are not waiting |  | ||||||
|                         worldWaitMap.replace(world, 0L); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,48 +0,0 @@ | |||||||
| package net.simon987.npcplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.npcplugin.NpcPlugin; |  | ||||||
| import net.simon987.npcplugin.Settlement; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.event.WorldGenerationEvent; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| import net.simon987.server.game.world.WorldGenerationException; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| 
 |  | ||||||
| import java.util.Random; |  | ||||||
| 
 |  | ||||||
| public class WorldCreationListener implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Spawn rate. Higher = rarer: A factory will be spawn about every FACTORY_SPAWN_RATE generated Worlds |  | ||||||
|      */ |  | ||||||
|     private static int FACTORY_SPAWN_RATE = 0; |  | ||||||
| 
 |  | ||||||
|     private Random random = new Random(); |  | ||||||
| 
 |  | ||||||
|     public WorldCreationListener(int factorySpawnRate) { |  | ||||||
|         FACTORY_SPAWN_RATE = factorySpawnRate; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return WorldGenerationEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         if (random.nextInt(FACTORY_SPAWN_RATE) == 0) { |  | ||||||
| 
 |  | ||||||
|             World world = (World) event.getSource(); |  | ||||||
| 
 |  | ||||||
|             try { |  | ||||||
|                 Settlement settlement = new Settlement(world); |  | ||||||
|                 NpcPlugin.settlementMap.put(world.getId(), settlement); |  | ||||||
|             } catch (WorldGenerationException e) { |  | ||||||
|                 LogManager.LOGGER.fine(String.format("Exception during settlement generation: %s.", |  | ||||||
|                         e.getMessage())); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,13 +0,0 @@ | |||||||
| package net.simon987.npcplugin.world; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.game.world.Tile; |  | ||||||
| 
 |  | ||||||
| public class TileVaultFloor extends Tile { |  | ||||||
| 
 |  | ||||||
|     public static final int ID = 4; |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getId() { |  | ||||||
|         return ID; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,26 +0,0 @@ | |||||||
| package net.simon987.npcplugin.world; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import net.simon987.server.game.world.Tile; |  | ||||||
| 
 |  | ||||||
| public class TileVaultWall extends Tile { |  | ||||||
| 
 |  | ||||||
|     public static final int ID = 5; |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getId() { |  | ||||||
|         return ID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean walk(GameObject object) { |  | ||||||
|         return false; //always blocked |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean isBlocked() { |  | ||||||
|         return true; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| } |  | ||||||
| @ -1,62 +0,0 @@ | |||||||
| { |  | ||||||
|   "hardware": [ |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.cubotplugin.CubotLeg", |  | ||||||
|       "address": 1 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.cubotplugin.CubotLaser", |  | ||||||
|       "address": 2 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.cubotplugin.CubotLidar", |  | ||||||
|       "address": 3 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.cubotplugin.CubotDrill", |  | ||||||
|       "address": 5 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.npcplugin.NpcInventory", |  | ||||||
|       "item": null, |  | ||||||
|       "address": 6 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.mischwplugin.RandomNumberGenerator", |  | ||||||
|       "address": 7 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.mischwplugin.Clock", |  | ||||||
|       "address": 8 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.cubotplugin.CubotHologram", |  | ||||||
|       "color": 0, |  | ||||||
|       "value": 0, |  | ||||||
|       "string": "", |  | ||||||
|       "mode": 0, |  | ||||||
|       "address": 9 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.npcplugin.NpcBattery", |  | ||||||
|       "energy": 60000, |  | ||||||
|       "max_energy": 60000, |  | ||||||
|       "address": 262 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.npcplugin.RadioReceiverHardware", |  | ||||||
|       "cubot": { |  | ||||||
|         "$oid": "5c1d43e40d3d2530aba636df" |  | ||||||
|       }, |  | ||||||
|       "address": 12 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.cubotplugin.CubotComPort", |  | ||||||
|       "address": 13 |  | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "type": "net.simon987.cubotplugin.CubotCore", |  | ||||||
|       "address": 14 |  | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| } |  | ||||||
| @ -1,4 +0,0 @@ | |||||||
| classpath=net.simon987.npcplugin.NpcPlugin |  | ||||||
| name=NPC Plugin |  | ||||||
| version=1.1 |  | ||||||
| depend=Cubot Plugin |  | ||||||
| @ -1,58 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> |  | ||||||
|   <component name="FacetManager"> |  | ||||||
|     <facet type="Spring" name="Spring"> |  | ||||||
|       <configuration /> |  | ||||||
|     </facet> |  | ||||||
|   </component> |  | ||||||
|   <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8"> |  | ||||||
|     <output url="file://$MODULE_DIR$/target/classes" /> |  | ||||||
|     <output-test url="file://$MODULE_DIR$/target/test-classes" /> |  | ||||||
|     <content url="file://$MODULE_DIR$"> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" /> |  | ||||||
|       <sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" /> |  | ||||||
|       <excludeFolder url="file://$MODULE_DIR$/target" /> |  | ||||||
|     </content> |  | ||||||
|     <orderEntry type="inheritedJdk" /> |  | ||||||
|     <orderEntry type="sourceFolder" forTests="false" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.googlecode.json-simple:json-simple:1.1.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: junit:junit:4.10" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.1" level="project" /> |  | ||||||
|     <orderEntry type="module" module-name="Server" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-text:1.6" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.8.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-sync:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:bson:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.mongodb:mongodb-driver-core:3.9.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework.security:spring-security-core:5.1.5.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.6.RELEASE" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.sparkjava:spark-core:2.8.0" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-server:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: javax.servlet:javax.servlet-api:3.1.0" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-http:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-util:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-io:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-webapp:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-xml:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-servlet:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-security:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-server:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-common:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-client:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty:jetty-client:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-servlet:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.eclipse.jetty.websocket:websocket-api:9.4.12.v20180830" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: com.sparkjava:spark-template-velocity:2.7.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.apache.velocity:velocity:1.7" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: commons-lang:commons-lang:2.4" level="project" /> |  | ||||||
|     <orderEntry type="library" name="Maven: org.slf4j:slf4j-simple:1.7.25" level="project" /> |  | ||||||
|   </component> |  | ||||||
| </module> |  | ||||||
							
								
								
									
										3
									
								
								Plugin Plant/plugin.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								Plugin Plant/plugin.properties
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | classpath=net.simon987.plantplugin.PlantPlugin | ||||||
|  | name=Plant Plugin | ||||||
|  | version=1.0 | ||||||
| @ -1,30 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="UTF-8"?> |  | ||||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" |  | ||||||
|          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |  | ||||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |  | ||||||
|     <modelVersion>4.0.0</modelVersion> |  | ||||||
| 
 |  | ||||||
|     <parent> |  | ||||||
|         <groupId>net.simon987.server</groupId> |  | ||||||
|         <artifactId>server_root</artifactId> |  | ||||||
|         <version>1.4a</version> |  | ||||||
|     </parent> |  | ||||||
| 
 |  | ||||||
|     <groupId>net.simon987.pluginplant</groupId> |  | ||||||
|     <artifactId>plugin-biomassBlob</artifactId> |  | ||||||
|     <version>1.4a</version> |  | ||||||
| 
 |  | ||||||
|     <dependencies> |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>com.googlecode.json-simple</groupId> |  | ||||||
|             <artifactId>json-simple</artifactId> |  | ||||||
|             <version>1.1.1</version> |  | ||||||
|         </dependency> |  | ||||||
| 
 |  | ||||||
|         <dependency> |  | ||||||
|             <groupId>net.simon987.server</groupId> |  | ||||||
|             <artifactId>server</artifactId> |  | ||||||
|             <version>1.4a</version> |  | ||||||
|         </dependency> |  | ||||||
|     </dependencies> |  | ||||||
| </project> |  | ||||||
| @ -1,94 +0,0 @@ | |||||||
| package net.simon987.biomassplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.game.item.Item; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import net.simon987.server.game.objects.InventoryHolder; |  | ||||||
| import org.bson.Document; |  | ||||||
| import org.json.simple.JSONObject; |  | ||||||
| 
 |  | ||||||
| public class BiomassBlob extends GameObject implements InventoryHolder { |  | ||||||
| 
 |  | ||||||
|     private static final char MAP_INFO = 0x0101; |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Yield of the blob, in biomass units |  | ||||||
|      */ |  | ||||||
|     private int biomassCount; |  | ||||||
| 
 |  | ||||||
|     public BiomassBlob() { |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public BiomassBlob(Document document) { |  | ||||||
|         super(document); |  | ||||||
| 
 |  | ||||||
|         biomassCount = document.getInteger("biomassCount"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char getMapInfo() { |  | ||||||
|         return MAP_INFO; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public JSONObject jsonSerialise() { |  | ||||||
| 
 |  | ||||||
|         JSONObject json = super.jsonSerialise(); |  | ||||||
| 
 |  | ||||||
|         json.put("b", biomassCount); |  | ||||||
| 
 |  | ||||||
|         return json; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Document mongoSerialise() { |  | ||||||
| 
 |  | ||||||
|         Document dbObject = super.mongoSerialise(); |  | ||||||
| 
 |  | ||||||
|         dbObject.put("biomassCount", biomassCount); |  | ||||||
| 
 |  | ||||||
|         return dbObject; |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public int getBiomassCount() { |  | ||||||
|         return biomassCount; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setBiomassCount(int biomassCount) { |  | ||||||
|         this.biomassCount = biomassCount; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Called when an object attempts to place an item in this BiomassBlob |  | ||||||
|      * |  | ||||||
|      * @return Always returns false |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public boolean placeItem(Item item) { |  | ||||||
|         //Why would you want to place an item in a blob? |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public boolean canTakeItem(int itemId) { |  | ||||||
|         return itemId == ItemBiomass.ID && biomassCount >= 1; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Called when an object attempts to take an item from this BiomassBlob. |  | ||||||
|      * If the object requests biomass, it will be subtracted from biomassCount, and |  | ||||||
|      * if it reaches 0, the plant is deleted |  | ||||||
|      */ |  | ||||||
|     @Override |  | ||||||
|     public void takeItem(int itemId) { |  | ||||||
| 
 |  | ||||||
|         if (itemId == ItemBiomass.ID) { |  | ||||||
|             if (biomassCount > 1) { |  | ||||||
|                 biomassCount--; |  | ||||||
|             } else { |  | ||||||
|                 //Delete plant |  | ||||||
|                 setDead(true); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,31 +0,0 @@ | |||||||
| package net.simon987.biomassplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.biomassplugin.event.ObjectDeathListener; |  | ||||||
| import net.simon987.biomassplugin.event.WorldCreationListener; |  | ||||||
| import net.simon987.biomassplugin.event.WorldUpdateListener; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.IServerConfiguration; |  | ||||||
| import net.simon987.server.game.objects.GameRegistry; |  | ||||||
| import net.simon987.server.logging.LogManager; |  | ||||||
| import net.simon987.server.plugin.ServerPlugin; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| public class BiomassPlugin extends ServerPlugin { |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void init(GameServer gameServer) { |  | ||||||
| 
 |  | ||||||
|         IServerConfiguration config = gameServer.getConfig(); |  | ||||||
|         GameRegistry registry = gameServer.getRegistry(); |  | ||||||
| 
 |  | ||||||
|         listeners.add(new WorldCreationListener()); |  | ||||||
|         listeners.add(new WorldUpdateListener(config)); |  | ||||||
|         listeners.add(new ObjectDeathListener(config)); |  | ||||||
| 
 |  | ||||||
|         registry.registerGameObject(BiomassBlob.class); |  | ||||||
|         registry.registerItem(ItemBiomass.ID, ItemBiomass.class); |  | ||||||
| 
 |  | ||||||
|         LogManager.LOGGER.info("(BiomassPlugin) Initialised Biomass plugin"); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,39 +0,0 @@ | |||||||
| package net.simon987.biomassplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.game.item.Item; |  | ||||||
| import net.simon987.server.game.objects.ControllableUnit; |  | ||||||
| import net.simon987.server.game.objects.Rechargeable; |  | ||||||
| import org.bson.Document; |  | ||||||
| 
 |  | ||||||
| public class ItemBiomass extends Item { |  | ||||||
| 
 |  | ||||||
|     public static final int ID = 0x0001; |  | ||||||
| 
 |  | ||||||
|     private static final int energy = GameServer.INSTANCE.getConfig().getInt("biomassEnergyValue"); |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public int getId() { |  | ||||||
|         return ID; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public ItemBiomass() { |  | ||||||
|         super(null); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public ItemBiomass(Document document) { |  | ||||||
|         super(document); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void clear(ControllableUnit unit) { |  | ||||||
|         if (unit instanceof Rechargeable) { |  | ||||||
|             ((Rechargeable) unit).storeEnergy(energy); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public char poll() { |  | ||||||
|         return ID; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,78 +0,0 @@ | |||||||
| package net.simon987.biomassplugin; |  | ||||||
| 
 |  | ||||||
| import net.simon987.server.game.world.TileMap; |  | ||||||
| import net.simon987.server.game.world.TilePlain; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| import org.bson.types.ObjectId; |  | ||||||
| 
 |  | ||||||
| import java.awt.*; |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.Random; |  | ||||||
| 
 |  | ||||||
| public class WorldUtils { |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Generate a list of biomass blobs for a world |  | ||||||
|      */ |  | ||||||
|     public static ArrayList<BiomassBlob> generateBlobs(World world, int minCount, int maxCount, int yield) { |  | ||||||
| 
 |  | ||||||
|         Random random = new Random(); |  | ||||||
|         int blobCount = random.nextInt(maxCount - minCount) + minCount; |  | ||||||
|         ArrayList<BiomassBlob> biomassBlobs = new ArrayList<>(blobCount); |  | ||||||
| 
 |  | ||||||
|         //Count number of plain tiles. If there is less plain tiles than desired amount of blobs, |  | ||||||
|         //set the desired amount of blobs to the plain tile count |  | ||||||
|         TileMap m = world.getTileMap(); |  | ||||||
|         int plainCount = 0; |  | ||||||
|         for (int y = 0; y < world.getWorldSize(); y++) { |  | ||||||
|             for (int x = 0; x < world.getWorldSize(); x++) { |  | ||||||
| 
 |  | ||||||
|                 if (m.getTileIdAt(x, y) == TilePlain.ID) { |  | ||||||
|                     plainCount++; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         if (blobCount > plainCount) { |  | ||||||
|             blobCount = plainCount; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         outerLoop: |  | ||||||
|         for (int i = 0; i < blobCount; i++) { |  | ||||||
| 
 |  | ||||||
|             Point p = m.getRandomTile(TilePlain.ID); |  | ||||||
|             if (p != null) { |  | ||||||
| 
 |  | ||||||
|                 //Don't block worlds |  | ||||||
|                 int counter = 0; |  | ||||||
|                 while (p.x == 0 || p.y == 0 || p.x == world.getWorldSize() - 1 || p.y == world.getWorldSize() - 1 || |  | ||||||
|                         world.getGameObjectsAt(p.x, p.y).size() != 0) { |  | ||||||
|                     p = m.getRandomTile(TilePlain.ID); |  | ||||||
|                     counter++; |  | ||||||
| 
 |  | ||||||
|                     if (counter > 25) { |  | ||||||
|                         continue outerLoop; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 for (BiomassBlob biomassBlob : biomassBlobs) { |  | ||||||
|                     if (biomassBlob.getX() == p.x && biomassBlob.getY() == p.y) { |  | ||||||
|                         //There is already a blob here |  | ||||||
|                         continue outerLoop; |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
| 
 |  | ||||||
|                 BiomassBlob biomassBlob = new BiomassBlob(); |  | ||||||
|                 biomassBlob.setObjectId(new ObjectId()); |  | ||||||
|                 biomassBlob.setBiomassCount(yield); |  | ||||||
|                 biomassBlob.setX(p.x); |  | ||||||
|                 biomassBlob.setY(p.y); |  | ||||||
|                 biomassBlob.setWorld(world); |  | ||||||
| 
 |  | ||||||
|                 biomassBlobs.add(biomassBlob); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         return biomassBlobs; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,65 +0,0 @@ | |||||||
| package net.simon987.biomassplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.biomassplugin.BiomassBlob; |  | ||||||
| import net.simon987.server.IServerConfiguration; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.event.ObjectDeathEvent; |  | ||||||
| import net.simon987.server.game.objects.GameObject; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| import org.bson.types.ObjectId; |  | ||||||
| 
 |  | ||||||
| /** |  | ||||||
|  * Handles ObjectDeathEvent events |  | ||||||
|  */ |  | ||||||
| public class ObjectDeathListener implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     private int biomassDropCount; |  | ||||||
| 
 |  | ||||||
|     public ObjectDeathListener(IServerConfiguration config) { |  | ||||||
|         biomassDropCount = config.getInt("harvester_biomass_drop_count"); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return ObjectDeathEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         if (event.getSource().getClass().getCanonicalName().equals("net.simon987.npcplugin.HarvesterNPC")) { |  | ||||||
|             //An HarvesterNPC ObjectDeathEvent is received |  | ||||||
|             GameObject dyingHarvesterNPC = (GameObject)event.getSource(); |  | ||||||
| 
 |  | ||||||
|             //Don't spawn biomass on World border |  | ||||||
|             if (dyingHarvesterNPC.getX() != 0 && dyingHarvesterNPC.getX() != dyingHarvesterNPC.getWorld().getWorldSize() - 1 && |  | ||||||
|                     dyingHarvesterNPC.getY() != 0 && dyingHarvesterNPC.getY() != dyingHarvesterNPC.getWorld().getWorldSize() - 1) { |  | ||||||
|                 //Create a new biomass |  | ||||||
|                 BiomassBlob newBiomassBlob = createBiomassBlobAt( |  | ||||||
|                         dyingHarvesterNPC.getX(), dyingHarvesterNPC.getY(), dyingHarvesterNPC.getWorld()); |  | ||||||
|                 //Add it to the world game objects |  | ||||||
|                 dyingHarvesterNPC.getWorld().addObject(newBiomassBlob); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     /** |  | ||||||
|      * Create and return a biomass at the given x, y coordinates and in the world |  | ||||||
|      * @param x x coord of biomass location |  | ||||||
|      * @param y y coord of biomass location |  | ||||||
|      * @param world world in which the biomass will be created in |  | ||||||
|      * @return the new BiomassBlob created |  | ||||||
|      */ |  | ||||||
|     private BiomassBlob createBiomassBlobAt(int x, int y, World world) { |  | ||||||
| 
 |  | ||||||
|         BiomassBlob biomassBlob = new BiomassBlob(); |  | ||||||
|         biomassBlob.setObjectId(new ObjectId()); |  | ||||||
|         biomassBlob.setBiomassCount(biomassDropCount); |  | ||||||
|         biomassBlob.setX(x); |  | ||||||
|         biomassBlob.setY(y); |  | ||||||
|         biomassBlob.setWorld(world); |  | ||||||
| 
 |  | ||||||
|         return biomassBlob; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,33 +0,0 @@ | |||||||
| package net.simon987.biomassplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.biomassplugin.BiomassBlob; |  | ||||||
| import net.simon987.biomassplugin.WorldUtils; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.event.WorldGenerationEvent; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| 
 |  | ||||||
| public class WorldCreationListener implements GameEventListener { |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return WorldGenerationEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         int minCount = GameServer.INSTANCE.getConfig().getInt("minBiomassCount"); |  | ||||||
|         int maxCount = GameServer.INSTANCE.getConfig().getInt("maxBiomassCount"); |  | ||||||
|         int yield = GameServer.INSTANCE.getConfig().getInt("biomass_yield"); |  | ||||||
| 
 |  | ||||||
|         ArrayList<BiomassBlob> biomassBlobs = WorldUtils.generateBlobs(((WorldGenerationEvent) event).getWorld(), |  | ||||||
|                 minCount, maxCount, yield); |  | ||||||
| 
 |  | ||||||
|         for (BiomassBlob blob : biomassBlobs) { |  | ||||||
|             ((WorldGenerationEvent) event).getWorld().addObject(blob); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,75 +0,0 @@ | |||||||
| package net.simon987.biomassplugin.event; |  | ||||||
| 
 |  | ||||||
| import net.simon987.biomassplugin.BiomassBlob; |  | ||||||
| import net.simon987.biomassplugin.WorldUtils; |  | ||||||
| import net.simon987.server.GameServer; |  | ||||||
| import net.simon987.server.IServerConfiguration; |  | ||||||
| import net.simon987.server.event.GameEvent; |  | ||||||
| import net.simon987.server.event.GameEventListener; |  | ||||||
| import net.simon987.server.event.WorldUpdateEvent; |  | ||||||
| import net.simon987.server.game.world.World; |  | ||||||
| 
 |  | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.HashMap; |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| public class WorldUpdateListener implements GameEventListener { |  | ||||||
| 
 |  | ||||||
|     private HashMap<World, Long> worldWaitMap = new HashMap<>(200); |  | ||||||
| 
 |  | ||||||
|     private static int minBlobCount; |  | ||||||
|     private static int maxBlobCount; |  | ||||||
|     private static int blobYield; |  | ||||||
|     private static int waitTime; |  | ||||||
|     private static int blobThreshold; |  | ||||||
| 
 |  | ||||||
|     public WorldUpdateListener(IServerConfiguration config) { |  | ||||||
| 
 |  | ||||||
|         minBlobCount = config.getInt("minBiomassRespawnCount"); |  | ||||||
|         maxBlobCount = config.getInt("maxBiomassRespawnCount"); |  | ||||||
|         waitTime = config.getInt("biomassRespawnTime"); |  | ||||||
|         blobThreshold = config.getInt("biomassRespawnThreshold"); |  | ||||||
|         blobYield = config.getInt("biomass_yield"); |  | ||||||
| 
 |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public Class getListenedEventType() { |  | ||||||
|         return WorldUpdateEvent.class; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public void handle(GameEvent event) { |  | ||||||
| 
 |  | ||||||
|         World world = ((WorldUpdateEvent) event).getWorld(); |  | ||||||
| 
 |  | ||||||
|         if (world.getDimension().startsWith("w")) { |  | ||||||
|             //If there is less than the respawn threshold, |  | ||||||
|             if (world.findObjects(BiomassBlob.class).size() < blobThreshold) { |  | ||||||
| 
 |  | ||||||
|                 //Set a timer for respawn_time ticks |  | ||||||
|                 if (!worldWaitMap.containsKey(world) || worldWaitMap.get(world) == 0L) { |  | ||||||
|                     worldWaitMap.put(world, GameServer.INSTANCE.getGameUniverse().getTime() + waitTime); |  | ||||||
|                 } else { |  | ||||||
| 
 |  | ||||||
|                     long waitUntil = worldWaitMap.get(world); |  | ||||||
| 
 |  | ||||||
|                     if (GameServer.INSTANCE.getGameUniverse().getTime() >= waitUntil) { |  | ||||||
| 
 |  | ||||||
|                         //If the timer was set less than respawn_time ticks ago, respawn the blobs |  | ||||||
|                         ArrayList<BiomassBlob> newBlobs = WorldUtils.generateBlobs(world, minBlobCount, |  | ||||||
|                                 maxBlobCount, blobYield); |  | ||||||
|                         for (BiomassBlob blob : newBlobs) { |  | ||||||
|                             world.addObject(blob); |  | ||||||
|                             world.incUpdatable(); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         //Set the 'waitUntil' time to 0 to indicate that we are not waiting |  | ||||||
|                         worldWaitMap.replace(world, 0L); |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @ -1,4 +0,0 @@ | |||||||
| classpath=net.simon987.biomassplugin.BiomassPlugin |  | ||||||
| name=Biomass Plugin |  | ||||||
| version=1.0 |  | ||||||
| depend=NPC Plugin |  | ||||||
							
								
								
									
										162
									
								
								Plugin Plant/src/net/simon987/plantplugin/Plant.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								Plugin Plant/src/net/simon987/plantplugin/Plant.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,162 @@ | |||||||
|  | package net.simon987.plantplugin; | ||||||
|  | 
 | ||||||
|  | import net.simon987.server.GameServer; | ||||||
|  | import net.simon987.server.game.GameObject; | ||||||
|  | import net.simon987.server.game.InventoryHolder; | ||||||
|  | import net.simon987.server.game.Updatable; | ||||||
|  | import org.json.simple.JSONObject; | ||||||
|  | 
 | ||||||
|  | public class Plant extends GameObject implements Updatable, InventoryHolder{ | ||||||
|  | 
 | ||||||
|  |     private static final char MAP_INFO = 0x4000; | ||||||
|  |     public static final int ID = 2; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Grow time (see config.properties) | ||||||
|  |      */ | ||||||
|  |     private static final int GROW_TIME = GameServer.INSTANCE.getConfig().getInt("plant_grow_time"); | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Game time of the creation of this Plant | ||||||
|  |      */ | ||||||
|  |     private long creationTime; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Whether the plant is grown or not | ||||||
|  |      */ | ||||||
|  |     private boolean grown; | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Yield of the plant, in biomass units | ||||||
|  |      */ | ||||||
|  |     private int biomassCount; | ||||||
|  |     /** | ||||||
|  |      * Style of the plant (Only visual) | ||||||
|  |      */ | ||||||
|  |     private int style; | ||||||
|  | 
 | ||||||
|  |     private static final int ITM_BIOMASS = 1; | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public char getMapInfo() { | ||||||
|  |         return MAP_INFO; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public JSONObject serialise() { | ||||||
|  | 
 | ||||||
|  |         JSONObject json = new JSONObject(); | ||||||
|  | 
 | ||||||
|  |         json.put("type", ID); | ||||||
|  |         json.put("id", getObjectId()); | ||||||
|  |         json.put("x", getX()); | ||||||
|  |         json.put("y", getY()); | ||||||
|  |         json.put("creationTime", creationTime); | ||||||
|  |         json.put("grown", grown); | ||||||
|  |         json.put("biomassCount", biomassCount); | ||||||
|  |         json.put("style", style); | ||||||
|  | 
 | ||||||
|  |         return json; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Called every tick | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public void update() { | ||||||
|  |         if (!grown) { | ||||||
|  |             //Check grow | ||||||
|  |             if (creationTime + GROW_TIME <= GameServer.INSTANCE.getGameUniverse().getTime()) { | ||||||
|  |                 grown = true; | ||||||
|  |                 biomassCount = GameServer.INSTANCE.getConfig().getInt("plant_yield"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public long getCreationTime() { | ||||||
|  |         return creationTime; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setCreationTime(long creationTime) { | ||||||
|  |         this.creationTime = creationTime; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public boolean isGrown() { | ||||||
|  |         return grown; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setGrown(boolean grown) { | ||||||
|  |         this.grown = grown; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public int getBiomassCount() { | ||||||
|  |         return biomassCount; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setBiomassCount(int biomassCount) { | ||||||
|  |         this.biomassCount = biomassCount; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public int getStyle() { | ||||||
|  |         return style; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setStyle(int style) { | ||||||
|  |         this.style = style; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public static Plant deserialize(JSONObject json){ | ||||||
|  | 
 | ||||||
|  |         Plant plant = new Plant(); | ||||||
|  | 
 | ||||||
|  |         plant.setObjectId((int)(long)json.get("id")); | ||||||
|  |         plant.setX((int)(long)json.get("x")); | ||||||
|  |         plant.setY((int)(long)json.get("y")); | ||||||
|  |         plant.grown = (boolean)json.get("grown"); | ||||||
|  |         plant.creationTime = (long)json.get("creationTime"); | ||||||
|  |         plant.style = (int)(long)json.get("style"); | ||||||
|  |         plant.biomassCount = (int)(long)json.get("biomassCount"); | ||||||
|  | 
 | ||||||
|  |         return plant; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Called when an object attempts to place an item in this Plant | ||||||
|  |      * | ||||||
|  |      * @param item item id (see MarConstants.ITEM_*) | ||||||
|  |      * @return Always returns false | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public boolean placeItem(int item) { | ||||||
|  |         //Why would you want to place an item in a plant? | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Called when an object attempts to take an item from this Plant. | ||||||
|  |      * If the object requests biomass, it will be subtracted from biomassCount, and | ||||||
|  |      * if it reaches 0, the plant is deleted | ||||||
|  |      * | ||||||
|  |      * @param item item id (see MarConstants.ITEM_*) | ||||||
|  |      * @return true if the requested item is ITEM_BIOMASS and if the plant is grown | ||||||
|  |      */ | ||||||
|  |     @Override | ||||||
|  |     public boolean takeItem(int item) { | ||||||
|  | 
 | ||||||
|  |         if (item == ITM_BIOMASS) { | ||||||
|  |             if (grown && biomassCount > 1) { | ||||||
|  |                 biomassCount--; | ||||||
|  |                 return true; | ||||||
|  |             } else if (grown) { | ||||||
|  |                 //Delete plant | ||||||
|  |                 setDead(true); | ||||||
|  |                 return true; | ||||||
|  |             } else { | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user