| @@ -0,0 +1,242 @@ | ||
| #include <string> | ||
| #include "area.h" | ||
|
|
||
| Area::Area(Direction* d) { | ||
| first = capacity/2; | ||
| last = first; | ||
| face = d; | ||
| } | ||
|
|
||
| void Area::swap_objects(unsigned int i, unsigned int j) { | ||
| Object* temp = vassals[i]; | ||
| vassals[i] = vassals[j]; | ||
| vassals[j] = temp; | ||
| } | ||
|
|
||
| /** | ||
| * Returns the index of the first found Object with Point p, | ||
| * or index of first Object with Point in front of p (if no such Object exists in vassals) | ||
| * Searches from start_i to end_i (exclusive) | ||
| */ | ||
| unsigned int Area::find_index(Point* p, unsigned int start_i, unsigned int end_i) { | ||
| unsigned int si = start_i, ei = end_i; | ||
| while (ei-si > 1) { | ||
| int c = compare(p, vassals[(si+ei)/2]->get_pos(), *face); | ||
| if (c == 0) { return (si+ei)/2; } | ||
| else if (c > 0) { si = (si+ei)/2; } | ||
| else { ei = (si+ei)/2; } | ||
| } | ||
| if (compare(p, vassals[si]->get_pos(), *face) >= 0) { | ||
| while (si >= start_i && compare(p, vassals[si]->get_pos(), *face) >= 0) { | ||
| si--; | ||
| } | ||
| return (si+1); | ||
| } else { | ||
| while (si < end_i && compare(p, vassals[si]->get_pos(), *face) < 0) { | ||
| si++; | ||
| } | ||
| return si; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Finds the specific place for the object and sorts it to that location | ||
| */ | ||
| void Area::resort_object(unsigned int index) { | ||
| unsigned int k = find_index(vassals[index]->get_pos(), first, index); | ||
| if (k < index) { | ||
| Object* temp = vassals[index]; | ||
| for (unsigned int i = index; i > k; i--) { | ||
| vassals[i] = vassals[i-1]; | ||
| } | ||
| vassals[k] = temp; | ||
| } else { | ||
| k = find_index(vassals[index]->get_pos(), index+1, last); | ||
| if (k > index) { | ||
| Object* temp = vassals[index]; | ||
| for (unsigned int i = index; i < k-1; i++) { | ||
| vassals[i] = vassals[i+1]; | ||
| } | ||
| vassals[k-1] = temp; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Sorts everything from si to ei, ei inclusive | ||
| * Uses quicksort, always choosing (si+ei)/2 as the pivot | ||
| */ | ||
| void Area::resort(unsigned int si, unsigned int ei) { | ||
| if (ei-si <= 1) { return; } | ||
| swap_objects((si+ei)/2, ei); | ||
| Point* pivot = vassals[ei]->get_pos(); | ||
| unsigned int i = si; | ||
| for (unsigned int j = i; j < ei; j++) { | ||
| if (compare(vassals[j]->get_pos(), pivot, *face) <= 0) { | ||
| swap_objects(j, i++); | ||
| } | ||
| } | ||
| swap_objects(i, ei); | ||
| resort(si, i-1); | ||
| resort(i+1, ei); | ||
|
|
||
| /* | ||
| unsigned int mi = (si+ei)/2; | ||
| resort(si, mi); | ||
| resort(mi, ei); | ||
| unsigned int l = si; | ||
| unsigned int r = mi; | ||
| if (compare(vassals[l]->get_pos(), vassals[r]->get_pos(), wrapper->get_face()) <= 0) { return true; } | ||
| while (l < mi && r < ei) { | ||
| if (compare(vassals[l]->get_pos(), vassals[r]->get_pos(), wrapper->get_face()) > 0) { | ||
| Object* temp = vassals[r]; | ||
| for (int i = r; i > l; i--) { | ||
| vassals[i] = vassals[i-1]; | ||
| } | ||
| vassals[l] = temp; | ||
| mi++; r++; | ||
| } | ||
| l++; | ||
| } | ||
| return false; | ||
| */ | ||
| } | ||
|
|
||
| unsigned int Area::find_index(Point* p) { | ||
| return find_index(p, first, last); | ||
| } | ||
|
|
||
| bool Area::add(Object* o) { | ||
| return add(o, o->get_pos()); | ||
| } | ||
|
|
||
| bool Area::add(Object* o, Point* p) { | ||
| bool add_before = (compare(p, vassals[(first+last)/2]->get_pos(), *face) <= 0); | ||
| if ((add_before && first == 0) || (!add_before && last == capacity)) { | ||
| unsigned int new_capacity = capacity*3/2; | ||
| if (new_capacity < capacity) { throw std::string("Too many objects in area."); } | ||
| Object** new_vassals = new Object*[new_capacity](); | ||
| unsigned int m = (add_before ? (capacity/2)-1 : 0); | ||
| for (unsigned int i = first+m; i < last; i++) { | ||
| if ((m == 0 || m == (capacity/2)-1) && compare(p, vassals[i-m]->get_pos(), *face) < 0) { | ||
| new_vassals[i] = o; | ||
| m++; | ||
| } else { | ||
| new_vassals[i] = vassals[i-m]; | ||
| } | ||
| } | ||
| if (add_before) { first--; } | ||
| else { last++; } | ||
|
|
||
| delete[] vassals; | ||
| vassals = new_vassals; | ||
| capacity = new_capacity; | ||
| } else { | ||
| unsigned int index = (add_before ? (--first) : (last++)); | ||
| vassals[index] = o; | ||
| resort_object(index); | ||
| } | ||
| return true; | ||
|
|
||
| /* | ||
| if (last == capacity) { | ||
| unsigned int new_capacity = capacity*7/4; | ||
| if (new_capacity < capacity) { throw std::string("Too many objects in area."); } | ||
| Object** new_vassals = new Object*[new_capacity]; | ||
| bool added = false; | ||
| for (int i = 0; i < last; i++) { | ||
| if (added) { | ||
| new_vassals[i+1] = vassals[i]; | ||
| } else if (compare(p, vassals[i]->get_pos(), face) < 0) { | ||
| new_vassals[i] = o; | ||
| new_vassals[i+1] = vassals[i]; | ||
| added = true; | ||
| } else { | ||
| new_vassals[i] = vassals[i]; | ||
| } | ||
| } | ||
| } else { | ||
| unsigned int index = find_index(p); | ||
| for (unsigned int i = last-1; i > index; i--) { | ||
| vassals[i] = vassals[i-1]; | ||
| } | ||
| vassals[index] = o; | ||
| } | ||
| last++; | ||
| return true; | ||
| */ | ||
| } | ||
|
|
||
| Object* Area::discard(Object* o) { | ||
| unsigned int index = find_index(o->get_pos()); | ||
| if (vassals[index] != o) { | ||
| for (unsigned int i = index; i < last; i++) { | ||
| if (vassals[i] == o) { | ||
| index = i; | ||
| break; | ||
| } else if (i == last-1 || compare(o->get_pos(), vassals[i]->get_pos(), *face) != 0) { | ||
| throw std::string("Attempted to delete Object not in Area."); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (index <= (first+last)/2) { | ||
| for (unsigned int i = index; i > first; i--) { | ||
| vassals[i] = vassals[i-1]; | ||
| } | ||
| vassals[first++] = NULL; | ||
| } else { | ||
| for (unsigned int i = index; i < last-1; i++) { | ||
| vassals[i] = vassals[i+1]; | ||
| } | ||
| vassals[--last] = NULL; | ||
| } | ||
| return o; | ||
|
|
||
| /* | ||
| unsigned int i = index; | ||
| while (vassals[i] != o) { | ||
| if (i >= last-1 || compare(o->get_pos(), vassals[i]->get_pos(), wrapper->get_face()) != 0) { | ||
| break; | ||
| } else { | ||
| i++; | ||
| } | ||
| } | ||
| if (vassals[i] == o) { | ||
| index = i; | ||
| } else { | ||
| i = index; | ||
| while (vassals[i] != o) { | ||
| if (i <= first || compare(o->get_pos(), vassals[i]->get_pos(), wrapper->get_face()) != 0) { | ||
| break; | ||
| } else { | ||
| i--; | ||
| } | ||
| } | ||
| if (vassals[i] == o) { | ||
| index = i | ||
| } else { | ||
| throw std::string("Attempted to delete Object not in Area."); | ||
| } | ||
| } | ||
| } | ||
| bool del_before = | ||
| for (unsigned int i = last-1; i > index; i--) { | ||
| vassals[i-1] = vassals[i]; | ||
| } | ||
| return o; | ||
| */ | ||
| } | ||
|
|
||
| Object* Area::get(Point* p) { | ||
| unsigned int index = find_index(p); | ||
| if (compare(p, vassals[index]->get_pos(), *face) != 0) { | ||
| throw 0; | ||
| } else { | ||
| return vassals[index]; | ||
| } | ||
| } | ||
|
|
| @@ -0,0 +1,33 @@ | ||
| #ifndef AREA_H | ||
| #define AREA_H | ||
|
|
||
| #include "lord.h" | ||
| #include "geometry.h" | ||
| #include "object.h" | ||
|
|
||
| class Area: public Lord<Object*, Point*> { | ||
| private: | ||
| unsigned int first; | ||
| unsigned int last; | ||
|
|
||
| Direction* face; | ||
|
|
||
| void swap_objects(unsigned int, unsigned int); | ||
| unsigned int find_index(Point*, unsigned int, unsigned int); | ||
| void resort_object(unsigned int); | ||
| void resort(unsigned int, unsigned int); | ||
| unsigned int find_index(Point*); | ||
|
|
||
| public: | ||
| Area(Direction*); | ||
|
|
||
| bool add(Object*); | ||
| bool add(Object*, Point*); | ||
| Object* discard(Object*); | ||
| Object* get(Point*); | ||
| void resort_all() { resort(0, last-1); } | ||
|
|
||
| void set_face(Direction* d) { face = d; } | ||
| }; | ||
|
|
||
| #endif // AREA_H |
| @@ -1,43 +1,133 @@ | ||
| /** | ||
|
|
||
| P R E D E F I N E D T Y P E S | ||
|
|
||
| VISIBLE OBJECTS | ||
| - Form the basic type for anything visible, can't be used on anything | ||
| * fixed flag: can the Form change position? (default = FALSE) | ||
| * x the x-coordinate of the Form | ||
| * y the y-coordinate of the Form | ||
| * sprite the sprite for the Form, as a path | ||
| * lord the thing that contains the Form | ||
| # INIT the Script for when the Form is created | ||
| # LEFT_CLICK the Script for when the Form is left-clicked | ||
| # RIGHT_CLICK the Script for when the Form is right-clicked | ||
| # DRAG_RELEASE the Script for when an Object is dragged onto the Form | ||
| - Menu(Form) container for Widgets | ||
| * vassals the Widgets in the Menu | ||
| # ADD the Script for when an outside call is made to add(Widget), returns TRUE if Widget should be added | ||
| - Widget(Form) buttons, labels, stuff in a Menu | ||
| - Object(Form) an actual object in the game | ||
| - Item(Object) an item of some sort | ||
| - Container(Item) an Item that can store other Items | ||
| * vassals the Items in the Container | ||
| # ADD the Script for when an outside call is made to add(Item), returns TRUE if Item should be added | ||
| - Entity(Object) an Object that has its own agency | ||
| * agent the Agent for the Entity | ||
| - Attired(Entity) an Entity that can put on Items | ||
| * vassals the Items on the Attired | ||
| # ADD the Script for when an outside call is made to add(Item), returns TRUE if Item should be added | ||
|
|
||
| OTHER TYPES | ||
| - Agent : the AI for an Entity | ||
|
|
||
|
|
||
| P R E D E F I N E D V A R S | ||
|
|
||
| this reference to the thing (specific to thing) | ||
| ui the UI, which holds all the Menus | ||
| *drag DRAG_RELEASE parameter, the Object dragged onto the Form | ||
| *addForm ADD parameter, the Form being added | ||
| *addX ADD parameter, the x-coordinate to add the Form at | ||
| *addY ADD parameter, the y-coordinate to add the Form at | ||
|
|
||
|
|
||
| D E F I N I T I O N S | ||
|
|
||
| type inherited type | ||
| params parameters for creating the thing | ||
| constraints constraints for parameters | ||
| scripts defined/overridden Scripts | ||
|
|
||
| **/ | ||
|
|
||
| def Menu { | ||
| scripts { | ||
| ADD { | ||
| return TRUE; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| def containerFormWidget { | ||
| type Widget | ||
| params { | ||
| contX, | ||
| contY | ||
| } | ||
| scripts { | ||
| DRAG_RELEASE { | ||
| lord.access.add( drag, contX, contY ); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| def containerWindow { | ||
| type Menu | ||
| params { | ||
| access | ||
| } | ||
| constraints { | ||
| access.type == Container | ||
| } | ||
| scripts { | ||
| INIT { | ||
| for (i = 0; i < access.width; i++) { | ||
| for (j = 0; j < access.height; j++) { | ||
| add( containerFormWidget( contX = i, contY = j ), 10*i, 10*j ); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| def Item { | ||
| params { | ||
| width, | ||
| height | ||
| } | ||
| scripts { | ||
| RIGHT_CLICK { | ||
| // open a window to view description and actions | ||
| } | ||
| } | ||
| } | ||
|
|
||
| def Container { | ||
| scripts { | ||
| LEFT_CLICK { | ||
| ui.add(containerWindow( access = this )); | ||
| } | ||
| DRAG_RELEASE { | ||
| for (i = 0; i < width; i++) { | ||
| for (j = 0; j < height; j++) { | ||
| if (add(drag, i, j)) { | ||
| return; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ADD { | ||
| for (i = 0; i < vassals.length; i++) { | ||
| if (addX >= vassals[i].x+vassals[i].width || | ||
| addX+addForm.width <= vassals[i].x || | ||
| addY >= vassals[i].y+vassals[i].height || | ||
| addY+addForm.height <= vassals[i].y) { | ||
| return FALSE; | ||
| } | ||
| } | ||
| return TRUE; | ||
| } | ||
| } | ||
| } | ||
|
|
| @@ -40,6 +40,8 @@ void show_error_message(const char* message) { | ||
|
|
||
| State* state; | ||
|
|
||
| State* get_state() { return state; } | ||
|
|
||
| void set_state(State* s) { | ||
| delete state; | ||
| state = s; | ||
| @@ -0,0 +1,15 @@ | ||
| #include <memory> | ||
| #include "form.h" | ||
| #include "script.h" | ||
|
|
||
| Form::Form(Parametrized* p) : Article(p) { | ||
| shape.center = &pos; | ||
| } | ||
|
|
||
| void Form::execute(unsigned int key) { | ||
| std::shared_ptr<Script> s = nullptr;// this->get_param<std::shared_ptr<Script> >(key); | ||
| //get_param<std::shared_ptr<Script> >(key); | ||
| if (s != nullptr) { | ||
| s->execute(); | ||
| } | ||
| } |
| @@ -0,0 +1,25 @@ | ||
| #ifndef FORM_H | ||
| #define FORM_H | ||
|
|
||
| #include <string> | ||
| #include "data.h" | ||
| #include "lord.h" | ||
| #include "geometry.h" | ||
|
|
||
| class Form: public Article { | ||
| protected: | ||
| Lord<Form*, Point*>* lord; | ||
|
|
||
| Point pos; | ||
| Shape shape; | ||
|
|
||
| public: | ||
| Form() {} | ||
| Form(Parametrized*); | ||
|
|
||
| Point* get_pos() { return &pos; } | ||
|
|
||
| void execute(unsigned int); | ||
| }; | ||
|
|
||
| #endif // FORM_H |
| @@ -0,0 +1,102 @@ | ||
| #include <cmath> | ||
| #include "geometry.h" | ||
|
|
||
| /** | ||
| * Returns the relative direction of v with respect to d | ||
| */ | ||
| Direction rel_dir(Direction v, Direction d) { | ||
| return static_cast<Direction>(((int)d-(int)v+10)%8); | ||
| } | ||
|
|
||
| /** | ||
| * Converts Point p to Direction | ||
| */ | ||
| Direction point_to_dir(Point* p) { | ||
| int a = (int)round(atan2(-p->y, p->x)*4/3.1415926535); | ||
| return static_cast<Direction>((a+8)%8); | ||
| } | ||
|
|
||
| /** | ||
| * Converts Direction d to Point | ||
| */ | ||
| Point* dir_to_point(Direction d) { | ||
| Point* p = new Point(); | ||
| if (d >= Direction::NORTHWEST && d <= Direction::SOUTHWEST) { | ||
| p->x = -1; | ||
| } else if ((d >= Direction::EAST && d <= Direction::NORTHEAST) || d == Direction::SOUTHEAST) { | ||
| p->x = 1; | ||
| } | ||
| if (d >= Direction::NORTHEAST && d <= Direction::NORTHWEST) { | ||
| p->y = -1; | ||
| } else if (d >= Direction::SOUTHWEST && d <= Direction::SOUTHEAST) { | ||
| p->y = 1; | ||
| } | ||
| return p; | ||
| } | ||
|
|
||
| /** | ||
| * Returns new Point translated in Direction d by distance dist | ||
| */ | ||
| Point* translate(Point* p, Direction d, int dist) { | ||
| Point* v = dir_to_point(d); | ||
| return new Point(p->x+(dist*v->x), p->y+(dist*v->y), p->z); | ||
| } | ||
|
|
||
| /** | ||
| * Returns 1 if p1 is in front of p2 | ||
| * -1 if p1 is behind p2 | ||
| * 0 if p1 equals p2 relative to dir | ||
| */ | ||
| int compare(Point* p1, Point* p2, Direction dir) { | ||
| if (p1->x == p2->x && p1->y == p2->y && p1->z == p2->z) { return 0; } | ||
| int x1 = p1->x; | ||
| int y1 = p1->y; | ||
| int x2 = p2->x; | ||
| int y2 = p2->y; | ||
| if (dir >= Direction::SOUTH || dir <= Direction::NORTHEAST) { | ||
| x1 = MAX_VALUE-x1; | ||
| x2 = MAX_VALUE-x2; | ||
| } | ||
| if (dir >= Direction::WEST) { | ||
| y1 = MAX_VALUE-y1; | ||
| y2 = MAX_VALUE-y2; | ||
| } | ||
| int v1 = x1+y1; | ||
| int v2 = x2+y2; | ||
| int d = static_cast<int>(dir); | ||
| if (d%2 == 0) { | ||
| if (d%4 == 0) { | ||
| v1 = x1; | ||
| v2 = x2; | ||
| } else { | ||
| v1 = y1; | ||
| v2 = y2; | ||
| } | ||
| } | ||
| if (v1 > v2) { | ||
| return 1; | ||
| } else if (v1 < v2) { | ||
| return -1; | ||
| } else { | ||
| if ((d/2)%2 == 0) { | ||
| v1 = y1; | ||
| v2 = y2; | ||
| } else { | ||
| v1 = x1; | ||
| v2 = x2; | ||
| } | ||
| if (v1 > v2) { | ||
| return 1; | ||
| } else if (v1 < v2) { | ||
| return -1; | ||
| } else { | ||
| if (p1->z > p2->z) { | ||
| return 1; | ||
| } else if (p1->z < p2->z) { | ||
| return -1; | ||
| } else { | ||
| return 0; | ||
| } | ||
| } | ||
| } | ||
| } |
| @@ -0,0 +1,40 @@ | ||
| #ifndef GEOMETRY_H | ||
| #define GEOMETRY_H | ||
|
|
||
| const int MAX_VALUE = 2048; | ||
|
|
||
| enum class Direction : int { | ||
| EAST = 0, | ||
| NORTHEAST = 1, | ||
| NORTH = 2, | ||
| NORTHWEST = 3, | ||
| WEST = 4, | ||
| SOUTHWEST = 5, | ||
| SOUTH = 6, | ||
| SOUTHEAST = 7 | ||
| }; | ||
|
|
||
| struct Point { | ||
| int x; | ||
| int y; | ||
| int z; | ||
| Point() {} | ||
| Point(int a, int b) : x(a%MAX_VALUE), y(b%MAX_VALUE) {} | ||
| Point(int a, int b, int c) : x(a%MAX_VALUE), y(b%MAX_VALUE), z(c%MAX_VALUE) {} | ||
| }; | ||
|
|
||
| struct Shape { | ||
| Point* center; | ||
| int dx; | ||
| int dy; | ||
| int dz; | ||
| }; | ||
|
|
||
| Direction rel_dir(Direction, Direction); | ||
| Direction point_to_dir(Point*); | ||
| Point* dir_to_point(Direction); | ||
| Point* translate(Point*, Direction, int=1); | ||
|
|
||
| int compare(Point*, Point*, Direction=Direction::NORTH); | ||
|
|
||
| #endif // GEOMETRY_H |
| @@ -0,0 +1,25 @@ | ||
| #ifndef INTELLIGENCE_H | ||
| #define INTELLIGENCE_H | ||
|
|
||
| enum class AIMode : int { | ||
| MANUAL = 0, // under manual control of player PC | ||
| ATTACK_SAME = 1, // attacks same target as PC ally | ||
| ATTACK_WEAK = 2, // attacks weakest threat | ||
| ATTACK_STRONG = 3, // attacks strongest threat | ||
| ATTACK_CLOSEST = 4, // attacks closest threat | ||
| PROTECT = 5, // attack anyone who attacks targeted ally | ||
| TARGET = 6, // target a specific enemy enemy | ||
| DISTANCE = 7, // attacks from distance, if possible | ||
| PACIFIST = 8, // don't attack, stay at distance | ||
| FLEE = 9 // don't attack, run away | ||
| }; | ||
|
|
||
| class Agent { | ||
| private: | ||
| AIMode mode; | ||
| public: | ||
| AIMode get_mode() { return mode; } | ||
| void set_mode(AIMode m) { mode = m; } | ||
| }; | ||
|
|
||
| #endif // INTELLIGENCE_H |
| @@ -0,0 +1,23 @@ | ||
| #ifndef LORD_H | ||
| #define LORD_H | ||
|
|
||
| template <class T, class P> | ||
| class Lord { | ||
| protected: | ||
| unsigned int capacity; | ||
| T* vassals; | ||
|
|
||
| public: | ||
| Lord() { | ||
| capacity = 8; | ||
| vassals = new T[capacity]; | ||
| } | ||
|
|
||
| virtual bool add(T) = 0; | ||
| virtual bool add(T, P) = 0; | ||
| virtual T discard(T) = 0; | ||
| virtual T get(P) = 0; | ||
|
|
||
| }; | ||
|
|
||
| #endif // LORD_H |
| @@ -1,73 +1,30 @@ | ||
| #include "module.h" | ||
| #include "loader.h" | ||
|
|
||
| using namespace std; | ||
|
|
||
|
|
||
| shared_ptr<Parametrized> Module::add_data(unsigned int key) { | ||
| shared_ptr<Parametrized> p(new Parametrized()); | ||
| pair<unsigned int, shared_ptr<Parametrized> > q(key, p); | ||
| data.insert(q); | ||
| return p; | ||
| } | ||
|
|
||
| shared_ptr<Parametrized> Module::get_data(unsigned int key) { | ||
| unordered_map<unsigned int, shared_ptr<Parametrized> >::iterator iter = data.find(key); | ||
| if (iter == data.end()) { | ||
| return add_data(key); | ||
| } else { | ||
| return iter->second; | ||
| } | ||
| } | ||
|
|
||
| void Module::load_modules(vector<ALLEGRO_FS_ENTRY*> files) { | ||
| FileLoader loader(this); | ||
| for (vector<ALLEGRO_FS_ENTRY*>::iterator iter = files.begin(); iter < files.end(); ++iter) { | ||
| ALLEGRO_FILE* file = al_open_fs_entry(*iter, "r"); | ||
| loader.load(file); | ||
| // TODO close file | ||
| } | ||
| } |
| @@ -1,29 +1,21 @@ | ||
| #ifndef MODULE_H | ||
| #define MODULE_H | ||
|
|
||
| #include <allegro5/allegro.h> | ||
| #include <memory> | ||
| #include <vector> | ||
| #include <unordered_map> | ||
| #include "data.h" | ||
|
|
||
| class Module { | ||
| private: | ||
| std::unordered_map<unsigned int, std::shared_ptr<Parametrized> > data; | ||
|
|
||
| std::shared_ptr<Parametrized> add_data(unsigned int); | ||
| public: | ||
| std::shared_ptr<Parametrized> get_data(unsigned int); | ||
|
|
||
| void load_modules(std::vector<ALLEGRO_FS_ENTRY*>); | ||
| }; | ||
|
|
||
| #endif // MODULE_H |
| @@ -0,0 +1,43 @@ | ||
| #ifndef OBJECT_H | ||
| #define OBJECT_H | ||
|
|
||
| #include "form.h" | ||
| #include "intelligence.h" | ||
|
|
||
| /** | ||
| * Basic physical object | ||
| */ | ||
| class Object: public Form { | ||
|
|
||
| }; | ||
|
|
||
| /** | ||
| * An inanimate object | ||
| */ | ||
| class Item: public Object { | ||
|
|
||
| }; | ||
|
|
||
| /** | ||
| * An Item that can store other items | ||
| */ | ||
| class Container: public Item, public Lord<Item*, Point*> { | ||
|
|
||
| }; | ||
|
|
||
| /** | ||
| * An animate object with some sort of agency | ||
| */ | ||
| class Entity: public Object { | ||
| private: | ||
| Agent* ai; | ||
| }; | ||
|
|
||
| /** | ||
| * An Entity which can equip items | ||
| */ | ||
| class Attired: public Entity, public Lord<Item*, int> { | ||
|
|
||
| }; | ||
|
|
||
| #endif // OBJECT_H |
| @@ -0,0 +1,130 @@ | ||
| #include "wrapper.h" | ||
|
|
||
| Area* load_area(Area* a, Direction d) { return nullptr; } | ||
|
|
||
| /** | ||
| * Sets a as current Area | ||
| */ | ||
| bool Wrapper::add(Area* a) { | ||
| delete current; | ||
| current = a; | ||
| for (int i = 0; i < 8; i++) { | ||
| delete vassals[i]; | ||
| vassals[i] = load_area(current, static_cast<Direction>(i)); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Sets a as the Area in direction d | ||
| */ | ||
| bool Wrapper::add(Area* a, Direction d) { | ||
| delete vassals[(int)d]; | ||
| vassals[(int)d] = a; | ||
| } | ||
|
|
||
| /** | ||
| * Sets the Area in direction d as current | ||
| */ | ||
| bool Wrapper::add(Direction dir) { | ||
| int d = (int)dir; | ||
| delete vassals[(d+4)%8]; | ||
| vassals[(d+4)%8] = current; | ||
| current = vassals[d]; | ||
| vassals[d] = load_area(current, static_cast<Direction>(d)); | ||
| if (d%2 == 0) { | ||
| delete vassals[(d+3)%8]; | ||
| vassals[(d+3)%8] = vassals[(d+2)%8]; | ||
| vassals[(d+2)%8] = vassals[(d+1)%8]; | ||
| vassals[(d+1)%8] = load_area(current, static_cast<Direction>((d+1)%8)); | ||
| delete vassals[(d+5)%8]; | ||
| vassals[(d+5)%8] = vassals[(d+6)%8]; | ||
| vassals[(d+6)%8] = vassals[(d+7)%8]; | ||
| vassals[(d+7)%8] = load_area(current, static_cast<Direction>((d+7)%8)); | ||
| } else { | ||
| delete vassals[(d+2)%8]; | ||
| vassals[(d+2)%8] = load_area(current, static_cast<Direction>((d+2)%8)); | ||
| delete vassals[(d+3)%8]; | ||
| vassals[(d+3)%8] = vassals[(d+1)%2]; | ||
| vassals[(d+1)%8] = load_area(current, static_cast<Direction>((d+1)%8)); | ||
| delete vassals[(d+5)%8]; | ||
| vassals[(d+5)%8] = vassals[(d+7)%8]; | ||
| vassals[(d+7)%8] = load_area(current, static_cast<Direction>((d+7)%8)); | ||
| delete vassals[(d+6)%8]; | ||
| vassals[(d+6)%8] = load_area(current, static_cast<Direction>((d+6)%8)); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Deletes a | ||
| * Returns NULL | ||
| */ | ||
| Area* Wrapper::discard(Area* a) { | ||
| if (current == a) { delete a; } | ||
| else { | ||
| for (int i = 0; i < 8; i++) { | ||
| if (vassals[i] == a) { | ||
| delete vassals[i]; | ||
| break; | ||
| } | ||
| } | ||
| } | ||
| return NULL; | ||
| } | ||
|
|
||
| /** | ||
| * Retrieves the Area in Direction d | ||
| */ | ||
| Area* Wrapper::get(Direction d) { | ||
| return vassals[(int)d]; | ||
| } | ||
|
|
||
|
|
||
| bool Wrapper::add(Object* o) { | ||
| return add(o, o->get_pos()); | ||
| } | ||
|
|
||
| bool Wrapper::add(Object* o, Point* p) { | ||
| if (p->x >= 0 && p->y >= 0 && p->x < MAX_VALUE && p->y < MAX_VALUE) { | ||
| return current->add(o, p); | ||
| } | ||
| int dx = -1; | ||
| int dy = -1; | ||
| if (p->x < 0) { | ||
| dx = (int)Direction::WEST; | ||
| p->x = (MAX_VALUE+p->x) % MAX_VALUE; | ||
| } else if (p->x >= MAX_VALUE) { | ||
| dx = (int)Direction::EAST; | ||
| p->x = p->x % MAX_VALUE; | ||
| } | ||
| if (p->y < 0) { | ||
| dy = (int)Direction::NORTH; | ||
| p->y = (MAX_VALUE+p->y) % MAX_VALUE; | ||
| } else if (p->y >= MAX_VALUE) { | ||
| dy = (int)Direction::SOUTH; | ||
| p->y = p->y % MAX_VALUE; | ||
| } | ||
| return vassals[((dx < 0) ? dy : ((dy < 0) ? dx : (dx+dy)/2))]->add(o, p); | ||
| } | ||
|
|
||
|
|
||
| /** | ||
| * Rotate view clockwise | ||
| */ | ||
| void Wrapper::c_rotate() { | ||
| face = static_cast<Direction>((6+(int)face)%8); | ||
| current->resort_all(); | ||
| for (int i = 0; i < 8; i++) { | ||
| vassals[i]->resort_all(); | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Rotate view counter-clockwise | ||
| */ | ||
| void Wrapper::cc_rotate() { | ||
| face = static_cast<Direction>((2+(int)face)%8); | ||
| current->resort_all(); | ||
| for (int i = 0; i < 8; i++) { | ||
| vassals[i]->resort_all(); | ||
| } | ||
| } |
| @@ -0,0 +1,32 @@ | ||
| #ifndef WRAPPER_H | ||
| #define WRAPPER_H | ||
|
|
||
| #include "lord.h" | ||
| #include "geometry.h" | ||
| #include "area.h" | ||
| #include "object.h" | ||
|
|
||
| class Wrapper: public Lord<Area*, Direction> { | ||
| private: | ||
| Area* current; | ||
| Point* center; | ||
| Direction face; | ||
|
|
||
| public: | ||
| Wrapper(Area*); | ||
|
|
||
| bool add(Area*); | ||
| bool add(Area*, Direction); | ||
| bool add(Direction); | ||
| Area* discard(Area*); | ||
| Area* get(Direction); | ||
|
|
||
| bool add(Object*); | ||
| bool add(Object*, Point*); | ||
|
|
||
| Direction get_face() { return face; } | ||
| void c_rotate(); | ||
| void cc_rotate(); | ||
| }; | ||
|
|
||
| #endif // WRAPPER_H |