aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorfusion32 <marcopuzziello@gmail.com>2025-05-18 14:28:29 -0300
committerfusion32 <marcopuzziello@gmail.com>2025-05-18 14:28:29 -0300
commit9b1af981f8d999df9e005213024be8e7fd7031ff (patch)
tree5a39724c6aff16f4cfc104586b8a11c086ad6a6a
parentdc2aa9a98c7911212a43f254eac83b9143a80522 (diff)
downloadgame-9b1af981f8d999df9e005213024be8e7fd7031ff.tar.gz
game-9b1af981f8d999df9e005213024be8e7fd7031ff.zip
implement `vector`
-rw-r--r--TODO.md3
-rw-r--r--src/vector.hh129
2 files changed, 130 insertions, 2 deletions
diff --git a/TODO.md b/TODO.md
index 222b21c..3c966d4 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,6 +1,5 @@
## TODO NEXT
-- ALL TSkill structures
-- vector container (?)
+- priority_queue (?)
- TCreature
- TPlayer
- TNonPlayer
diff --git a/src/vector.hh b/src/vector.hh
new file mode 100644
index 0000000..5c59d2c
--- /dev/null
+++ b/src/vector.hh
@@ -0,0 +1,129 @@
+#ifndef TIBIA_VECTOR_HH_
+#define TIBIA_VECTOR_HH_ 1
+
+#include "main.hh"
+
+// NOTE(fusion): What the actual fuck. This is an ever growing dynamic array
+// with each access through `operator()` growing it to make sure the requested
+// index is valid, even for negative indices.
+template<typename T>
+struct vector{
+ // REGULAR FUNCTIONS
+ // =========================================================================
+ vector(int min, int max, int block){
+ int space = (max - min) + 1;
+ if(space < 1){
+ error("vector: Ungueltige Feldgroesse %d bis %d.\n", min, max);
+ space = 1;
+ }
+
+ if(block < 0){
+ error("vector: Ungueltige Blockgroesse %d.\n", block);
+ block = 0;
+ }
+
+ this->min = min;
+ this->max = max;
+ this->start = min;
+ this->space = space;
+ this->block = block;
+ this->initialized = false;
+ this->entry = new T[this->space];
+ }
+
+ vector(int min, int max, int block, T init) : vector(min, max, block) {
+ this->initialized = true;
+ this->init = init;
+ for(int i = 0; i < this->space; i += 1){
+ this->entry[i] = init;
+ }
+ }
+
+ T *operator(int index){
+ // TODO(fusion): This is probably not the best way to achieve this.
+
+ while(index < this->start){
+ int increment = this->block;
+ if(increment == 0){
+ increment = this->space;
+ }
+
+ T *entry = new T[this->space + increment];
+ for(int i = this->min; i <= this->max; i += 1){
+ int old_index = i - this->start;
+ int new_index = old_index + increment;
+
+ // TODO(fusion): Do we actually need to swap elements here? I'm
+ // assuming some non-trivial structures that would invoke their
+ // destructors when `this->entry` gets deleted just below.
+ {
+ T tmp = entry[new_index];
+ entry[new_index] = this->entry[old_index];
+ this->entry[old_index] = tmp;
+ }
+ }
+
+ if(this->entry != NULL){
+ delete[] this->entry;
+ }
+ this->entry = entry;
+ this->start -= increment;
+ this->space += increment;
+ }
+
+ while(index >= (this->start + this->space)){
+ int increment = this->block;
+ if(increment == 0){
+ increment = this->space;
+ }
+
+ T *entry = new[this->space + increment];
+ for(int i = this->min; i <= this->max; i += 1){
+ int old_index = i - this->start;
+ int new_index = old_index;
+
+ // TODO(fusion): Same as above.
+ {
+ T tmp = entry[new_index];
+ entry[new_index] = this->entry[old_index];
+ this->entry[old_index] = tmp;
+ }
+ }
+
+ if(this->entry != NULL){
+ delete[] this->entry;
+ }
+ this->entry = entry;
+ this->space += increment;
+ }
+
+ while(index < this->min){
+ this->min -= 1;
+ if(this->initialized){
+ this->entry[this->min - this->start] = this->init;
+ }
+ }
+
+ while(index > this->max){
+ this->max += 1;
+ if(this->initialized){
+ this->entry[this->max - this->start] = this->init;
+ }
+ }
+
+ return &this->entry[index - this->start];
+ }
+
+ // DATA
+ // =========================================================================
+ int min;
+ int max;
+ int start;
+ int space;
+ int block;
+ bool initialized;
+ T init;
+ T *entry;
+};
+
+#endif //TIBIA_VECTOR_HH_