Merge branch 'master' of git://github.com/peterix/dfhack
						commit
						0cf3ee3dc6
					
				@ -1,96 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
https://github.com/peterix/dfhack
 | 
					 | 
				
			||||||
Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
This software is provided 'as-is', without any express or implied
 | 
					 | 
				
			||||||
warranty. In no event will the authors be held liable for any
 | 
					 | 
				
			||||||
damages arising from the use of this software.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Permission is granted to anyone to use this software for any
 | 
					 | 
				
			||||||
purpose, including commercial applications, and to alter it and
 | 
					 | 
				
			||||||
redistribute it freely, subject to the following restrictions:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
1. The origin of this software must not be misrepresented; you must
 | 
					 | 
				
			||||||
not claim that you wrote the original software. If you use this
 | 
					 | 
				
			||||||
software in a product, an acknowledgment in the product documentation
 | 
					 | 
				
			||||||
would be appreciated but is not required.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
2. Altered source versions must be plainly marked as such, and
 | 
					 | 
				
			||||||
must not be misrepresented as being the original software.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
3. This notice may not be removed or altered from any source
 | 
					 | 
				
			||||||
distribution.
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef DFVECTOR_H_INCLUDED
 | 
					 | 
				
			||||||
#define DFVECTOR_H_INCLUDED
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "Pragma.h"
 | 
					 | 
				
			||||||
#include "Export.h"
 | 
					 | 
				
			||||||
#include "VersionInfo.h"
 | 
					 | 
				
			||||||
#include "MemAccess.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace DFHack
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    template <class T>
 | 
					 | 
				
			||||||
    class DFHACK_EXPORT DfVector
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        private:
 | 
					 | 
				
			||||||
            std::vector<T> * real_vec;
 | 
					 | 
				
			||||||
        public:
 | 
					 | 
				
			||||||
            DfVector(uint32_t address)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                real_vec = (std::vector<T> *) address;
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            ~DfVector()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            // get offset of the specified index
 | 
					 | 
				
			||||||
            inline const T& operator[] (uint32_t index)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // FIXME: vector out of bounds exception
 | 
					 | 
				
			||||||
                //assert(index < size);
 | 
					 | 
				
			||||||
                return real_vec->at(index);
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            // get offset of the specified index
 | 
					 | 
				
			||||||
            inline const T& at (uint32_t index)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                //assert(index < size);
 | 
					 | 
				
			||||||
                return real_vec->at(index);
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            // update value at index
 | 
					 | 
				
			||||||
            bool set(uint32_t index, T value)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (index >= real_vec->size())
 | 
					 | 
				
			||||||
                    return false;
 | 
					 | 
				
			||||||
                real_vec->at(index) = value;
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            // remove value
 | 
					 | 
				
			||||||
            bool remove(uint32_t index)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if (index >= real_vec->size())
 | 
					 | 
				
			||||||
                    return false;
 | 
					 | 
				
			||||||
                // Remove the item
 | 
					 | 
				
			||||||
                real_vec->erase(real_vec->begin() + index);
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            // get vector size
 | 
					 | 
				
			||||||
            inline uint32_t size ()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return real_vec->size();
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
            // get vector start
 | 
					 | 
				
			||||||
            inline const T * start ()
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                return real_vec->data();
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif // DFVECTOR_H_INCLUDED
 | 
					 | 
				
			||||||
@ -1,3 +1,3 @@
 | 
				
			|||||||
*.h
 | 
					*.h
 | 
				
			||||||
*.inc
 | 
					static*.inc
 | 
				
			||||||
*.xml
 | 
					*.xml
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,45 @@
 | 
				
			|||||||
 | 
					coord(const coord2d &c, uint16_t _z) : x(c.x), y(c.y), z(_z) {}
 | 
				
			||||||
 | 
					coord(uint16_t _x, uint16_t _y, uint16_t _z) : x(_x), y(_y), z(_z) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					operator coord2d() const { return coord2d(x,y); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool isValid() const { return x != -30000; }
 | 
				
			||||||
 | 
					void clear() { x = y = z = -30000; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool operator==(const coord &other) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (x == other.x) && (y == other.y) && (z == other.z);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool operator!=(const coord &other) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (x != other.x) || (y != other.y) || (z != other.z);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool operator<(const coord &other) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (x != other.x) return (x < other.x);
 | 
				
			||||||
 | 
					    if (y != other.y) return (y < other.y);
 | 
				
			||||||
 | 
					    return z < other.z;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					coord operator/(int number) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return coord(x/number, y/number, z);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					coord operator*(int number) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return coord(x*number, y*number, z);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					coord operator%(int number) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return coord(x%number, y%number, z);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					coord operator-(int number) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return coord(x,y,z-number);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					coord operator+(int number) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return coord(x,y,z+number);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,32 @@
 | 
				
			|||||||
 | 
					coord2d(uint16_t _x, uint16_t _y) : x(_x), y(_y) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool isValid() const { return x != -30000; }
 | 
				
			||||||
 | 
					void clear() { x = y = -30000; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool operator==(const coord2d &other) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (x == other.x) && (y == other.y);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					bool operator!=(const coord2d &other) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (x != other.x) || (y != other.y);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool operator<(const coord2d &other) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (x != other.x) return (x < other.x);
 | 
				
			||||||
 | 
					    return y < other.y;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					coord2d operator/(int number) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return coord2d(x/number, y/number);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					coord2d operator*(int number) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return coord2d(x*number, y*number);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					coord2d operator%(int number) const
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return coord2d(x%number, y%number);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					unsigned size() const { return x.size(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					coord operator[] (unsigned idx) const {
 | 
				
			||||||
 | 
					    if (idx >= x.size() || idx >= y.size() || idx >= z.size())
 | 
				
			||||||
 | 
					        return coord();
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return coord(x[idx], y[idx], z[idx]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					/*
 | 
				
			||||||
 | 
					https://github.com/peterix/dfhack
 | 
				
			||||||
 | 
					Copyright (c) 2009-2011 Petr Mrázek (peterix@gmail.com)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This software is provided 'as-is', without any express or implied
 | 
				
			||||||
 | 
					warranty. In no event will the authors be held liable for any
 | 
				
			||||||
 | 
					damages arising from the use of this software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Permission is granted to anyone to use this software for any
 | 
				
			||||||
 | 
					purpose, including commercial applications, and to alter it and
 | 
				
			||||||
 | 
					redistribute it freely, subject to the following restrictions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. The origin of this software must not be misrepresented; you must
 | 
				
			||||||
 | 
					not claim that you wrote the original software. If you use this
 | 
				
			||||||
 | 
					software in a product, an acknowledgment in the product documentation
 | 
				
			||||||
 | 
					would be appreciated but is not required.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Altered source versions must be plainly marked as such, and
 | 
				
			||||||
 | 
					must not be misrepresented as being the original software.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. This notice may not be removed or altered from any source
 | 
				
			||||||
 | 
					distribution.
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#ifndef CL_MOD_JOB
 | 
				
			||||||
 | 
					#define CL_MOD_JOB
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Export.h"
 | 
				
			||||||
 | 
					#include "Module.h"
 | 
				
			||||||
 | 
					#include <ostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace df
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    struct job;
 | 
				
			||||||
 | 
					    struct job_item;
 | 
				
			||||||
 | 
					    struct job_item_filter;
 | 
				
			||||||
 | 
					    struct building;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace DFHack
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // Duplicate the job structure. It is not linked into any DF lists.
 | 
				
			||||||
 | 
					    DFHACK_EXPORT df::job *cloneJobStruct(df::job *job);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Delete a cloned structure.
 | 
				
			||||||
 | 
					    DFHACK_EXPORT void deleteJobStruct(df::job *job);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DFHACK_EXPORT bool operator== (const df::job_item &a, const df::job_item &b);
 | 
				
			||||||
 | 
					    DFHACK_EXPORT bool operator== (const df::job &a, const df::job &b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DFHACK_EXPORT void printJobDetails(Core *c, df::job *job);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DFHACK_EXPORT df::building *getJobHolder(df::job *job);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    DFHACK_EXPORT bool linkJobIntoWorld(df::job *job, bool new_id = true);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1,86 +1,38 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
#ifndef CL_MOD_VERMIN
 | 
					 | 
				
			||||||
#define CL_MOD_VERMIN
 | 
					 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * \defgroup grp_vermin Wild vermin (ants, bees, etc)
 | 
					 * \defgroup grp_vermin Wild vermin (ants, bees, etc)
 | 
				
			||||||
 * @ingroup grp_vermin
 | 
					 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#include "Export.h"
 | 
					#include "Export.h"
 | 
				
			||||||
#include "Module.h"
 | 
					namespace DFHack { namespace Simple { namespace Vermin
 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef __cplusplus
 | 
					 | 
				
			||||||
namespace DFHack
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Structure for holding a read DF vermin spawn point object
 | 
					     * Structure for holding a read DF vermin spawn point object
 | 
				
			||||||
     * \ingroup grp_vermin
 | 
					     * \ingroup grp_vermin
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    struct t_spawnPoint
 | 
					    struct t_vermin
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint32_t origin;
 | 
					        void * origin;
 | 
				
			||||||
        int16_t race;
 | 
					        int16_t race;
 | 
				
			||||||
        uint16_t type;
 | 
					        int16_t caste;
 | 
				
			||||||
        uint16_t x;
 | 
					        uint16_t x;
 | 
				
			||||||
        uint16_t y;
 | 
					        uint16_t y;
 | 
				
			||||||
        uint16_t z;
 | 
					        uint16_t z;
 | 
				
			||||||
        bool     in_use;
 | 
					 | 
				
			||||||
        uint8_t  unknown;
 | 
					 | 
				
			||||||
        uint32_t countdown;
 | 
					        uint32_t countdown;
 | 
				
			||||||
 | 
					        bool visible:1;
 | 
				
			||||||
 | 
					        bool is_colony:1; /// Is vermin object a colony?
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					    static const uint16_t TYPE_WILD_COLONY = 0xFFFF;
 | 
				
			||||||
    class DFContextShared;
 | 
					 | 
				
			||||||
    class SpawnPoints;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * The Vermin module - allows reading DF vermin
 | 
					     * Get number of vermin objects
 | 
				
			||||||
     * \ingroup grp_modules
 | 
					 | 
				
			||||||
     * \ingroup grp_vermin
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    class DFHACK_EXPORT Vermin : public Module
 | 
					    DFHACK_EXPORT uint32_t getNumVermin();
 | 
				
			||||||
    {
 | 
					    /**
 | 
				
			||||||
        public:
 | 
					     * Read from vermin object
 | 
				
			||||||
        Vermin();
 | 
					     */
 | 
				
			||||||
        ~Vermin();
 | 
					    DFHACK_EXPORT bool Read (const uint32_t index, t_vermin & point);
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
        bool Finish();
 | 
					     * Write into vermin object
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
        // NOTE: caller must call delete on result when done.
 | 
					    DFHACK_EXPORT bool Write (const uint32_t index, t_vermin & point);
 | 
				
			||||||
        SpawnPoints* getSpawnPoints();
 | 
					} } } // end DFHack::Simple::Vermin
 | 
				
			||||||
 | 
					 | 
				
			||||||
        private:
 | 
					 | 
				
			||||||
        struct Private;
 | 
					 | 
				
			||||||
        Private *d;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        friend class SpawnPoints;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class DFHACK_EXPORT SpawnPoints
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        static const uint16_t TYPE_WILD_COLONY = 0xFFFF;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected:
 | 
					 | 
				
			||||||
        SpawnPoints(Vermin * v);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        ~SpawnPoints();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        size_t size();
 | 
					 | 
				
			||||||
        bool   Read (const uint32_t index, t_spawnPoint & point);
 | 
					 | 
				
			||||||
        bool   Write (const uint32_t index, t_spawnPoint & point);
 | 
					 | 
				
			||||||
        bool   isValid();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static bool isWildColony(t_spawnPoint & point);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
        Vermin* v;
 | 
					 | 
				
			||||||
        std::vector <void*> * p_sp;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        friend class Vermin;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
#endif // __cplusplus
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -1 +1 @@
 | 
				
			|||||||
Subproject commit 7a730830c515fea701ff73b33cb604f48a4531fc
 | 
					Subproject commit d5abec61f72f113e023219fed19c4022363de953
 | 
				
			||||||
@ -1 +1 @@
 | 
				
			|||||||
Subproject commit 355674a508d72349983455f04791b4481b6c1515
 | 
					Subproject commit c114ec5f995aec69631187212254309464f82775
 | 
				
			||||||
@ -1,76 +1,56 @@
 | 
				
			|||||||
// Dry Buckets : Remove all "water" objects from buckets scattered around the fortress
 | 
					// Dry Buckets : Remove all "water" objects from buckets scattered around the fortress
 | 
				
			||||||
#include <iostream>
 | 
					 | 
				
			||||||
#include <iomanip>
 | 
					 | 
				
			||||||
#include <sstream>
 | 
					 | 
				
			||||||
#include <climits>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
#include <set>
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Core.h"
 | 
					#include "Core.h"
 | 
				
			||||||
#include <Console.h>
 | 
					#include "Console.h"
 | 
				
			||||||
#include <Export.h>
 | 
					#include "Export.h"
 | 
				
			||||||
#include <PluginManager.h>
 | 
					#include "PluginManager.h"
 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <algorithm>
 | 
					 | 
				
			||||||
#include <modules/Items.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "DataDefs.h"
 | 
				
			||||||
 | 
					#include "df/world.h"
 | 
				
			||||||
 | 
					#include "df/item.h"
 | 
				
			||||||
 | 
					#include "df/builtin_mats.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using std::string;
 | 
				
			||||||
 | 
					using std::vector;
 | 
				
			||||||
using namespace DFHack;
 | 
					using namespace DFHack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DFhackCExport command_result df_drybuckets (Core * c, vector <string> & parameters);
 | 
					using df::global::world;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DFhackCExport const char * plugin_name ( void )
 | 
					DFhackCExport command_result df_drybuckets (Core * c, vector <string> & parameters)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return "drybuckets";
 | 
						if (!parameters.empty())
 | 
				
			||||||
}
 | 
							return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
 | 
					        CoreSuspender suspend(c);
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	commands.clear();
 | 
					 | 
				
			||||||
	commands.push_back(PluginCommand("drybuckets", "Removes water from buckets.", df_drybuckets));
 | 
					 | 
				
			||||||
	return CR_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DFhackCExport command_result plugin_shutdown ( Core * c )
 | 
						int dried_total = 0;
 | 
				
			||||||
 | 
						for (int i = 0; i < world->items.all.size(); i++)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							df::item *item = world->items.all[i];
 | 
				
			||||||
 | 
							if ((item->getType() == df::item_type::LIQUID_MISC) && (item->getMaterial() == df::builtin_mats::WATER))
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								item->flags.bits.garbage_colect = 1;
 | 
				
			||||||
 | 
								dried_total++;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (dried_total)
 | 
				
			||||||
 | 
							c->con.print("Done. %d buckets of water marked for emptying.\n", dried_total);
 | 
				
			||||||
	return CR_OK;
 | 
						return CR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DFhackCExport command_result df_drybuckets (Core * c, vector <string> & parameters)
 | 
					DFhackCExport const char * plugin_name ( void )
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if(parameters.size() > 0)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		string & p = parameters[0];
 | 
					 | 
				
			||||||
		if(p == "?" || p == "help")
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
			c->con.print("This utility removes all objects of type LIQUID_MISC:NONE and material WATER:NONE - that is, water stored in buckets.\n");
 | 
						return "drybuckets";
 | 
				
			||||||
			return CR_OK;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
	c->Suspend();
 | 
					 | 
				
			||||||
	DFHack::Items * Items = c->getItems();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vector <df_item *> p_items;
 | 
					DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
 | 
				
			||||||
	if(!Items->readItemVector(p_items))
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
		c->con.printerr("Can't access the item vector.\n");
 | 
						commands.clear();
 | 
				
			||||||
		c->Resume();
 | 
						commands.push_back(PluginCommand("drybuckets", "Removes water from buckets.", df_drybuckets));
 | 
				
			||||||
		return CR_FAILURE;
 | 
						return CR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
	std::size_t numItems = p_items.size();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int dried_total = 0;
 | 
					DFhackCExport command_result plugin_shutdown ( Core * c )
 | 
				
			||||||
	for (std::size_t i = 0; i < numItems; i++)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		df_item *item = p_items[i];
 | 
					 | 
				
			||||||
		if ((item->getType() == Items::LIQUID_MISC) && (item->getMaterial() == Materials::WATER))
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
			item->flags.garbage_colect = 1;
 | 
					 | 
				
			||||||
			dried_total++;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	c->Resume();
 | 
					 | 
				
			||||||
	c->con.print("Done. %d buckets of water emptied.\n", dried_total);
 | 
					 | 
				
			||||||
	return CR_OK;
 | 
						return CR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,93 +1,75 @@
 | 
				
			|||||||
// This tool counts static tiles and active flows of water and magma.
 | 
					// This tool counts static tiles and active flows of water and magma.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <iostream>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
#include <map>
 | 
					 | 
				
			||||||
#include <stddef.h>
 | 
					 | 
				
			||||||
#include <string.h>
 | 
					 | 
				
			||||||
using namespace std;
 | 
					 | 
				
			||||||
#include "Core.h"
 | 
					#include "Core.h"
 | 
				
			||||||
#include <Console.h>
 | 
					#include "Console.h"
 | 
				
			||||||
#include <Export.h>
 | 
					#include "Export.h"
 | 
				
			||||||
#include <PluginManager.h>
 | 
					#include "PluginManager.h"
 | 
				
			||||||
#include <modules/Maps.h>
 | 
					 | 
				
			||||||
using namespace DFHack;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DFhackCExport command_result df_flows (Core * c, vector <string> & parameters);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DFhackCExport const char * plugin_name ( void )
 | 
					#include "DataDefs.h"
 | 
				
			||||||
{
 | 
					#include "df/world.h"
 | 
				
			||||||
    return "flows";
 | 
					#include "df/map_block.h"
 | 
				
			||||||
}
 | 
					#include "df/tile_liquid.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
 | 
					using std::string;
 | 
				
			||||||
{
 | 
					using std::vector;
 | 
				
			||||||
    commands.clear();
 | 
					using namespace DFHack;
 | 
				
			||||||
    commands.push_back(PluginCommand("flows",
 | 
					 | 
				
			||||||
                                     "Counts map blocks with flowing liquids.",
 | 
					 | 
				
			||||||
                                     df_flows));
 | 
					 | 
				
			||||||
    return CR_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DFhackCExport command_result plugin_shutdown ( Core * c )
 | 
					using df::global::world;
 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    return CR_OK;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
DFhackCExport command_result df_flows (Core * c, vector <string> & parameters)
 | 
					DFhackCExport command_result df_flows (Core * c, vector <string> & parameters)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uint32_t x_max,y_max,z_max;
 | 
					    CoreSuspender suspend(c);
 | 
				
			||||||
    DFHack::designations40d designations;
 | 
					 | 
				
			||||||
    DFHack::Maps *Maps;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    c->Suspend();
 | 
					    int flow1 = 0, flow2 = 0, flowboth = 0, water = 0, magma = 0;
 | 
				
			||||||
    Maps = c->getMaps();
 | 
					 | 
				
			||||||
    // init the map
 | 
					 | 
				
			||||||
    if(!Maps->Start())
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        c->con.printerr("Can't init map.\n");
 | 
					 | 
				
			||||||
        c->Resume();
 | 
					 | 
				
			||||||
        return CR_FAILURE;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    DFHack::t_blockflags bflags;
 | 
					 | 
				
			||||||
    Maps->getSize(x_max,y_max,z_max);
 | 
					 | 
				
			||||||
    // walk the map, count flowing tiles, magma, water
 | 
					 | 
				
			||||||
    uint32_t flow1=0, flow2=0, flowboth=0, water=0, magma=0;
 | 
					 | 
				
			||||||
    c->con.print("Counting flows and liquids ...\n");
 | 
					    c->con.print("Counting flows and liquids ...\n");
 | 
				
			||||||
    for(uint32_t x = 0; x< x_max;x++)
 | 
					
 | 
				
			||||||
    {
 | 
					    for (int i = 0; i < world->map.map_blocks.size(); i++)
 | 
				
			||||||
        for(uint32_t y = 0; y< y_max;y++)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            for(uint32_t z = 0; z< z_max;z++)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                if(Maps->getBlock(x,y,z))
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
                    Maps->ReadBlockFlags(x, y, z, bflags);
 | 
					        df::map_block *cur = world->map.map_blocks[i];
 | 
				
			||||||
                    Maps->ReadDesignations(x, y, z, &designations);
 | 
					        if (cur->flags.is_set(df::block_flags::UpdateLiquid))
 | 
				
			||||||
                    if (bflags.bits.liquid_1)
 | 
					 | 
				
			||||||
            flow1++;
 | 
					            flow1++;
 | 
				
			||||||
                    if (bflags.bits.liquid_2)
 | 
					        if (cur->flags.is_set(df::block_flags::UpdateLiquidTwice))
 | 
				
			||||||
            flow2++;
 | 
					            flow2++;
 | 
				
			||||||
                    if (bflags.bits.liquid_1 && bflags.bits.liquid_2)
 | 
					        if (cur->flags.is_set(df::block_flags::UpdateLiquid) && cur->flags.is_set(df::block_flags::UpdateLiquidTwice))
 | 
				
			||||||
            flowboth++;
 | 
					            flowboth++;
 | 
				
			||||||
                    for (uint32_t i = 0; i < 16;i++) for (uint32_t j = 0; j < 16;j++)
 | 
					        for (int x = 0; x < 16; x++)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
                        if (designations[i][j].bits.liquid_type == DFHack::liquid_magma)
 | 
					            for (int y = 0; y < 16; y++)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // only count tiles with actual liquid in them
 | 
				
			||||||
 | 
					                if (cur->designation[x][y].bits.flow_size == 0)
 | 
				
			||||||
 | 
					                    continue;
 | 
				
			||||||
 | 
					                if (cur->designation[x][y].bits.liquid_type == df::tile_liquid::Magma)
 | 
				
			||||||
                    magma++;
 | 
					                    magma++;
 | 
				
			||||||
                        if (designations[i][j].bits.liquid_type == DFHack::liquid_water)
 | 
					                if (cur->designation[x][y].bits.liquid_type == df::tile_liquid::Water)
 | 
				
			||||||
                    water++;
 | 
					                    water++;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    c->con.print("Blocks with liquid_1=true: %d\n", flow1);
 | 
				
			||||||
 | 
					    c->con.print("Blocks with liquid_2=true: %d\n", flow2);
 | 
				
			||||||
 | 
					    c->con.print("Blocks with both:          %d\n", flowboth);
 | 
				
			||||||
 | 
					    c->con.print("Water tiles:               %d\n", water);
 | 
				
			||||||
 | 
					    c->con.print("Magma tiles:               %d\n", magma);
 | 
				
			||||||
 | 
					    return CR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DFhackCExport const char * plugin_name ( void )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return "flows";
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    commands.clear();
 | 
				
			||||||
 | 
					    commands.push_back(PluginCommand("flows",
 | 
				
			||||||
 | 
					        "Counts map blocks with flowing liquids.",
 | 
				
			||||||
 | 
					        df_flows));
 | 
				
			||||||
 | 
					    return CR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
    c->con.print("Blocks with liquid_1=true: %d\n"
 | 
					
 | 
				
			||||||
                 "Blocks with liquid_2=true: %d\n"
 | 
					DFhackCExport command_result plugin_shutdown ( Core * c )
 | 
				
			||||||
                 "Blocks with both:          %d\n"
 | 
					{
 | 
				
			||||||
                 "Water tiles:               %d\n"
 | 
					 | 
				
			||||||
                 "Magma tiles:               %d\n"
 | 
					 | 
				
			||||||
                 ,flow1, flow2, flowboth, water, magma
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
    c->Resume();
 | 
					 | 
				
			||||||
    return CR_OK;
 | 
					    return CR_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,416 @@
 | 
				
			|||||||
 | 
					#include "Core.h"
 | 
				
			||||||
 | 
					#include "Console.h"
 | 
				
			||||||
 | 
					#include "Export.h"
 | 
				
			||||||
 | 
					#include "PluginManager.h"
 | 
				
			||||||
 | 
					#include "MiscUtils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "modules/Materials.h"
 | 
				
			||||||
 | 
					#include "modules/Items.h"
 | 
				
			||||||
 | 
					#include "modules/Gui.h"
 | 
				
			||||||
 | 
					#include "modules/Job.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "DataDefs.h"
 | 
				
			||||||
 | 
					#include "df/world.h"
 | 
				
			||||||
 | 
					#include "df/ui.h"
 | 
				
			||||||
 | 
					#include "df/ui_build_selector.h"
 | 
				
			||||||
 | 
					#include "df/ui_build_item_req.h"
 | 
				
			||||||
 | 
					#include "df/build_req_choice_genst.h"
 | 
				
			||||||
 | 
					#include "df/build_req_choice_specst.h"
 | 
				
			||||||
 | 
					#include "df/building_workshopst.h"
 | 
				
			||||||
 | 
					#include "df/building_furnacest.h"
 | 
				
			||||||
 | 
					#include "df/job.h"
 | 
				
			||||||
 | 
					#include "df/job_item.h"
 | 
				
			||||||
 | 
					#include "df/job_list_link.h"
 | 
				
			||||||
 | 
					#include "df/item.h"
 | 
				
			||||||
 | 
					#include "df/tool_uses.h"
 | 
				
			||||||
 | 
					#include "df/general_ref.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using std::vector;
 | 
				
			||||||
 | 
					using std::string;
 | 
				
			||||||
 | 
					using std::endl;
 | 
				
			||||||
 | 
					using namespace DFHack;
 | 
				
			||||||
 | 
					using namespace df::enums;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using df::global::world;
 | 
				
			||||||
 | 
					using df::global::ui;
 | 
				
			||||||
 | 
					using df::global::ui_build_selector;
 | 
				
			||||||
 | 
					using df::global::ui_workshop_job_cursor;
 | 
				
			||||||
 | 
					using df::global::job_next_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Plugin registration */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool job_material_hotkey(Core *c, df::viewscreen *top);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static command_result job_material(Core *c, vector <string> & parameters);
 | 
				
			||||||
 | 
					static command_result job_duplicate(Core *c, vector <string> & parameters);
 | 
				
			||||||
 | 
					static command_result job_cmd(Core *c, vector <string> & parameters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DFhackCExport const char * plugin_name ( void )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return "jobutils";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DFhackCExport command_result plugin_init (Core *c, std::vector <PluginCommand> &commands)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    commands.clear();
 | 
				
			||||||
 | 
					    if (!world || !ui)
 | 
				
			||||||
 | 
					        return CR_FAILURE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    commands.push_back(
 | 
				
			||||||
 | 
					        PluginCommand(
 | 
				
			||||||
 | 
					            "job", "General job query and manipulation.",
 | 
				
			||||||
 | 
					            job_cmd, false,
 | 
				
			||||||
 | 
					            "  job [query]\n"
 | 
				
			||||||
 | 
					            "    Print details of the current job.\n"
 | 
				
			||||||
 | 
					            "  job list\n"
 | 
				
			||||||
 | 
					            "    Print details of all jobs in the workshop.\n"
 | 
				
			||||||
 | 
					            "  job item-material <item-idx> <material[:subtoken]>\n"
 | 
				
			||||||
 | 
					            "    Replace the exact material id in the job item.\n"
 | 
				
			||||||
 | 
					            "  job item-type <item-idx> <type[:subtype]>\n"
 | 
				
			||||||
 | 
					            "    Replace the exact item type id in the job item.\n"
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ui_workshop_job_cursor || ui_build_selector) {
 | 
				
			||||||
 | 
					        commands.push_back(
 | 
				
			||||||
 | 
					            PluginCommand(
 | 
				
			||||||
 | 
					                "job-material", "Alter the material of the selected job.",
 | 
				
			||||||
 | 
					                job_material, job_material_hotkey,
 | 
				
			||||||
 | 
					                "  job-material <inorganic-token>\n"
 | 
				
			||||||
 | 
					                "Intended to be used as a keybinding:\n"
 | 
				
			||||||
 | 
					                "  - In 'q' mode, when a job is highlighted within a workshop\n"
 | 
				
			||||||
 | 
					                "    or furnace, changes the material of the job.\n"
 | 
				
			||||||
 | 
					                "  - In 'b' mode, during selection of building components\n"
 | 
				
			||||||
 | 
					                "    positions the cursor over the first available choice\n"
 | 
				
			||||||
 | 
					                "    with the matching material.\n"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ui_workshop_job_cursor && job_next_id) {
 | 
				
			||||||
 | 
					        commands.push_back(
 | 
				
			||||||
 | 
					            PluginCommand(
 | 
				
			||||||
 | 
					                "job-duplicate", "Duplicate the selected job in a workshop.",
 | 
				
			||||||
 | 
					                job_duplicate, workshop_job_hotkey,
 | 
				
			||||||
 | 
					                "  - In 'q' mode, when a job is highlighted within a workshop\n"
 | 
				
			||||||
 | 
					                "    or furnace building, instantly duplicates the job.\n"
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return CR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DFhackCExport command_result plugin_shutdown ( Core * c )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return CR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* UI state guards */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool job_material_hotkey(Core *c, df::viewscreen *top)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return workshop_job_hotkey(c, top) ||
 | 
				
			||||||
 | 
					           build_selector_hotkey(c, top);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* job-material implementation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static command_result job_material_in_job(Core *c, MaterialInfo &new_mat)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    df::job *job = getSelectedWorkshopJob(c);
 | 
				
			||||||
 | 
					    if (!job)
 | 
				
			||||||
 | 
					        return CR_FAILURE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!new_mat.isValid() || new_mat.type != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        c->con.printerr("New job material isn't inorganic: %s\n",
 | 
				
			||||||
 | 
					                        new_mat.toString().c_str());
 | 
				
			||||||
 | 
					        return CR_FAILURE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MaterialInfo cur_mat(job);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!cur_mat.isValid() || cur_mat.type != 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        c->con.printerr("Current job material isn't inorganic: %s\n",
 | 
				
			||||||
 | 
					                        cur_mat.toString().c_str());
 | 
				
			||||||
 | 
					        return CR_FAILURE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    df::craft_material_class old_class = cur_mat.getCraftClass();
 | 
				
			||||||
 | 
					    if (old_class == craft_material_class::None)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        c->con.printerr("Unexpected current material type: %s\n",
 | 
				
			||||||
 | 
					                        cur_mat.toString().c_str());
 | 
				
			||||||
 | 
					        return CR_FAILURE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (new_mat.getCraftClass() != old_class)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        c->con.printerr("New material %s does not satisfy requirement: %s\n",
 | 
				
			||||||
 | 
					                        new_mat.toString().c_str(), ENUM_KEY_STR(craft_material_class, old_class));
 | 
				
			||||||
 | 
					        return CR_FAILURE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < job->job_items.size(); i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        df::job_item *item = job->job_items[i];
 | 
				
			||||||
 | 
					        MaterialInfo item_mat(item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (item_mat != cur_mat)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            c->con.printerr("Job item %d has different material: %s\n",
 | 
				
			||||||
 | 
					                            i, item_mat.toString().c_str());
 | 
				
			||||||
 | 
					            return CR_FAILURE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!new_mat.matches(*item))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            c->con.printerr("Job item %d requirements not satisfied by %s.\n",
 | 
				
			||||||
 | 
					                            i, new_mat.toString().c_str());
 | 
				
			||||||
 | 
					            return CR_FAILURE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Apply the substitution
 | 
				
			||||||
 | 
					    job->mat_type = new_mat.type;
 | 
				
			||||||
 | 
					    job->mat_index = new_mat.index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < job->job_items.size(); i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        df::job_item *item = job->job_items[i];
 | 
				
			||||||
 | 
					        item->mat_type = new_mat.type;
 | 
				
			||||||
 | 
					        item->mat_index = new_mat.index;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    c->con << "Applied material '" << new_mat.toString()
 | 
				
			||||||
 | 
					           << "' to job " << ENUM_KEY_STR(job_type,job->job_type) << endl;
 | 
				
			||||||
 | 
					    return CR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool build_choice_matches(df::ui_build_item_req *req, df::build_req_choicest *choice,
 | 
				
			||||||
 | 
					                                 MaterialInfo &new_mat, bool ignore_select)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (VIRTUAL_CAST_VAR(gen, df::build_req_choice_genst, choice))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (gen->mat_type == new_mat.type &&
 | 
				
			||||||
 | 
					            gen->mat_index == new_mat.index &&
 | 
				
			||||||
 | 
					            (ignore_select || gen->used_count < gen->candidates.size()))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (VIRTUAL_CAST_VAR(spec, df::build_req_choice_specst, choice))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (spec->candidate &&
 | 
				
			||||||
 | 
					            spec->candidate->getActualMaterial() == new_mat.type &&
 | 
				
			||||||
 | 
					            spec->candidate->getActualMaterialIndex() == new_mat.index &&
 | 
				
			||||||
 | 
					            (ignore_select || !req->candidate_selected[spec->candidate_id]))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static command_result job_material_in_build(Core *c, MaterialInfo &new_mat)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    df::ui_build_selector *sel = ui_build_selector;
 | 
				
			||||||
 | 
					    df::ui_build_item_req *req = sel->requirements[ui_build_selector->req_index];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Loop through matching choices
 | 
				
			||||||
 | 
					    bool matches = build_choice_matches(req, sel->choices[sel->sel_index], new_mat, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int size = sel->choices.size();
 | 
				
			||||||
 | 
					    int base = (matches ? sel->sel_index + 1 : 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (unsigned i = 0; i < size; i++)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        int idx = (base + i) % size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (build_choice_matches(req, sel->choices[idx], new_mat, false))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            sel->sel_index = idx;
 | 
				
			||||||
 | 
					            return CR_OK;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    c->con.printerr("Could not find material in list: %s\n", new_mat.toString().c_str());
 | 
				
			||||||
 | 
					    return CR_FAILURE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static command_result job_material(Core * c, vector <string> & parameters)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // HOTKEY COMMAND: CORE ALREADY SUSPENDED
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    MaterialInfo new_mat;
 | 
				
			||||||
 | 
					    if (parameters.size() == 1)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (!new_mat.find(parameters[0])) {
 | 
				
			||||||
 | 
					            c->con.printerr("Could not find material: %s\n", parameters[0].c_str());
 | 
				
			||||||
 | 
					            return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (ui->main.mode == ui_sidebar_mode::QueryBuilding)
 | 
				
			||||||
 | 
					        return job_material_in_job(c, new_mat);
 | 
				
			||||||
 | 
					    if (ui->main.mode == ui_sidebar_mode::Build)
 | 
				
			||||||
 | 
					        return job_material_in_build(c, new_mat);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* job-duplicate implementation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static command_result job_duplicate(Core * c, vector <string> & parameters)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!parameters.empty())
 | 
				
			||||||
 | 
					        return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    df::job *job = getSelectedWorkshopJob(c);
 | 
				
			||||||
 | 
					    if (!job)
 | 
				
			||||||
 | 
					        return CR_FAILURE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!job->misc_links.empty() ||
 | 
				
			||||||
 | 
					        (job->job_items.empty() &&
 | 
				
			||||||
 | 
					         job->job_type != job_type::CollectSand &&
 | 
				
			||||||
 | 
					         job->job_type != job_type::CollectClay))
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        c->con.printerr("Cannot duplicate job %s\n", ENUM_KEY_STR(job_type,job->job_type));
 | 
				
			||||||
 | 
					        return CR_FAILURE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    df::building *building = world->selected_building;
 | 
				
			||||||
 | 
					    if (building->jobs.size() >= 10)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        c->con.printerr("Job list is already full.\n");
 | 
				
			||||||
 | 
					        return CR_FAILURE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Actually clone
 | 
				
			||||||
 | 
					    df::job *pnew = cloneJobStruct(job);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    linkJobIntoWorld(pnew);
 | 
				
			||||||
 | 
					    vector_insert_at(building->jobs, ++*ui_workshop_job_cursor, pnew);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return CR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Main job command implementation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static df::job_item *getJobItem(Core *c, df::job *job, std::string idx)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (!job)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int v = atoi(idx.c_str());
 | 
				
			||||||
 | 
					    if (v < 1 || v > job->job_items.size()) {
 | 
				
			||||||
 | 
					        c->con.printerr("Invalid item index.\n");
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return job->job_items[v-1];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static command_result job_cmd(Core * c, vector <string> & parameters)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CoreSuspender suspend(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::string cmd = (parameters.empty() ? "query" : parameters[0]);
 | 
				
			||||||
 | 
					    if (cmd == "query" || cmd == "list")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        df::job *job = getSelectedWorkshopJob(c);
 | 
				
			||||||
 | 
					        if (!job)
 | 
				
			||||||
 | 
					            return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (cmd == "query") {
 | 
				
			||||||
 | 
					            printJobDetails(c, job);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            df::building *selected = world->selected_building;
 | 
				
			||||||
 | 
					            for (unsigned i = 0; i < selected->jobs.size(); i++)
 | 
				
			||||||
 | 
					                printJobDetails(c, selected->jobs[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (cmd == "item-material")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (parameters.size() != 3)
 | 
				
			||||||
 | 
					            return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        df::job *job = getSelectedWorkshopJob(c);
 | 
				
			||||||
 | 
					        df::job_item *item = getJobItem(c, job, parameters[1]);
 | 
				
			||||||
 | 
					        if (!item)
 | 
				
			||||||
 | 
					            return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ItemTypeInfo iinfo(item);
 | 
				
			||||||
 | 
					        MaterialInfo minfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!minfo.find(parameters[2])) {
 | 
				
			||||||
 | 
					            c->con.printerr("Could not find the specified material.\n");
 | 
				
			||||||
 | 
					            return CR_FAILURE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (minfo.isValid() && !iinfo.matches(*item, &minfo)) {
 | 
				
			||||||
 | 
					            c->con.printerr("Material does not match the requirements.\n");
 | 
				
			||||||
 | 
					            printJobDetails(c, job);
 | 
				
			||||||
 | 
					            return CR_FAILURE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (job->mat_type != -1 &&
 | 
				
			||||||
 | 
					            job->mat_type == item->mat_type &&
 | 
				
			||||||
 | 
					            job->mat_index == item->mat_index)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            job->mat_type = minfo.type;
 | 
				
			||||||
 | 
					            job->mat_index = minfo.index;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        item->mat_type = minfo.type;
 | 
				
			||||||
 | 
					        item->mat_index = minfo.index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        c->con << "Job item updated." << endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (item->item_type < 0 && minfo.isValid())
 | 
				
			||||||
 | 
					            c->con.printerr("WARNING: Due to a probable bug, creature & plant material subtype\n"
 | 
				
			||||||
 | 
					                            "         is ignored unless the item type is also specified.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        printJobDetails(c, job);
 | 
				
			||||||
 | 
					        return CR_OK;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (cmd == "item-type")
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (parameters.size() != 3)
 | 
				
			||||||
 | 
					            return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        df::job *job = getSelectedWorkshopJob(c);
 | 
				
			||||||
 | 
					        df::job_item *item = getJobItem(c, job, parameters[1]);
 | 
				
			||||||
 | 
					        if (!item)
 | 
				
			||||||
 | 
					            return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ItemTypeInfo iinfo;
 | 
				
			||||||
 | 
					        MaterialInfo minfo(item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!iinfo.find(parameters[2])) {
 | 
				
			||||||
 | 
					            c->con.printerr("Could not find the specified item type.\n");
 | 
				
			||||||
 | 
					            return CR_FAILURE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (iinfo.isValid() && !iinfo.matches(*item, &minfo)) {
 | 
				
			||||||
 | 
					            c->con.printerr("Item type does not match the requirements.\n");
 | 
				
			||||||
 | 
					            printJobDetails(c, job);
 | 
				
			||||||
 | 
					            return CR_FAILURE;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        item->item_type = iinfo.type;
 | 
				
			||||||
 | 
					        item->item_subtype = iinfo.subtype;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        c->con << "Job item updated." << endl;
 | 
				
			||||||
 | 
					        printJobDetails(c, job);
 | 
				
			||||||
 | 
					        return CR_OK;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					        return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return CR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -0,0 +1,82 @@
 | 
				
			|||||||
 | 
					// All above-ground soil not covered by buildings will be covered with grass.
 | 
				
			||||||
 | 
					// Necessary for worlds generated prior to version 0.31.19 - otherwise, outdoor shrubs and trees no longer grow.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Core.h"
 | 
				
			||||||
 | 
					#include "Console.h"
 | 
				
			||||||
 | 
					#include "Export.h"
 | 
				
			||||||
 | 
					#include "PluginManager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "DataDefs.h"
 | 
				
			||||||
 | 
					#include "df/world.h"
 | 
				
			||||||
 | 
					#include "df/map_block.h"
 | 
				
			||||||
 | 
					#include "TileTypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using std::string;
 | 
				
			||||||
 | 
					using std::vector;
 | 
				
			||||||
 | 
					using namespace DFHack;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					using df::global::world;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DFhackCExport command_result df_regrass (Core * c, vector <string> & parameters)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (!parameters.empty())
 | 
				
			||||||
 | 
							return CR_WRONG_USAGE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CoreSuspender suspend(c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int count = 0;
 | 
				
			||||||
 | 
						for (int i = 0; i < world->map.map_blocks.size(); i++)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							df::map_block *cur = world->map.map_blocks[i];
 | 
				
			||||||
 | 
							for (int x = 0; x < 16; x++)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								for (int y = 0; y < 16; y++)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (DFHack::tileShape(cur->tiletype[x][y]) != DFHack::FLOOR)
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									if (DFHack::tileMaterial(cur->tiletype[x][y]) != DFHack::SOIL)
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									if (cur->designation[x][y].bits.subterranean)
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
									if (cur->occupancy[x][y].bits.building)
 | 
				
			||||||
 | 
										continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									switch (rand() % 8)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
									// light grass
 | 
				
			||||||
 | 
									case 0:	cur->tiletype[x][y] = 0x015C;	break;
 | 
				
			||||||
 | 
									case 1:	cur->tiletype[x][y] = 0x015D;	break;
 | 
				
			||||||
 | 
									case 2:	cur->tiletype[x][y] = 0x015E;	break;
 | 
				
			||||||
 | 
									case 3:	cur->tiletype[x][y] = 0x015F;	break;
 | 
				
			||||||
 | 
									// dark grass
 | 
				
			||||||
 | 
									case 4:	cur->tiletype[x][y] = 0x018E;	break;
 | 
				
			||||||
 | 
									case 5:	cur->tiletype[x][y] = 0x018F;	break;
 | 
				
			||||||
 | 
									case 6:	cur->tiletype[x][y] = 0x0190;	break;
 | 
				
			||||||
 | 
									case 7:	cur->tiletype[x][y] = 0x0191;	break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									count++;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (count)
 | 
				
			||||||
 | 
							c->con.print("Regrew %d tiles of grass.\n", count);
 | 
				
			||||||
 | 
						return CR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DFhackCExport const char *plugin_name ( void )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return "regrass";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DFhackCExport command_result plugin_init (Core *c, std::vector<PluginCommand> &commands)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						commands.clear();
 | 
				
			||||||
 | 
						commands.push_back(PluginCommand("regrass", "Regrows all surface grass, restoring outdoor plant growth for pre-0.31.19 worlds.", df_regrass));
 | 
				
			||||||
 | 
						return CR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DFhackCExport command_result plugin_shutdown ( Core * c )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return CR_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1 +1 @@
 | 
				
			|||||||
Subproject commit 1b28039e2c93daa3c2f69f5e2a000ff8c96ee1f8
 | 
					Subproject commit 92627e39cb3502812cd5a131716d3d1da8ef625a
 | 
				
			||||||
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
		Loading…
	
		Reference in New Issue