// g0rpg.cpp : Defines the entry point for the console application. #include "stdafx.h" #include "string.h" #include "iostream.h" #include "math.h" #include "time.h" #include "stdlib.h" #define NULL 0 #define NUMBER 1 #define STRING 2 enum comparisontype { LESS = -2, LESSOREQUAL, EQUAL, GREATEROREQUAL, GREATER }; class multitype { public: double val; void* specialval; void* target; int type; multitype() { val = 0; specialval = NULL; target = NULL; type = 0; } }; class quest; class item; template class baseclass { private: char name[255]; public: long index; kind* sub; quest* qsub; item* isub; baseclass() { setName("new"); setIndex(0); sub = NULL; qsub = NULL; isub = NULL; } baseclass(const char* n, long i) { setName(n); setIndex(i); sub = NULL; qsub = NULL; isub = NULL; } long getIndex() { return index; } void setIndex(long i) { index = i; } int setName(const char* c) { if(strcpy(name, c)) return 1; return 0; } char* getName() { return name; } void add(const char* n, long index) { if (sub == NULL) { sub = new(kind); sub->setName(n); sub->setIndex(index); sub->next = sub; sub->prev = sub; return; } else { kind* tempholder; tempholder = sub->next; sub->next = new(kind); sub->next->setName(n); sub->next->setIndex(index); sub->next->prev = sub; sub->next->next = tempholder; tempholder->prev = sub->next; } } long count() { long counter = 0; long indexholder = 0; if (sub == NULL) return 0; indexholder = sub->getIndex(); counter++; while (sub->next->getIndex() != indexholder) { sub = sub->next; counter++; } sub = sub->next; return counter; } void move(long n) { if (n > 0) for (int i = 0; i < n; i++) sub = sub->next; if (n < 0) for (int i = 0; i > n; i--) sub = sub->prev; } bool moveTo(long index) { //0 for fail for (int i=0; i < count(); i++) { sub = sub->next; if (sub->getIndex() == index) return true; } return false; } bool moveTo(const char* c) { //0 for fail //not necessarily unique for (int i=0; i < count(); i++) { sub = sub->next; if (!strcmp(sub->getName(), c)) return true; } return false; } long qcount() { long counter = 0; long indexholder = 0; if (qsub == NULL) return 0; indexholder = qsub->getIndex(); counter++; while (qsub->next->getIndex() != indexholder) { qsub = qsub->next; counter++; } qsub = qsub->next; return counter; } void qadd(const char* n, long index) { if (qsub == NULL) { qsub = new(quest); qsub->setName(n); qsub->setIndex(index); qsub->next = qsub; qsub->prev = qsub; return; } else { quest* tempholder; tempholder = qsub->next; qsub->next = new(quest); qsub->next->setName(n); qsub->next->setIndex(index); qsub->next->prev = qsub; qsub->next->next = tempholder; tempholder->prev = qsub->next; } } void qremove() { if (qsub == qsub->next) { qsub = NULL; } else { qsub->prev->next = qsub->next; qsub->next->prev = qsub->prev; qsub = qsub->next; } } void qmove(long n) { if (n > 0) for (int i = 0; i < n; i++) qsub = qsub->next; if (n < 0) for (int i = 0; i > n; i--) qsub = qsub->prev; } bool qmoveTo(long index) { //0 for fail for (int i=0; i < qcount(); i++) { qsub = qsub->next; if (qsub->getIndex() == index) return true; } return false; } bool qmoveTo(const char* c) { //0 for fail //not necessarily unique for (int i=0; i < qcount(); i++) { qsub = qsub->next; if (!strcmp(qsub->getName(), c)) return true; } return false; } void checkQuests() { for (int i=0; i < count(); i++) { sub->checkQuests(); move(1); } for (i=0; i < qcount(); i++) { if (qsub->giveReward()) { qremove(); } else { qmove(1); } } } void viewQuests() { for (int i=0; i < qcount(); i++) { cout << qsub->getName() << endl; qmove(1); } cout << endl; } void iadd(const char* n, long index) { if (isub == NULL) { isub = new(item); isub->setName(n); isub->setIndex(index); isub->next = isub; isub->prev = isub; return; } else { item* tempholder; tempholder = isub->next; isub->next = new(item); isub->next->setName(n); isub->next->setIndex(index); isub->next->prev = isub; isub->next->next = tempholder; tempholder->prev = isub->next; } } void imove(long n) { if (n > 0) for (int i = 0; i < n; i++) isub = isub->next; if (n < 0) for (int i = 0; i > n; i--) isub = isub->prev; } long icount() { long counter = 0; long indexholder = 0; if (isub == NULL) return 0; indexholder = isub->getIndex(); counter++; while (isub->next->getIndex() != indexholder) { isub = isub->next; counter++; } isub = isub->next; return counter; } }; class quest : public baseclass { public: quest* next; quest* prev; multitype goal; multitype reward; comparisontype comp; quest() { next = NULL; prev = NULL; comp = EQUAL; } void setGoal(double g, void* t, void* sg, int datatype, comparisontype c) { if (datatype == NUMBER) goal.val = g; if (datatype == STRING) goal.specialval = sg; goal.type = datatype; goal.target = t; comp = c; } void setReward(double r, void* t, void* sr, int datatype) { if (datatype == NUMBER) reward.val = r; if (datatype == STRING) reward.specialval = sr; reward.target = t; reward.type = datatype; } bool isSatisfied() { if (comp == EQUAL) { if (goal.target) if ( *(double*)goal.target == goal.val ) return 1; } if (comp == GREATEROREQUAL) { if (goal.target) if ( *(double*)goal.target >= goal.val ) return 1; } if (comp == LESSOREQUAL) { if (goal.target) if ( *(double*)goal.target <= goal.val ) return 1; } if (comp == GREATER) { if (goal.target) if ( *(double*)goal.target > goal.val ) return 1; } if (comp == LESS) { if (goal.target) if ( *(double*)goal.target < goal.val ) return 1; } return 0; } bool giveReward() { if (isSatisfied()) { if (reward.type == NUMBER) (*((double*)reward.target)) += reward.val; cout << "Quest: " << getName() << " completed." << endl; return 1; } else return 0; } }; class expclass { private: double exp; bool autolevelup; double levs[99]; public: double lev; expclass() { lev = 0; exp = 0; autolevelup = true; for (long i = 0; i < 100; i++) { levs[i] = (long)(100*i+pow(1.13,i+50)-450); } } double getLev() { return lev; } double setLev(long l) { lev = l; } double getExp() { return exp; } double setExp(long e) { exp = e; } void addExp(long e) { exp += e; bool verbose = true; //set default verbosity for addExp if (autolevelup) if (isLevelUp()) levelUp(verbose); } double expLeft() { if (exp < levs[(long)lev+1]) return (levs[(long)lev+1]-exp); return 0; } bool isLevelUp() { if (expLeft() <= 0) return 1; return 0; } double levelUp() { while(expLeft() <= 0) lev++; return lev; } double levelUp(bool verbose) { while(expLeft() <= 0) { lev++; if (verbose) cout << "Level up! Now on level: " << lev << endl; } return lev; } }; class item : public baseclass { public: item* next; item* prev; double att; double def; double wis; item() { att = 0; def = 0; wis = 0; next = NULL; prev = NULL; } void setItem(double a, double d, double w) { att = a; def = d; wis = w; } }; class creature : public baseclass { public: double hpmax; double hp; double str; double dex; double wis; double gold; expclass exp; creature* next; creature* prev; creature() { hpmax = rand()%100; hp = hpmax; str = rand()%20; dex = rand()%20; wis = rand()%20; gold = rand()%1000; exp.lev = 0; } creature(const char* c, long i, double h, double s, double d, double w, long g) { setName(c); setIndex(i); hpmax = h; hp = h; str = s; dex = d; wis = w; gold = g; exp.lev = 0; } double getHp() { return hp; } void setHp(long l) { hp = l; } double getStr() { return str; } void setStr(long l) { str = l; } double getDex() { return dex; } void setDex(long l) { dex = l; } double getWis() { return wis; } void setWis(long l) { wis = l; } double getLev() { return exp.getLev(); } double setLev(long l) { exp.setLev(l); } double getExp() { return exp.getExp(); } double setExp(long e) { exp.setExp(e); } void addExp(long e) { exp.addExp(e); } double expLeft() { return exp.expLeft(); } bool isLevelUp() { return exp.isLevelUp(); } double levelUp() { return exp.levelUp(); } double levelUp(bool verbose) { return exp.levelUp(verbose); } void status() { cout << getName() << endl; cout << "Level: " << getLev() << endl; cout << "Experience: " << getExp() << endl; cout << "Exp left: " << expLeft() << endl; cout << "Hp: " << hp << endl; cout << "Str: " << str << endl; cout << "Dex: " << dex << endl; cout << "Wis: " << wis << endl; cout << "Gold: " << gold << endl; cout << endl; } void viewInv() { for (int i=0; i < icount(); i++) { cout << "Name: " << isub->getName() << endl; cout << "Attack bonus: " << isub->att << endl; cout << "Defense bonus: " << isub->def << endl; cout << "Magic bonus: " << isub->wis << endl; cout << endl; imove(1); } } }; class team : public baseclass { public: team* next; team* prev; double gold; team() { gold = 0; } void update() { gold = 0; for (int i = 0; i < count(); i++) { gold += sub->gold; move(1); } } void status() { cout << "Party name: " << getName() << endl; cout << "Party gold: " << gold << endl; cout << "Members: " << count() << endl << endl; for (int i = 0; i < count(); i++) { cout << sub->getName() << endl; cout << "Level: " << sub->getLev() << endl; cout << "Experience: " << sub->getExp() << endl; cout << "Exp left: " << sub->expLeft() << endl; cout << "Hp: " << sub->hp << endl; cout << "Str: " << sub->str << endl; cout << "Dex: " << sub->dex << endl; cout << "Wis: " << sub->wis << endl; cout << "Gold: " << sub->gold << endl; cout << endl; move(1); } } }; class level : public baseclass { public: level* next; level* prev; long menu(long n) { int action = 0; if (strcmp(getName(),"Castle") == 0) { do { cout << n << ") View Level Info" << endl; cout << n+1 << ") View Level Quests" << endl; cout << n+2 << ") Go to bank" << endl; } while (action != 0); } return action; } long menuaction(long n) { int i; //general menu choices for all levels switch (n) { case 7: cout << "Parties in " << getName() << ":" << endl; for (i=0; i < count(); i++) { cout << sub->getName() << endl; move(1); } cout << endl; break; case 8: cout << "Quest(s) available in " << getName() << ":" << endl; for (i=0; i < qcount(); i++) { cout << qsub->getName() << endl; qmove(1); } cout << endl; break; } //specific menu choices switch (n) { case 9: cout << "Bank" << endl; cout << "Your party has " << sub->gold << " gold" << endl; cout << endl; break; } return n; } }; class area : public baseclass { public: area* next; area* prev; }; void commonmenu() { cout << "Menu" << endl; cout << "1) View Current Player Info" << endl; cout << "2) View Inventory" << endl; cout << "3) View Party" << endl; cout << "4) View Quests" << endl; cout << "5) Change Current Player" << endl; cout << "6) Raise Level" << endl; } int main(int argc, char* argv[]) { cout << "g0rpg v0.00" << endl; srand( (unsigned)time( NULL ) ); baseclass w("World", 0); area* a; level* l; team* t; creature* c; item* u; w.add("Town", w.count()); w.add("Forest", w.count()); w.add("Mountain", w.count()); w.add("Dungeon", w.count()); w.moveTo("Town"); a = w.sub; a->add("Castle", a->count()); a->moveTo("Castle"); l = a->sub; l->add("Party1", l->count()); l->moveTo("Party1"); t = l->sub; t->add("Player1", t->count()); c = t->sub; c->qadd("Level 5 Attainment Quest", c->qcount()); c->qsub->setGoal(5, &(c->exp.lev), 0, NUMBER, GREATEROREQUAL); c->qsub->setReward(1000, &(c->gold), 0, NUMBER); t->add("Player2", t->count()); t->move(1); c = t->sub; c->qadd("Strength Attainment Quest", c->qcount()); c->qsub->setGoal(25, &(c->str), 0, NUMBER, GREATEROREQUAL); c->qsub->setReward(10000, &(c->gold), 0, NUMBER); long action = 0; //main loop do { a->checkQuests(); l->checkQuests(); t->update(); t->checkQuests(); commonmenu(); l->menu(7); cout << "0) Quit" << endl; cout << "> "; cin >> action; cout << endl; switch (action) { case 1: t->sub->status(); break; case 2: t->sub->viewInv(); break; case 3: t->status(); break; case 4: t->sub->viewQuests(); break; case 5: t->move(1); break; case 6: t->sub->exp.lev++; } if (action > 6) l->menuaction(action); } while (action); return 0; }