1 #include "rpg.h" 2 3 namespace game 4 { 5 vector<rpgobj *> objects, stack; 6 hashset<char *> names; 7 8 rpgobj *pointingat = NULL; 9 rpgobj *playerobj = NULL; 10 rpgobj *selected = NULL; 11 12 rpgquest *quests = NULL; 13 rpgquest *currentquest = NULL; 14 resetstack()15 void resetstack() 16 { 17 stack.setsize(0); 18 loopi(10) stack.add(playerobj); // determines the stack depth 19 } 20 clearworld()21 void clearworld() 22 { 23 if(playerobj) { playerobj->ent = NULL; delete playerobj; } 24 playerobj = new rpgobj("player"); 25 playerobj->ent = player1; 26 player1->ro = playerobj; 27 28 pointingat = NULL; 29 objects.deletecontents(); 30 resetstack(); 31 32 playerobj->scriptinit(); // will fail when this is called from emptymap(), which is ok 33 } 34 removefromsystem(rpgobj * o)35 void removefromsystem(rpgobj *o) 36 { 37 removefromworld(o); 38 o->decontain(); 39 if(pointingat==o) pointingat = NULL; 40 if(selected==o) selected = NULL; 41 resetstack(); 42 DELETEP(o); 43 } 44 updateobjects()45 void updateobjects() 46 { 47 pointingat = NULL; 48 loopv(objects) 49 { 50 objects[i]->update(); 51 52 float dist = player1->o.dist(objects[i]->ent->o); 53 if(dist<50 && intersect(objects[i]->ent, player1->o, worldpos) && (!pointingat || player1->o.dist(pointingat->ent->o)>dist)) 54 { 55 pointingat = objects[i]; 56 } 57 } 58 } 59 spawn(char * name)60 void spawn(char *name) 61 { 62 rpgobj *o = new rpgobj(name); 63 pushobj(o); 64 o->scriptinit(); 65 } 66 placeinworld(vec & pos,float yaw)67 void placeinworld(vec &pos, float yaw) 68 { 69 stack[0]->placedinworld(new rpgent(stack[0], pos, yaw)); 70 objects.add(stack[0]); 71 } 72 spawnfroment(rpgentity & e)73 void spawnfroment(rpgentity &e) 74 { 75 spawn(e.name); 76 placeinworld(e.o, e.attr1); 77 } 78 pushobj(rpgobj * o)79 void pushobj(rpgobj *o) { stack.pop(); stack.insert(0, o); } // never overflows, just removes bottom popobj()80 void popobj() { stack.add(stack.remove(0)); } // never underflows, just puts it at the bottom 81 removefromworld(rpgobj * worldobj)82 void removefromworld(rpgobj *worldobj) 83 { 84 objects.removeobj(worldobj); 85 DELETEP(worldobj->ent); 86 } 87 taken(rpgobj * worldobj,rpgobj * newowner)88 void taken(rpgobj *worldobj, rpgobj *newowner) 89 { 90 removefromworld(worldobj); 91 newowner->add(worldobj, false); 92 } 93 takefromplayer(char * name,char * ok,char * notok)94 void takefromplayer(char *name, char *ok, char *notok) 95 { 96 rpgobj *o = playerobj->take(name); 97 if(o) 98 { 99 stack[0]->add(o, false); 100 conoutf("\f2you hand over a %s", o->name); 101 if(currentquest) 102 { 103 conoutf("\f2you finish a quest for %s", currentquest->npc); 104 currentquest->completed = true; 105 } 106 } 107 execute(o ? ok : notok); 108 } 109 givetoplayer(char * name)110 void givetoplayer(char *name) 111 { 112 rpgobj *o = stack[0]->take(name); 113 if(o) 114 { 115 conoutf("\f2you receive a %s", o->name); 116 playerobj->add(o, false); 117 } 118 } 119 addquest(const char * questline,const char * npc)120 rpgquest *addquest(const char *questline, const char *npc) 121 { 122 quests = new rpgquest(quests, npc, questline); 123 conoutf("\f2you have accepted a quest for %s", npc); 124 return quests; 125 } 126 listquests(bool completed,g3d_gui & g)127 void listquests(bool completed, g3d_gui &g) 128 { 129 for(rpgquest *q = quests; q; q = q->next) if(q->completed==completed) 130 { 131 defformatstring(info, "%s: %s", q->npc, q->questline); 132 g.text(info, 0xAAAAAA, "info"); 133 } 134 } 135 stringpool(char * name)136 char *stringpool(char *name) 137 { 138 char *exists = names.find(name, NULL); 139 if(exists) return exists; 140 return names.add(newstring(name)); 141 } 142 renderobjects()143 void renderobjects() { loopv(objects) objects[i]->render(); } g3d_npcmenus()144 void g3d_npcmenus() { loopv(objects) objects[i]->g3d_menu(); } 145 146 #define N(n) ICOMMAND(r_##n, "i", (int *val), { stack[0]->s_##n = *val; }); \ 147 ICOMMAND(r_get_##n, "", (), { intret(stack[0]->s_##n); }); 148 149 RPGNAMES 150 #undef N 151 #define N(n) ICOMMAND(r_def_##n, "ii", (int *i1, int *i2), { stats::def_##n(*i1, *i2); }); \ 152 ICOMMAND(r_eff_##n, "", (), { intret(stack[0]->eff_##n()); }); 153 RPGSTATNAMES 154 #undef N 155 156 ICOMMAND(r_model, "s", (char *s), { stack[0]->model = stringpool(s); }); 157 ICOMMAND(r_spawn, "s", (char *s), { spawn(stringpool(s)); }); 158 ICOMMAND(r_contain, "s", (char *s), { stack[0]->decontain(); stack[1]->add(stack[0], atoi(s)); }); 159 ICOMMAND(r_pop, "", (), { popobj(); }); 160 ICOMMAND(r_swap, "", (), { swap(stack[0], stack[1]); }); 161 ICOMMAND(r_say, "s", (char *s), { stack[0]->abovetext = stringpool(s); }); 162 ICOMMAND(r_quest, "ss", (char *s, char *a), { stack[0]->addaction(stringpool(s), stringpool(a), true); }); 163 ICOMMAND(r_action, "ss", (char *s, char *a), { stack[0]->addaction(stringpool(s), stringpool(a), false); }); 164 ICOMMAND(r_action_use, "s", (char *s), { stack[0]->action_use.script = stringpool(s); }); 165 ICOMMAND(r_take, "sss", (char *name, char *ok, char *notok), { takefromplayer(name, ok, notok); }); 166 ICOMMAND(r_give, "s", (char *s), { givetoplayer(s); }); 167 ICOMMAND(r_use, "", (), { stack[0]->selectuse(); }); 168 ICOMMAND(r_applydamage, "i", (int *d), { stack[0]->takedamage(*d, *stack[1]); }); 169 } 170 171