]> code.bitgloo.com Git - clyne/gamedev.git/commitdiff
added gif support
authorClyne Sullivan <tullivan99@gmail.com>
Sat, 29 Jul 2017 22:25:01 +0000 (18:25 -0400)
committerClyne Sullivan <tullivan99@gmail.com>
Sat, 29 Jul 2017 22:37:26 +0000 (18:37 -0400)
20 files changed:
Makefile
assets/effects/starAttack.gif [new file with mode: 0644]
config/items.xml
include/attack.hpp
include/components/hit.hpp
include/gif_lib.h [new file with mode: 0644]
include/inventory.hpp
include/texture.hpp
lib/libgif.a [new file with mode: 0644]
lib/libgif.la [new file with mode: 0755]
lib/libgif.so [new file with mode: 0755]
lib/libgif.so.7 [new file with mode: 0755]
lib/libgif.so.7.0.0 [new file with mode: 0755]
src/attack.cpp
src/inventory.cpp
src/player.cpp
src/render.cpp
src/texture.cpp
xcf/starAttack.xcf [new file with mode: 0644]
xml/!town.xml

index 4372c312168b43be00f74b85c439d004d9e439aa..a8904db56929aa2d6b1d3f40ad52cf7a9d6ac509 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ CC  = gcc
 CXX = g++
 
 ifeq ($(TARGET_OS),linux)
-       LIBS = -lpthread -lGL -lGLEW -lfreetype \
+       LIBS = -Llib -lgif -lpthread -lGL -lGLEW -lfreetype \
               -lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2main
 endif
 ifeq ($(TARGET_OS),win32)
diff --git a/assets/effects/starAttack.gif b/assets/effects/starAttack.gif
new file mode 100644 (file)
index 0000000..09dd41d
Binary files /dev/null and b/assets/effects/starAttack.gif differ
index e4b5b5a6b8edf866307c877afa3b12415b462055..6225062d5ef15f096e98e7b4d3131bcfbaef9fd8 100644 (file)
 
 <!-- WEAPONS -->
 <item name="Wood Sword"     type="Sword"    damage="3"  maxStackSize="1"  sound="assets/sounds/longSwing.wav"  sprite="assets/items/SWORD_WOOD.png" cooldown="250">
-       <attack range="6, 2" power="1" />
+       <attack range="6, 2" power="1" effect="assets/effects/starAttack.gif"/>
+</item>
+<item name="Hunters Bow"    type="Bow"      damage="2"  maxStackSize="1"    sprite="assets/items/bow.png" cooldown="600">
+       <attack power="4" effect="assets/effects/starAttack.gif"/>
 </item>
-<item name="Hunters Bow"    type="Bow"      damage="2"  maxStackSize="1"    sprite="assets/items/bow.png" cooldown="600" />
 <item name="Arrow"    type="Arrow"    damage="1"  maxStackSize="99"   sprite="assets/items/arrow_crude.png"/>
 
 <!-- UTILITIES -->
index 2074ac25f005914a1d1137741de53ec397ded0f4..37025e1ca84dc1f60a20fcd9a6727905c27a9baf 100644 (file)
@@ -4,7 +4,9 @@
 #include <entityx/entityx.h>
 
 #include <forward_list>
+#include <vector>
 
+#include <texture.hpp>
 #include <vector2.hpp>
 
 struct Attack {
@@ -13,6 +15,8 @@ struct Attack {
        vec2 range;
        vec2 vel; // TODO use
        vec2 accel; // TODO use
+
+       TextureIterator effect;
 };
 
 struct AttackEvent {
@@ -27,8 +31,17 @@ struct AttackEvent {
 
 class AttackSystem : public entityx::System<AttackSystem>, public entityx::Receiver<AttackSystem> {
 private:
+       struct AttackAnimation {
+               vec2 pos;
+               TextureIterator effect;
+               unsigned int counter;
+
+               AttackAnimation(vec2 p, TextureIterator ti)
+                       : pos(p), effect(ti), counter(0) {}
+       };
+       
        std::forward_list<AttackEvent> attacks;
-
+       static std::vector<AttackAnimation> effects;
 public:
        void configure(entityx::EventManager& ev) {
                ev.subscribe<AttackEvent>(*this);
@@ -36,6 +49,7 @@ public:
 
        void receive(const AttackEvent& ae);
        void update(entityx::EntityManager& en, entityx::EventManager& ev, entityx::TimeDelta dt) override;
+       static void render(void);
 };
 
 #endif // ATTACK_HPP_
index d2e80ca96e38bc71a7b7de80262dcaff07b64336..334712bfa1ad7e6078c5ec62e64ffa25004847a1 100644 (file)
@@ -3,12 +3,15 @@
 
 #include "base.hpp"
 
+#include <texture.hpp>
+
 struct Hit : public Component {
        Hit(int d, bool p = false)
                : damage(d), pierce(p) {}
 
        int damage;
        bool pierce;
+       TextureIterator effect;
 
        void fromXML(XMLElement* imp, XMLElement* def) final {
                (void)imp;
diff --git a/include/gif_lib.h b/include/gif_lib.h
new file mode 100644 (file)
index 0000000..078930c
--- /dev/null
@@ -0,0 +1,312 @@
+/******************************************************************************
+gif_lib.h - service library for decoding and encoding GIF images
+                                                                             
+*****************************************************************************/
+
+#ifndef _GIF_LIB_H_
+#define _GIF_LIB_H_ 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GIFLIB_MAJOR 5
+#define GIFLIB_MINOR 1
+#define GIFLIB_RELEASE 4
+
+#define GIF_ERROR   0
+#define GIF_OK      1
+
+#include <stddef.h>
+#include <stdbool.h>
+
+#define GIF_STAMP "GIFVER"          /* First chars in file - GIF stamp.  */
+#define GIF_STAMP_LEN sizeof(GIF_STAMP) - 1
+#define GIF_VERSION_POS 3           /* Version first character in stamp. */
+#define GIF87_STAMP "GIF87a"        /* First chars in file - GIF stamp.  */
+#define GIF89_STAMP "GIF89a"        /* First chars in file - GIF stamp.  */
+
+typedef unsigned char GifPixelType;
+typedef unsigned char *GifRowType;
+typedef unsigned char GifByteType;
+typedef unsigned int GifPrefixType;
+typedef int GifWord;
+
+typedef struct GifColorType {
+    GifByteType Red, Green, Blue;
+} GifColorType;
+
+typedef struct ColorMapObject {
+    int ColorCount;
+    int BitsPerPixel;
+    bool SortFlag;
+    GifColorType *Colors;    /* on malloc(3) heap */
+} ColorMapObject;
+
+typedef struct GifImageDesc {
+    GifWord Left, Top, Width, Height;   /* Current image dimensions. */
+    bool Interlace;                     /* Sequential/Interlaced lines. */
+    ColorMapObject *ColorMap;           /* The local color map */
+} GifImageDesc;
+
+typedef struct ExtensionBlock {
+    int ByteCount;
+    GifByteType *Bytes; /* on malloc(3) heap */
+    int Function;       /* The block function code */
+#define CONTINUE_EXT_FUNC_CODE    0x00    /* continuation subblock */
+#define COMMENT_EXT_FUNC_CODE     0xfe    /* comment */
+#define GRAPHICS_EXT_FUNC_CODE    0xf9    /* graphics control (GIF89) */
+#define PLAINTEXT_EXT_FUNC_CODE   0x01    /* plaintext */
+#define APPLICATION_EXT_FUNC_CODE 0xff    /* application block */
+} ExtensionBlock;
+
+typedef struct SavedImage {
+    GifImageDesc ImageDesc;
+    GifByteType *RasterBits;         /* on malloc(3) heap */
+    int ExtensionBlockCount;         /* Count of extensions before image */    
+    ExtensionBlock *ExtensionBlocks; /* Extensions before image */    
+} SavedImage;
+
+typedef struct GifFileType {
+    GifWord SWidth, SHeight;         /* Size of virtual canvas */
+    GifWord SColorResolution;        /* How many colors can we generate? */
+    GifWord SBackGroundColor;        /* Background color for virtual canvas */
+    GifByteType AspectByte;         /* Used to compute pixel aspect ratio */
+    ColorMapObject *SColorMap;       /* Global colormap, NULL if nonexistent. */
+    int ImageCount;                  /* Number of current image (both APIs) */
+    GifImageDesc Image;              /* Current image (low-level API) */
+    SavedImage *SavedImages;         /* Image sequence (high-level API) */
+    int ExtensionBlockCount;         /* Count extensions past last image */
+    ExtensionBlock *ExtensionBlocks; /* Extensions past last image */    
+    int Error;                      /* Last error condition reported */
+    void *UserData;                  /* hook to attach user data (TVT) */
+    void *Private;                   /* Don't mess with this! */
+} GifFileType;
+
+#define GIF_ASPECT_RATIO(n)    ((n)+15.0/64.0)
+
+typedef enum {
+    UNDEFINED_RECORD_TYPE,
+    SCREEN_DESC_RECORD_TYPE,
+    IMAGE_DESC_RECORD_TYPE, /* Begin with ',' */
+    EXTENSION_RECORD_TYPE,  /* Begin with '!' */
+    TERMINATE_RECORD_TYPE   /* Begin with ';' */
+} GifRecordType;
+
+/* func type to read gif data from arbitrary sources (TVT) */
+typedef int (*InputFunc) (GifFileType *, GifByteType *, int);
+
+/* func type to write gif data to arbitrary targets.
+ * Returns count of bytes written. (MRB)
+ */
+typedef int (*OutputFunc) (GifFileType *, const GifByteType *, int);
+
+/******************************************************************************
+ GIF89 structures
+******************************************************************************/
+
+typedef struct GraphicsControlBlock {
+    int DisposalMode;
+#define DISPOSAL_UNSPECIFIED      0       /* No disposal specified. */
+#define DISPOSE_DO_NOT            1       /* Leave image in place */
+#define DISPOSE_BACKGROUND        2       /* Set area too background color */
+#define DISPOSE_PREVIOUS          3       /* Restore to previous content */
+    bool UserInputFlag;      /* User confirmation required before disposal */
+    int DelayTime;           /* pre-display delay in 0.01sec units */
+    int TransparentColor;    /* Palette index for transparency, -1 if none */
+#define NO_TRANSPARENT_COLOR   -1
+} GraphicsControlBlock;
+
+/******************************************************************************
+ GIF encoding routines
+******************************************************************************/
+
+/* Main entry points */
+GifFileType *EGifOpenFileName(const char *GifFileName,
+                              const bool GifTestExistence, int *Error);
+GifFileType *EGifOpenFileHandle(const int GifFileHandle, int *Error);
+GifFileType *EGifOpen(void *userPtr, OutputFunc writeFunc, int *Error);
+int EGifSpew(GifFileType * GifFile);
+const char *EGifGetGifVersion(GifFileType *GifFile); /* new in 5.x */
+int EGifCloseFile(GifFileType *GifFile, int *ErrorCode);
+
+#define E_GIF_SUCCEEDED          0
+#define E_GIF_ERR_OPEN_FAILED    1    /* And EGif possible errors. */
+#define E_GIF_ERR_WRITE_FAILED   2
+#define E_GIF_ERR_HAS_SCRN_DSCR  3
+#define E_GIF_ERR_HAS_IMAG_DSCR  4
+#define E_GIF_ERR_NO_COLOR_MAP   5
+#define E_GIF_ERR_DATA_TOO_BIG   6
+#define E_GIF_ERR_NOT_ENOUGH_MEM 7
+#define E_GIF_ERR_DISK_IS_FULL   8
+#define E_GIF_ERR_CLOSE_FAILED   9
+#define E_GIF_ERR_NOT_WRITEABLE  10
+
+/* These are legacy.  You probably do not want to call them directly */
+int EGifPutScreenDesc(GifFileType *GifFile,
+                      const int GifWidth, const int GifHeight, 
+                     const int GifColorRes,
+                      const int GifBackGround,
+                      const ColorMapObject *GifColorMap);
+int EGifPutImageDesc(GifFileType *GifFile, 
+                    const int GifLeft, const int GifTop,
+                     const int GifWidth, const int GifHeight, 
+                    const bool GifInterlace,
+                     const ColorMapObject *GifColorMap);
+void EGifSetGifVersion(GifFileType *GifFile, const bool gif89);
+int EGifPutLine(GifFileType *GifFile, GifPixelType *GifLine,
+                int GifLineLen);
+int EGifPutPixel(GifFileType *GifFile, const GifPixelType GifPixel);
+int EGifPutComment(GifFileType *GifFile, const char *GifComment);
+int EGifPutExtensionLeader(GifFileType *GifFile, const int GifExtCode);
+int EGifPutExtensionBlock(GifFileType *GifFile,
+                         const int GifExtLen, const void *GifExtension);
+int EGifPutExtensionTrailer(GifFileType *GifFile);
+int EGifPutExtension(GifFileType *GifFile, const int GifExtCode, 
+                    const int GifExtLen,
+                     const void *GifExtension);
+int EGifPutCode(GifFileType *GifFile, int GifCodeSize,
+                const GifByteType *GifCodeBlock);
+int EGifPutCodeNext(GifFileType *GifFile,
+                    const GifByteType *GifCodeBlock);
+
+/******************************************************************************
+ GIF decoding routines
+******************************************************************************/
+
+/* Main entry points */
+GifFileType *DGifOpenFileName(const char *GifFileName, int *Error);
+GifFileType *DGifOpenFileHandle(int GifFileHandle, int *Error);
+int DGifSlurp(GifFileType * GifFile);
+GifFileType *DGifOpen(void *userPtr, InputFunc readFunc, int *Error);    /* new one (TVT) */
+    int DGifCloseFile(GifFileType * GifFile, int *ErrorCode);
+
+#define D_GIF_SUCCEEDED          0
+#define D_GIF_ERR_OPEN_FAILED    101    /* And DGif possible errors. */
+#define D_GIF_ERR_READ_FAILED    102
+#define D_GIF_ERR_NOT_GIF_FILE   103
+#define D_GIF_ERR_NO_SCRN_DSCR   104
+#define D_GIF_ERR_NO_IMAG_DSCR   105
+#define D_GIF_ERR_NO_COLOR_MAP   106
+#define D_GIF_ERR_WRONG_RECORD   107
+#define D_GIF_ERR_DATA_TOO_BIG   108
+#define D_GIF_ERR_NOT_ENOUGH_MEM 109
+#define D_GIF_ERR_CLOSE_FAILED   110
+#define D_GIF_ERR_NOT_READABLE   111
+#define D_GIF_ERR_IMAGE_DEFECT   112
+#define D_GIF_ERR_EOF_TOO_SOON   113
+
+/* These are legacy.  You probably do not want to call them directly */
+int DGifGetScreenDesc(GifFileType *GifFile);
+int DGifGetRecordType(GifFileType *GifFile, GifRecordType *GifType);
+int DGifGetImageDesc(GifFileType *GifFile);
+int DGifGetLine(GifFileType *GifFile, GifPixelType *GifLine, int GifLineLen);
+int DGifGetPixel(GifFileType *GifFile, GifPixelType GifPixel);
+int DGifGetComment(GifFileType *GifFile, char *GifComment);
+int DGifGetExtension(GifFileType *GifFile, int *GifExtCode,
+                     GifByteType **GifExtension);
+int DGifGetExtensionNext(GifFileType *GifFile, GifByteType **GifExtension);
+int DGifGetCode(GifFileType *GifFile, int *GifCodeSize,
+                GifByteType **GifCodeBlock);
+int DGifGetCodeNext(GifFileType *GifFile, GifByteType **GifCodeBlock);
+int DGifGetLZCodes(GifFileType *GifFile, int *GifCode);
+
+
+/******************************************************************************
+ Color table quantization (deprecated)
+******************************************************************************/
+int GifQuantizeBuffer(unsigned int Width, unsigned int Height,
+                   int *ColorMapSize, GifByteType * RedInput,
+                   GifByteType * GreenInput, GifByteType * BlueInput,
+                   GifByteType * OutputBuffer,
+                   GifColorType * OutputColorMap);
+
+/******************************************************************************
+ Error handling and reporting.
+******************************************************************************/
+extern const char *GifErrorString(int ErrorCode);     /* new in 2012 - ESR */
+
+/*****************************************************************************
+ Everything below this point is new after version 1.2, supporting `slurp
+ mode' for doing I/O in two big belts with all the image-bashing in core.
+******************************************************************************/
+
+/******************************************************************************
+ Color map handling from gif_alloc.c
+******************************************************************************/
+
+extern ColorMapObject *GifMakeMapObject(int ColorCount,
+                                     const GifColorType *ColorMap);
+extern void GifFreeMapObject(ColorMapObject *Object);
+extern ColorMapObject *GifUnionColorMap(const ColorMapObject *ColorIn1,
+                                     const ColorMapObject *ColorIn2,
+                                     GifPixelType ColorTransIn2[]);
+extern int GifBitSize(int n);
+
+extern void *
+reallocarray(void *optr, size_t nmemb, size_t size);
+
+/******************************************************************************
+ Support for the in-core structures allocation (slurp mode).              
+******************************************************************************/
+
+extern void GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]);
+extern int GifAddExtensionBlock(int *ExtensionBlock_Count,
+                               ExtensionBlock **ExtensionBlocks, 
+                               int Function, 
+                               unsigned int Len, unsigned char ExtData[]);
+extern void GifFreeExtensions(int *ExtensionBlock_Count,
+                             ExtensionBlock **ExtensionBlocks);
+extern SavedImage *GifMakeSavedImage(GifFileType *GifFile,
+                                  const SavedImage *CopyFrom);
+extern void GifFreeSavedImages(GifFileType *GifFile);
+
+/******************************************************************************
+ 5.x functions for GIF89 graphics control blocks
+******************************************************************************/
+
+int DGifExtensionToGCB(const size_t GifExtensionLength,
+                      const GifByteType *GifExtension,
+                      GraphicsControlBlock *GCB);
+size_t EGifGCBToExtension(const GraphicsControlBlock *GCB,
+                      GifByteType *GifExtension);
+
+int DGifSavedExtensionToGCB(GifFileType *GifFile, 
+                           int ImageIndex, 
+                           GraphicsControlBlock *GCB);
+int EGifGCBToSavedExtension(const GraphicsControlBlock *GCB, 
+                           GifFileType *GifFile, 
+                           int ImageIndex);
+
+/******************************************************************************
+ The library's internal utility font                          
+******************************************************************************/
+
+#define GIF_FONT_WIDTH  8
+#define GIF_FONT_HEIGHT 8
+extern const unsigned char GifAsciiTable8x8[][GIF_FONT_WIDTH];
+
+extern void GifDrawText8x8(SavedImage *Image,
+                     const int x, const int y,
+                     const char *legend, const int color);
+
+extern void GifDrawBox(SavedImage *Image,
+                    const int x, const int y,
+                    const int w, const int d, const int color);
+
+extern void GifDrawRectangle(SavedImage *Image,
+                   const int x, const int y,
+                   const int w, const int d, const int color);
+
+extern void GifDrawBoxedText8x8(SavedImage *Image,
+                          const int x, const int y,
+                          const char *legend,
+                          const int border, const int bg, const int fg);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _GIF_LIB_H */
+
+/* end */
index ac87f38856a4787f3652026d928a8da2d4c36469..475575c79f33890296d1184e46203af911abccb7 100644 (file)
@@ -25,12 +25,13 @@ using namespace tinyxml2;
  * Contains the information neccessary for an item.
  */
 struct Item {
-       std::string name; /**< The name of the item */
-       std::string type; /**< The type of the item */
-       int value;        /**< The value/worth of the item */
-       int stackSize;    /**< The stack size of the item */
-       Texture sprite;   /**< The texture for the item (in inventory) */
-       Mix_Chunk* sound; /**< The sound to play on item use */
+       std::string name;       /**< The name of the item */
+       std::string type;       /**< The type of the item */
+       int value;              /**< The value/worth of the item */
+       int stackSize;          /**< The stack size of the item */
+       Texture sprite;         /**< The texture for the item (in inventory) */
+       TextureIterator effect; /**< Animation played on item use */
+       Mix_Chunk* sound;       /**< The sound to play on item use */
        int cooldown;
 
        Item(void)
index 9531d9d3a195115d836ec97c9e998fda283afff8..d4bcfa9a70d941f59807e484cd12244ba1e02b71 100644 (file)
@@ -137,6 +137,9 @@ public:
         * @param l the list of textures
         */
        TextureIterator(const std::vector<std::string> &l);
+
+       void appendGIF(const std::string& gif);
+
        /**
         * Shifts to the next texture in the array, stopping at the end if we're there.
         * Also binds the texture.
@@ -148,19 +151,21 @@ public:
         * Also binds the texture.
         */
        void operator--(int) noexcept;
+
        /**
         * Goes to the given index in the list.
         * @param index the index to use
         */
-       void operator()(const int &index);
+       void operator()(const int& index);
+
        /**
         * Gets the dimensions of the currently selected texture.
         * @return the texture's dimensions
         */
-       inline const vec2& getTextureDim(void)
+       inline const vec2& getTextureDim(void) const
        { return position->getDim(); }
 
-       inline unsigned int size(void)
+       inline unsigned int size(void) const
        { return textures.size(); }
 };
 
diff --git a/lib/libgif.a b/lib/libgif.a
new file mode 100644 (file)
index 0000000..0a53285
Binary files /dev/null and b/lib/libgif.a differ
diff --git a/lib/libgif.la b/lib/libgif.la
new file mode 100755 (executable)
index 0000000..6338897
--- /dev/null
@@ -0,0 +1,41 @@
+# libgif.la - a libtool library file
+# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1.11
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='libgif.so.7'
+
+# Names of this library.
+library_names='libgif.so.7.0.0 libgif.so.7 libgif.so'
+
+# The name of the static archive.
+old_library='libgif.a'
+
+# Linker flags that can not go in dependency_libs.
+inherited_linker_flags=''
+
+# Libraries that this one depends upon.
+dependency_libs=''
+
+# Names of additional weak libraries provided by this library
+weak_library_names=''
+
+# Version information for libgif.
+current=7
+age=0
+revision=0
+
+# Is this an already installed library?
+installed=yes
+
+# Should we warn about portability when linking against -modules?
+shouldnotlink=no
+
+# Files to dlopen/dlpreopen
+dlopen=''
+dlpreopen=''
+
+# Directory that this library needs to be installed in:
+libdir='/home/clyne/Downloads/giflib-5.1.4/out/lib'
diff --git a/lib/libgif.so b/lib/libgif.so
new file mode 100755 (executable)
index 0000000..0511815
Binary files /dev/null and b/lib/libgif.so differ
diff --git a/lib/libgif.so.7 b/lib/libgif.so.7
new file mode 100755 (executable)
index 0000000..0511815
Binary files /dev/null and b/lib/libgif.so.7 differ
diff --git a/lib/libgif.so.7.0.0 b/lib/libgif.so.7.0.0
new file mode 100755 (executable)
index 0000000..0511815
Binary files /dev/null and b/lib/libgif.so.7.0.0 differ
index f8a90330d0abc0f083dadf0f6bd7e23587f4085e..f585a73473d123eff83738c63c277bb9bcc8f9d2 100644 (file)
@@ -4,6 +4,7 @@
 #include <engine.hpp>
 #include <particle.hpp>
 #include <player.hpp>
+#include <render.hpp>
 #include <world.hpp>
 
 // math helpers because we don't trust stdlib
@@ -25,6 +26,8 @@ bool inrange(float point, float left, float right)
        return point > left && point < right;
 }
 
+std::vector<AttackSystem::AttackAnimation> AttackSystem::effects;
+
 void AttackSystem::receive(const AttackEvent& ae)
 {
        attacks.emplace_front(ae);
@@ -42,7 +45,10 @@ void AttackSystem::update(entityx::EntityManager& en, entityx::EventManager& ev,
                en.each<Health, Position, Solid>([&](entityx::Entity e, Health& health, Position& pos, Solid& dim) {
                        if (!e.has_component<Player>() && inrange(ppos.x, pos.x, pos.x + dim.width) && inrange(ppos.y, pos.y - 2, pos.y + dim.height)) {
                                health.health -= hit.damage;
-                               e.replace<Flash>(Color(255, 0, 0));
+                               if (hit.effect.size() == 0)
+                                       e.replace<Flash>(Color(255, 0, 0));
+                               else
+                                       effects.emplace_back(vec2(ppos.x, ppos.y), hit.effect);
                                ParticleSystem::addMultiple(15, ParticleType::SmallBlast,
                                        [&](){ return vec2(pos.x + dim.width / 2, pos.y + dim.height / 2); }, 300, 7);
                                die = !hit.pierce;
@@ -68,9 +74,13 @@ void AttackSystem::update(entityx::EntityManager& en, entityx::EventManager& ev,
                                if (inrange(point.x, pos.x, pos.x + dim.width, HLINES(size.x)) &&
                                        inrange(point.y, pos.y, pos.y + dim.height, HLINES(size.y))) {
                                        h.health -= a.attack.power;
-                                       e.replace<Flash>(Color(255, 0, 0));
-                                       ParticleSystem::addMultiple(15, ParticleType::DownSlash,
-                                               [&](){ return vec2(pos.x + dim.width / 2, pos.y + dim.height / 2); }, 300, 7);
+
+                                       if (a.attack.effect.size() == 0)
+                                               e.replace<Flash>(Color(255, 0, 0));
+                                       else
+                                               effects.emplace_back(point, a.attack.effect);
+                                       //ParticleSystem::addMultiple(15, ParticleType::DownSlash,
+                                       //      [&](){ return vec2(pos.x + dim.width / 2, pos.y + dim.height / 2); }, 300, 7);
                                }
                        }
                );
@@ -79,3 +89,30 @@ void AttackSystem::update(entityx::EntityManager& en, entityx::EventManager& ev,
        attacks.clear();
 }
 
+#define RATE 3
+void AttackSystem::render(void)
+{
+       float z = -9.9f;
+       Render::worldShader.use();
+       Render::worldShader.enable();
+       for (auto& ae : effects) {
+               ae.effect(ae.counter / RATE); // bind current frame
+               auto dim = ae.effect.getTextureDim();
+               GLfloat verts[] = {
+                       ae.pos.x,         ae.pos.y,         z, 0, 0,
+                       ae.pos.x + dim.x, ae.pos.y,         z, 1, 0,
+                       ae.pos.x + dim.x, ae.pos.y + dim.y, z, 1, 1,
+                       ae.pos.x + dim.x, ae.pos.y + dim.y, z, 1, 1,
+                       ae.pos.x,         ae.pos.y + dim.y, z, 0, 1,
+                       ae.pos.x,         ae.pos.y,         z, 0, 0
+               };
+               glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), verts);
+               glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), verts + 3);
+               glDrawArrays(GL_TRIANGLES, 0, 6);
+       }
+       Render::worldShader.disable();
+       Render::worldShader.unuse();
+
+       effects.erase(std::remove_if(effects.begin(), effects.end(), [](auto& e) { return ++e.counter >= e.effect.size() * RATE; }),
+               effects.end());
+}
index 495526a2b30bcabdba68b3e6d2d945b655cbbc58..95ab523c52e0b269c1eb8e7e9b2d689a94d4a2d6 100644 (file)
@@ -78,6 +78,8 @@ void InventorySystem::loadItems(void) {
                        attack.range  = atk->StrAttribute("range");
                        attack.vel    = atk->StrAttribute("velocity");
                        attack.accel  = atk->StrAttribute("accel");
+                       if (atk->Attribute("effect") != nullptr)
+                               attack.effect.appendGIF(atk->StrAttribute("effect")); 
                        attackList.emplace(item.name, attack);
                }
 
index 6674da0c101ffdd7a41732ae8ec4ad6491f27982..3606bc713ee424c0e593318d5d0b4f249b3704df 100644 (file)
@@ -227,7 +227,7 @@ void PlayerSystem::receive(const UseItemEvent& uie)
                                uie.attack->range.x *= -1;
                        game::events.emit<AttackEvent>(loc, *uie.attack, true);
                } else if (uie.item->type == "Bow") {
-                       /*if (InventorySystem::take("Arrow", 1)) {
+                       if (InventorySystem::take("Arrow", 1)) {
                                auto e = game::entities.create();
                                auto pos = getPosition();
                                e.assign<Position>(pos.x, pos.y + 10);
@@ -242,8 +242,10 @@ void PlayerSystem::receive(const UseItemEvent& uie)
                                sprite->addSpriteSegment(SpriteData(tex->sprite), 0);
                                auto dim = HLINES(sprite->getSpriteSize());
                                e.assign<Solid>(dim.x, dim.y);
-                               e.assign<Hit>(10, false);
-                       }*/
+                               e.assign<Hit>(uie.attack->power, false);
+                               if (uie.attack->effect.size() > 0)
+                                       e.component<Hit>()->effect = uie.attack->effect;
+                       }
                }
 
                cool.store(false);
index 58674a13c4f3d05c5896706dca69892865fec452..baa08ee0c1f7dcac7ad6c7c079965eddbc055c5b 100644 (file)
@@ -178,6 +178,7 @@ void render(const int& fps)
 
        WorldSystem::render();
        ParticleSystem::render();
+       AttackSystem::render();
        RenderSystem::render();
        InventorySystem::render();
 
index 44e48a0f1cae9bed9fcee4acf323266d7ffae1bd..19aae3f7273f455ba6888607d77c44e6a47d92fa 100644 (file)
@@ -9,6 +9,7 @@
 #include <config.hpp>
 #include <debug.hpp>
 #include <error.hpp>
+#include <gif_lib.h>
 
 namespace Colors
 {
@@ -149,6 +150,48 @@ void TextureIterator::operator()(const int &index)
        position->use();
 }
 
+void TextureIterator::appendGIF(const std::string& gif)
+{
+       int* error = nullptr;
+       auto handle = DGifOpenFileName(gif.c_str(), error);
+       UserAssert(handle != nullptr && error == nullptr, "Failed to load GIF: " + gif);
+       UserAssert(DGifSlurp(handle) == GIF_OK, "Failed to extract from GIF: " + gif);
+
+       for (int i = 0; i < handle->ImageCount; i++) {
+               vec2 dim (handle->SavedImages[i].ImageDesc.Width,
+                       handle->SavedImages[i].ImageDesc.Height);
+               int pcount = dim.x * dim.y;
+               auto buf = new GLubyte[pcount * 4];
+               auto bits = handle->SavedImages[i].RasterBits;
+               auto map = handle->SColorMap->Colors;
+               for (int j = 0; j < pcount; j++) {
+                       //if (bits[j * 4] == handle->SBackGroundColor) {
+                       auto c = map[bits[j]];
+                       if (c.Red == 0xFF && c.Green == 0xFF && c.Blue == 0xFF) {
+                               buf[j * 4] = buf[j * 4 + 1] = buf[j * 4 + 2] = buf[j * 4 + 3] = 0;
+                       } else {
+                               buf[j * 4 + 0] = c.Red;
+                               buf[j * 4 + 1] = c.Green;
+                               buf[j * 4 + 2] = c.Blue;
+                               buf[j * 4 + 3] = 0xFF;
+                       }
+               }
+
+               GLuint object;
+               glGenTextures(1, &object);
+               glBindTexture(GL_TEXTURE_2D, object);
+               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+               glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+               glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+               glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dim.x, dim.y, 0, GL_RGBA,
+                       GL_UNSIGNED_BYTE, buf);
+
+               textures.emplace_back(gif, object, dim);
+               delete[] buf;
+       }
+}
 
 void unloadTextures(void)
 {
diff --git a/xcf/starAttack.xcf b/xcf/starAttack.xcf
new file mode 100644 (file)
index 0000000..8413a15
Binary files /dev/null and b/xcf/starAttack.xcf differ
index 9f5bd0a6e626263a2c31cb47d2609660c01d9ff6..28d3a9b751356c02dc7ca223aa34c2dd80b2cb46 100644 (file)
 
 <Dialog name="Bob">
     <text id="0" nextid="1">
-        <give name="Wood Sword" count="1"/>
+           <give name="Hunters Bow" count="1"/>
+           <give name="Arrow" count="50"/>
                <option name="Yes" />
-               <option name="Yes daddy" />
-               <option name="Ooooh boy yesss please" />
         <content>
                        Hey there! The name's Bob. Good to see you've finally woken up from your nap by the cliff there... lol
                </content>