--- orig/rpggame/entities.h
+++ mod/rpggame/entities.h
@@ -6,7 +6,7 @@
 struct rpgentity : extentity
 {
     char name[SPAWNNAMELEN];
-    
+
     rpgentity() { memset(name, 0, SPAWNNAMELEN); }
 };
 
@@ -19,7 +19,7 @@
     ~rpgentities() {}
     rpgentities(rpgclient &_cl) : cl(_cl), lastcreated(NULL)
     {
-        CCOMMAND(spawnname, "s", (rpgentities *self, char *s), { if(self->lastcreated) { s_strncpy(self->lastcreated->name, s, SPAWNNAMELEN); self->spawnfroment(*self->lastcreated); } });    
+        CCOMMAND(spawnname, "s", (rpgentities *self, char *s), { if(self->lastcreated) { s_strncpy(self->lastcreated->name, s, SPAWNNAMELEN); self->spawnfroment(*self->lastcreated); } });
     }
 
     vector<extentity *> &getents() { return (vector<extentity *> &)ents; }
@@ -53,13 +53,13 @@
                 e.attr1 = (int)cl.player1.yaw;
         }
     }
-    
+
     void spawnfroment(rpgentity &e)
     {
         cl.os.spawn(e.name);
-        cl.os.placeinworld(e.o, e.attr1);      
+        cl.os.placeinworld(e.o, e.attr1);
     }
-    
+
     void startmap()
     {
         lastcreated = NULL;
--- orig/rpggame/rpg.cpp
+++ mod/rpggame/rpg.cpp
@@ -19,19 +19,19 @@
     rpgentities et;
     rpgdummycom cc;
     rpgobjset os;
-    
+
     rpgent player1;
 
     int lastmillis, maptime;
     string mapname;
-      
+
     int menutime, menutab, menuwhich;
     vec menupos;
 
     rpgclient() : et(*this), os(*this), player1(os.playerobj, *this, vec(0, 0, 0), 0, 100, ENT_PLAYER), lastmillis(0), maptime(0), menutime(0), menutab(1), menuwhich(0)
     {
-        CCOMMAND(map, "s", (rpgclient *self, char *s), load_world(s));    
-        CCOMMAND(showplayergui, "i", (rpgclient *self, int *which), self->showplayergui(*which));    
+        CCOMMAND(map, "s", (rpgclient *self, char *s), load_world(s));
+        CCOMMAND(showplayergui, "i", (rpgclient *self, int *which), self->showplayergui(*which));
     }
     ~rpgclient() {}
 
@@ -48,7 +48,7 @@
         player1.updateplayer(curtime, pos);
         checktriggers();
     }
-    
+
     void showplayergui(int which)
     {
         if((menutime && which==menuwhich) || !which)
@@ -58,7 +58,7 @@
         else
         {
             menutime = starttime();
-            menupos  = menuinfrontofplayer();        
+            menupos  = menuinfrontofplayer();
             menuwhich = which;
         }
     }
@@ -73,12 +73,12 @@
                 g.tab("inventory", 0xFFFFF);
                 os.playerobj->invgui(g);
                 break;
-            
+
             case 2:
                 g.tab("stats", 0xFFFFF);
                 os.playerobj->st_show(g);
                 break;
-            
+
             case 3:
                 g.tab("active quests", 0xFFFFF);
                 os.listquests(false, g);
@@ -87,17 +87,17 @@
         }
         g.end();
     }
-    
+
     void initclient() {}
-        
+
     void physicstrigger(physent *d, bool local, int floorlevel, int waterlevel, int material)
     {
         if     (waterlevel>0) playsoundname("free/splash1", d==&player1 ? NULL : &d->o);
         else if(waterlevel<0) playsoundname("free/splash2", d==&player1 ? NULL : &d->o);
         if     (floorlevel>0) { if(local) playsoundname("aard/jump"); else if(d->type==ENT_AI) playsoundname("aard/jump", &d->o); }
-        else if(floorlevel<0) { if(local) playsoundname("aard/land"); else if(d->type==ENT_AI) playsoundname("aard/land", &d->o); }    
+        else if(floorlevel<0) { if(local) playsoundname("aard/land"); else if(d->type==ENT_AI) playsoundname("aard/land", &d->o); }
     }
-    
+
     void edittrigger(const selinfo &sel, int op, int arg1 = 0, int arg2 = 0, int arg3 = 0) {}
     char *getclientmap() { return mapname; }
     void resetgamestate() {}
@@ -113,7 +113,7 @@
         if(*name) os.playerobj->st_init();
         et.startmap();
     }
-    
+
     void quad(int x, int y, int xs, int ys)
     {
         glBegin(GL_QUADS);
@@ -123,28 +123,28 @@
         glTexCoord2f(0, 1); glVertex2i(x,    y+ys);
         glEnd();
     }
-    
+
     void gameplayhud(int w, int h)
     {
         glLoadIdentity();
         glOrtho(0, w*2, h*2, 0, -1, 1);
-        draw_textf("using: %s", 636*2, h*2-256+149, os.selected ? os.selected->name : "(none)");       // temp     
-                                            
+        draw_textf("using: %s", 636*2, h*2-256+149, os.selected ? os.selected->name : "(none)");       // temp
+
         glLoadIdentity();
         glOrtho(0, w, h, 0, -1, 1);
         settexture("data/hud_rpg.png", true);
-        
+
         glEnable(GL_BLEND);
         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-        quad(0, h-128, 768, 128);        
+        quad(0, h-128, 768, 128);
         settexture("data/hbar.png", true);
         glColor4f(1, 0, 0, 0.5f);
-        quad(130, h-128+57, 193*os.playerobj->s_hp/os.playerobj->eff_maxhp(), 17);        
+        quad(130, h-128+57, 193*os.playerobj->s_hp/os.playerobj->eff_maxhp(), 17);
         glColor4f(0, 0, 1, 0.5f);
-        quad(130, h-128+87, 193*os.playerobj->s_mana/os.playerobj->eff_maxmana(), 17);        
+        quad(130, h-128+87, 193*os.playerobj->s_mana/os.playerobj->eff_maxmana(), 17);
         glDisable(GL_BLEND);
     }
-    
+
     void drawhudmodel(int anim, float speed = 0, int base = 0)
     {
         rendermodel(NULL, "hudguns/fist", anim, player1.o, player1.yaw+90, player1.pitch, MDL_LIGHT, NULL, NULL, base, speed);
@@ -175,7 +175,7 @@
         if(isthirdperson()) renderclient(&player1, "monster/ogro", NULL, ANIM_PUNCH, 300, player1.lastaction, player1.lastpain);
         os.render();
     }
-    
+
     void g3d_gamemenus() { os.g3d_npcmenus(); if(menutime) g3d_addgui(this, menupos, GUI_2D); }
 
     void writegamedata(vector<char> &extras) {}
@@ -188,8 +188,8 @@
     const char *autoexec()      { return "rpg_autoexec.cfg"; }
 };
 
-#define N(n) int rpgclient::stats::pointscale_##n, rpgclient::stats::percentscale_##n; 
-RPGSTATNAMES 
+#define N(n) int rpgclient::stats::pointscale_##n, rpgclient::stats::percentscale_##n;
+RPGSTATNAMES
 #undef N
 
 REGISTERGAME(rpggame, "rpg", new rpgclient(), new rpgdummyserver());
--- orig/rpggame/rpgent.h
+++ mod/rpggame/rpgent.h
@@ -5,23 +5,23 @@
 
     int lastaction, lastpain;
     bool attacking;
-    
+
     bool magicprojectile;
     vec mppos, mpdir;
     rpgobj *mpweapon;
     float mpdist;
-    
+
     rpgent *enemy;
-    
+
     enum { R_STARE, R_ROAM, R_SEEK, R_ATTACK, R_BLOCKED, R_BACKHOME };
     int npcstate;
-    
+
     int trigger;
 
     float sink;
 
     vec home;
-        
+
     enum { ROTSPEED = 200 };
 
     rpgent(rpgobj *_ro, rpgclient &_cl, const vec &_pos, float _yaw, int _maxspeed = 40, int _type = ENT_AI) : ro(_ro), cl(_cl), lastaction(0), lastpain(0), attacking(false), magicprojectile(false), enemy(NULL), npcstate(R_STARE), trigger(0), sink(0)
@@ -40,20 +40,20 @@
 
     void tryattackobj(rpgobj &eo, rpgobj &weapon)
     {
-        if(!eo.s_ai || (eo.s_ai==ro->s_ai && eo.ent!=enemy)) return;    
-        
+        if(!eo.s_ai || (eo.s_ai==ro->s_ai && eo.ent!=enemy)) return;
+
         rpgent &e = *eo.ent;
         if(e.state!=CS_ALIVE) return;
 
         vec d = e.o;
         d.sub(o);
         d.z = 0;
-        if(d.magnitude()>e.radius+weapon.s_maxrange) return; 
+        if(d.magnitude()>e.radius+weapon.s_maxrange) return;
 
         if(o.z+aboveeye<=e.o.z-e.eyeheight || o.z-eyeheight>=e.o.z+e.aboveeye) return;
 
         vec p(0, 0, 0), closep;
-        float closedist = 1e10f; 
+        float closedist = 1e10f;
         loopj(ATTACKSAMPLES)
         {
             p.x = e.xradius * cosf(2*M_PI*j/ATTACKSAMPLES);
@@ -72,15 +72,15 @@
 
         if(closedist>weapon.s_maxrange*weapon.s_maxrange) return;
 
-        weapon.useaction(eo, *this, true);   
+        weapon.useaction(eo, *this, true);
     }
-    
-    #define loopallrpgobjsexcept(ro) loop(i, cl.os.set.length()+1) for(rpgobj *eo = i ? cl.os.set[i-1] : cl.os.playerobj; eo; eo = NULL) if((ro)!=eo) 
+
+    #define loopallrpgobjsexcept(ro) loop(i, cl.os.set.length()+1) for(rpgobj *eo = i ? cl.os.set[i-1] : cl.os.playerobj; eo; eo = NULL) if((ro)!=eo)
 
     void tryattack(vec &lookatpos, rpgobj &weapon)
-    {                
+    {
         if(cl.lastmillis-lastaction<weapon.s_attackrate) return;
-        
+
         lastaction = cl.lastmillis;
 
         switch(weapon.s_usetype)
@@ -90,7 +90,7 @@
                 weapon.usesound(this);
                 loopallrpgobjsexcept(ro) tryattackobj(*eo, weapon);
                 break;
-            
+
             case 2:
             {
                 if(!weapon.s_damage) return;
@@ -112,15 +112,15 @@
                         bestdist = dist;
                     }
                 }
-                if(best) weapon.useaction(*best, *this, true);  
+                if(best) weapon.useaction(*best, *this, true);
                 break;
-            }   
-            case 3:                
+            }
+            case 3:
                 if(weapon.s_maxrange)   // projectile, cast on target
                 {
                     if(magicprojectile) return;     // only one in the air at once
                     if(!ro->usemana(weapon)) return;
-                                       
+
                     magicprojectile = true;
                     mpweapon = &weapon;
                     mppos = o;
@@ -132,22 +132,22 @@
                 else
                 {
                     weapon.useaction(*ro, *this, true);   // cast on self
-                }                
+                }
                 break;
         }
-        
+
     }
 
     void updateprojectile(int curtime)
     {
         if(!magicprojectile) return;
-        
+
         regular_particle_splash(1, 2, 300, mppos);
-        particle_splash(mpweapon->s_effect, 1, 1, mppos);    
+        particle_splash(mpweapon->s_effect, 1, 1, mppos);
 
         float dist = curtime/5.0f;
         if((mpdist -= dist)<0) { magicprojectile = false; return; };
-        
+
         vec mpto = vec(mpdir).mul(dist).add(mppos);
 
         loopallrpgobjsexcept(ro)     // FIXME: make fast "give me all rpgobs in range R that are not X" function
@@ -158,52 +158,52 @@
                 mpweapon->useaction(*eo, *this, false);    // cast on target
             }
         }
-        
-        mppos = mpto;  
+
+        mppos = mpto;
     }
 
-    void transition(int _state, int _moving, int n) 
+    void transition(int _state, int _moving, int n)
     {
         npcstate = _state;
         move = _moving;
         trigger = cl.lastmillis+n;
     }
-    
+
     void gotoyaw(float yaw, int s, int m, int t)
     {
-        targetyaw = yaw;            
+        targetyaw = yaw;
         rotspeed = ROTSPEED;
-        transition(s, m, t);            
+        transition(s, m, t);
     }
-    
+
     void gotopos(vec &pos, int s, int m, int t) { gotoyaw(vecyaw(pos), s, m, t); }
-    
+
     void goroam()
     {
         if(home.dist(o)>128 && npcstate!=R_BACKHOME)  gotopos(home, R_ROAM, 1, 1000);
-        else                                          gotoyaw(targetyaw+90+rnd(180), R_ROAM, 1, 1000);                                       
+        else                                          gotoyaw(targetyaw+90+rnd(180), R_ROAM, 1, 1000);
     }
-    
+
     void stareorroam()
     {
         if(rnd(10)) transition(R_STARE, 0, 500);
-        else goroam();    
+        else goroam();
     }
-    
+
     void update(int curtime, float playerdist)
     {
         updateprojectile(curtime);
 
         if(state==CS_DEAD) { stopmoving(); return; };
 
-        if(blocked && npcstate!=R_BLOCKED && npcstate!=R_SEEK)                                                             
+        if(blocked && npcstate!=R_BLOCKED && npcstate!=R_SEEK)
         {
             blocked = false;
-            gotoyaw(targetyaw+90+rnd(180), R_BLOCKED, 1, 1000);                           
+            gotoyaw(targetyaw+90+rnd(180), R_BLOCKED, 1, 1000);
         }
-                
-        if(ro->s_hp<ro->eff_maxhp() && npcstate!=R_SEEK) gotopos(enemy->o, R_SEEK,  1, 200);   
-        
+
+        if(ro->s_hp<ro->eff_maxhp() && npcstate!=R_SEEK) gotopos(enemy->o, R_SEEK,  1, 200);
+
         #define ifnextstate   if(trigger<cl.lastmillis)
         #define ifplayerclose if(playerdist<64)
 
@@ -213,7 +213,7 @@
             case R_BACKHOME:
                 ifnextstate goroam();
                 break;
-        
+
             case R_STARE:
                 ifplayerclose
                 {
@@ -222,12 +222,12 @@
                 }
                 else ifnextstate stareorroam();
                 break;
-            
+
             case R_ROAM:
                 ifplayerclose    transition(R_STARE, 0, 500);
                 else ifnextstate stareorroam();
                 break;
-                
+
             case R_SEEK:
                 ifnextstate
                 {
@@ -241,7 +241,7 @@
                     else gotopos(enemy->o, R_SEEK, 1, 100);
                 }
         }
-        
+
         #undef ifnextstate
         #undef ifplayerclose
     }
@@ -269,6 +269,6 @@
             moveplayer(this, 20, true);
             ro->st_update(cl.lastmillis);
             if(attacking) tryattack(lookatpos, ro->selectedweapon());
-        }            
+        }
     }
 };
--- orig/rpggame/rpgobj.h
+++ mod/rpggame/rpgobj.h
@@ -6,7 +6,7 @@
     const char *npc;
     const char *questline;
     bool completed;
-    
+
     rpgquest(rpgquest *_n, const char *_npc, const char *_ql) : next(_n), npc(_npc), questline(_ql), completed(false) {}
 };
 
@@ -58,14 +58,14 @@
     };
 
     int itemflags;
-    
+
     rpgaction *actions, action_use;
-    char *abovetext;    
+    char *abovetext;
 
     int menutime, menutab, menuwhich;
 
     rpgobjset &os;
-    
+
     #define loopinventory() for(rpgobj *o = inventory; o; o = o->sibling)
     #define loopinventorytype(T) loopinventory() if(o->itemflags&(T))
 
@@ -87,7 +87,7 @@
         execute(aliasname);
     }
 
-    void decontain() 
+    void decontain()
     {
         if(parent) parent->remove(this);
     }
@@ -98,20 +98,20 @@
         o->parent = this;
         inventory = o;
         o->itemflags = itemflags;
-        
+
         if(itemflags&IF_INVENTORY) recalcstats();
     }
 
     void remove(rpgobj *o)
     {
         for(rpgobj **l = &inventory; *l; )
-            if(*l==o) 
+            if(*l==o)
             {
                 *l = o->sibling;
                 o->sibling = o->parent = NULL;
             }
             else l = &(*l)->sibling;
-            
+
         if(o->itemflags&IF_INVENTORY) recalcstats();
     }
 
@@ -120,14 +120,14 @@
         st_reset();
         loopinventorytype(IF_INVENTORY) st_accumulate(*o);
     }
-    
+
     rpgobj &selectedweapon()
     {
         if(this==os.playerobj) return os.selected ? *os.selected : *this;
         else { loopinventorytype(IF_INVENTORY) if(o->s_usetype) return *o; };
         return *this;
     }
-    
+
     void placeinworld(rpgent *_ent)
     {
         if(!model) model = "tentus/moneybag";
@@ -140,7 +140,7 @@
 
     void render()
     {
-        if(s_ai) 
+        if(s_ai)
         {
             float sink = 0;
             if(ent->physstate>=PHYS_SLIDE)
@@ -195,15 +195,15 @@
         }
         return NULL;
     }
-    
+
     void takedamage(int damage, rpgobj &attacker)
     {
         ent->enemy = attacker.ent;
-        
+
         particle_splash(3, damage*5, 1000, ent->o);
         s_sprintfd(ds)("@%d", damage);
         particle_text(ent->o, ds, 8);
-        
+
         if((s_hp -= damage)<=0)
         {
             s_hp = 0;
@@ -213,14 +213,14 @@
             menutime = 0;
             conoutf("%s killed: %s", attacker.name, name);
             droploot();
-        }    
+        }
     }
-    
+
     void usesound(rpgent *user)
     {
-        if(s_usesound) playsound(s_usesound, &user->o);    
+        if(s_usesound) playsound(s_usesound, &user->o);
     }
-    
+
     bool usemana(rpgobj &o)
     {
         if(o.s_manacost>s_mana) { if(this==os.playerobj) conoutf("\f2not enough mana"); return false; };
@@ -228,29 +228,29 @@
         o.usesound(ent);
         return true;
     }
-        
+
     void useaction(rpgobj &target, rpgent &initiator, bool chargemana)
     {
         if(action_use.script && (!chargemana || initiator.ro->usemana(*this)))
         {
             action_use.exec(this, &target, initiator.ro, os);
             if(s_useamount && !--s_useamount) os.removefromsystem(this);
-        } 
+        }
     }
-    
+
     void selectuse()
     {
         if(s_usetype)
         {
             conoutf("\f2using: %s", name);
-            os.selected = this;                    
+            os.selected = this;
         }
         else
         {
             useaction(*os.playerobj, *os.playerobj->ent, true);
         }
     }
-    
+
     void guiaction(g3d_gui &g, rpgaction *a)
     {
         if(!a) return;
@@ -260,9 +260,9 @@
             os.currentquest = a->q;
             a->exec(this, os.playerobj, os.playerobj, os);
             os.currentquest = NULL;
-        } 
+        }
     }
-    
+
     void gui(g3d_gui &g, bool firstpass)
     {
         g.start(menutime, 0.015f, &menutab);
@@ -282,7 +282,7 @@
                     if(trader)
                     {
                         if(g.button("buy",  0xFFFFFF, "coins")&G3D_UP) menuwhich = MENU_BUY;
-                        if(g.button("sell", 0xFFFFFF, "coins")&G3D_UP) menuwhich = MENU_SELL;                    
+                        if(g.button("sell", 0xFFFFFF, "coins")&G3D_UP) menuwhich = MENU_SELL;
                     }
                 }
                 else
@@ -301,7 +301,7 @@
                 }
                 break;
             }
-               
+
             case MENU_BUY:
             {
                 s_sprintfd(info)("buying from: %s", name);
@@ -328,11 +328,11 @@
                     }
                 }
                 s_sprintf(info)("you have %d gold", os.playerobj->s_gold);
-                g.text(info, 0xAAAAAA, "info");   
+                g.text(info, 0xAAAAAA, "info");
                 if(g.button("done buying", 0xFFFFFF, "coins")&G3D_UP) menuwhich = MENU_DEFAULT;
                 break;
             }
-               
+
             case MENU_SELL:
             {
                 s_sprintfd(info)("selling to: %s", name);
@@ -344,7 +344,7 @@
         }
         g.end();
     }
-    
+
     void invgui(g3d_gui &g, rpgobj *buyer = NULL)
     {
         loopinventory()
@@ -358,7 +358,7 @@
                 {
                     if(price>buyer->s_gold)
                     {
-                        conoutf("\f2%s cannot afford to buy %s from you!", buyer->name, o->name);                    
+                        conoutf("\f2%s cannot afford to buy %s from you!", buyer->name, o->name);
                     }
                     else
                     {
@@ -368,7 +368,7 @@
                             s_gold += price;
                             buyer->s_gold -= price;
                             o->decontain();
-                            buyer->add(o, IF_TRADE);                                            
+                            buyer->add(o, IF_TRADE);
                         }
                         else
                         {
@@ -383,7 +383,7 @@
             }
         }
         s_sprintfd(info)("you have %d gold", os.playerobj->s_gold);
-        g.text(info, 0xAAAAAA, "info");   
+        g.text(info, 0xAAAAAA, "info");
     }
 
     void g3d_menu()
--- orig/rpggame/rpgobjset.h
+++ mod/rpggame/rpgobjset.h
@@ -4,48 +4,48 @@
 
     vector<rpgobj *> set, stack;
     hashtable<char *, char *> names;
-    
+
     rpgobj *pointingat;
     rpgobj *playerobj;
     rpgobj *selected;
-    
+
     rpgquest *quests;
     rpgquest *currentquest;
-    
+
     rpgobjset(rpgclient &_cl) : cl(_cl), pointingat(NULL), playerobj(NULL), selected(NULL), quests(NULL), currentquest(NULL)
     {
         #define N(n) CCOMMAND(r_##n,     "i", (rpgobjset *self, int *val), { self->stack[0]->s_##n = *val; }); \
-                     CCOMMAND(r_get_##n, "",  (rpgobjset *self), { intret(self->stack[0]->s_##n); }); 
-                     
-        RPGNAMES 
+                     CCOMMAND(r_get_##n, "",  (rpgobjset *self), { intret(self->stack[0]->s_##n); });
+
+        RPGNAMES
         #undef N
         #define N(n) CCOMMAND(r_def_##n, "ii", (rpgobjset *self, int *i1, int *i2), { stats::def_##n(*i1, *i2); }); \
-                     CCOMMAND(r_eff_##n, "",   (rpgobjset *self), { intret(self->stack[0]->eff_##n()); }); 
-        RPGSTATNAMES 
+                     CCOMMAND(r_eff_##n, "",   (rpgobjset *self), { intret(self->stack[0]->eff_##n()); });
+        RPGSTATNAMES
         #undef N
-        
-        CCOMMAND(r_model,       "s",   (rpgobjset *self, char *s), { self->stack[0]->model = self->stringpool(s); });    
-        CCOMMAND(r_spawn,       "s",   (rpgobjset *self, char *s), { self->spawn(self->stringpool(s)); });    
-        CCOMMAND(r_contain,     "s",   (rpgobjset *self, char *s), { self->stack[0]->decontain(); self->stack[1]->add(self->stack[0], atoi(s)); });    
-        CCOMMAND(r_pop,         "",    (rpgobjset *self), { self->popobj(); });    
-        CCOMMAND(r_swap,        "",    (rpgobjset *self), { swap(self->stack[0], self->stack[1]); });    
-        CCOMMAND(r_say,         "s",   (rpgobjset *self, char *s), { self->stack[0]->abovetext = self->stringpool(s); });    
-        CCOMMAND(r_quest,       "ss",  (rpgobjset *self, char *s, char *a), { self->stack[0]->addaction(self->stringpool(s), self->stringpool(a), true); });    
-        CCOMMAND(r_action,      "ss",  (rpgobjset *self, char *s, char *a), { self->stack[0]->addaction(self->stringpool(s), self->stringpool(a), false); });    
-        CCOMMAND(r_action_use,  "s",   (rpgobjset *self, char *s), { self->stack[0]->action_use.script = self->stringpool(s); });    
-        CCOMMAND(r_take,        "sss", (rpgobjset *self, char *name, char *ok, char *notok), { self->takefromplayer(name, ok, notok); });    
-        CCOMMAND(r_give,        "s",   (rpgobjset *self, char *s), { self->givetoplayer(s); });    
-        CCOMMAND(r_use,         "",    (rpgobjset *self), { self->stack[0]->selectuse(); });    
-        CCOMMAND(r_applydamage, "i",   (rpgobjset *self, int *d), { self->stack[0]->takedamage(*d, *self->stack[1]); });    
+
+        CCOMMAND(r_model,       "s",   (rpgobjset *self, char *s), { self->stack[0]->model = self->stringpool(s); });
+        CCOMMAND(r_spawn,       "s",   (rpgobjset *self, char *s), { self->spawn(self->stringpool(s)); });
+        CCOMMAND(r_contain,     "s",   (rpgobjset *self, char *s), { self->stack[0]->decontain(); self->stack[1]->add(self->stack[0], atoi(s)); });
+        CCOMMAND(r_pop,         "",    (rpgobjset *self), { self->popobj(); });
+        CCOMMAND(r_swap,        "",    (rpgobjset *self), { swap(self->stack[0], self->stack[1]); });
+        CCOMMAND(r_say,         "s",   (rpgobjset *self, char *s), { self->stack[0]->abovetext = self->stringpool(s); });
+        CCOMMAND(r_quest,       "ss",  (rpgobjset *self, char *s, char *a), { self->stack[0]->addaction(self->stringpool(s), self->stringpool(a), true); });
+        CCOMMAND(r_action,      "ss",  (rpgobjset *self, char *s, char *a), { self->stack[0]->addaction(self->stringpool(s), self->stringpool(a), false); });
+        CCOMMAND(r_action_use,  "s",   (rpgobjset *self, char *s), { self->stack[0]->action_use.script = self->stringpool(s); });
+        CCOMMAND(r_take,        "sss", (rpgobjset *self, char *name, char *ok, char *notok), { self->takefromplayer(name, ok, notok); });
+        CCOMMAND(r_give,        "s",   (rpgobjset *self, char *s), { self->givetoplayer(s); });
+        CCOMMAND(r_use,         "",    (rpgobjset *self), { self->stack[0]->selectuse(); });
+        CCOMMAND(r_applydamage, "i",   (rpgobjset *self, int *d), { self->stack[0]->takedamage(*d, *self->stack[1]); });
         clearworld();
     }
-    
+
     void resetstack()
     {
         stack.setsize(0);
-        loopi(10) stack.add(playerobj);     // determines the stack depth    
+        loopi(10) stack.add(playerobj);     // determines the stack depth
     }
-    
+
     void clearworld()
     {
         if(playerobj) { playerobj->ent = NULL; delete playerobj; }
@@ -56,10 +56,10 @@
         pointingat = NULL;
         set.deletecontentsp();
         resetstack();
-        
+
         playerobj->scriptinit();            // will fail when this is called from emptymap(), which is ok
     }
-    
+
     void removefromsystem(rpgobj *o)
     {
         removefromworld(o);
@@ -69,7 +69,7 @@
         resetstack();
         DELETEP(o);
     }
-    
+
     void update(int curtime)
     {
         extern vec worldpos;
@@ -79,41 +79,41 @@
             set[i]->update(curtime);
 
             float dist = cl.player1.o.dist(set[i]->ent->o);
-            if(dist<50 && intersect(set[i]->ent, cl.player1.o, worldpos) && (!pointingat || cl.player1.o.dist(pointingat->ent->o)>dist))    
-            {    
-                pointingat = set[i]; 
+            if(dist<50 && intersect(set[i]->ent, cl.player1.o, worldpos) && (!pointingat || cl.player1.o.dist(pointingat->ent->o)>dist))
+            {
+                pointingat = set[i];
             }
         }
     }
-    
+
     void spawn(char *name)
     {
         rpgobj *o = new rpgobj(name, *this);
         pushobj(o);
         o->scriptinit();
     }
-    
+
     void placeinworld(vec &pos, float yaw)
     {
         stack[0]->placeinworld(new rpgent(stack[0], cl, pos, yaw));
         set.add(stack[0]);
     }
-    
+
     void pushobj(rpgobj *o) { stack.pop(); stack.insert(0, o); }       // never overflows, just removes bottom
     void popobj()           { stack.add(stack.remove(0)); }            // never underflows, just puts it at the bottom
-    
+
     void removefromworld(rpgobj *worldobj)
     {
         set.removeobj(worldobj);
-        DELETEP(worldobj->ent);    
+        DELETEP(worldobj->ent);
     }
-    
+
     void take(rpgobj *worldobj, rpgobj *newowner)
     {
         removefromworld(worldobj);
         newowner->add(worldobj, false);
     }
-    
+
     void takefromplayer(char *name, char *ok, char *notok)
     {
         rpgobj *o = playerobj->take(name);
@@ -123,13 +123,13 @@
             conoutf("\f2you hand over a %s", o->name);
             if(currentquest)
             {
-                conoutf("\f2you finish a quest for %s", currentquest->npc); 
-                currentquest->completed = true;           
+                conoutf("\f2you finish a quest for %s", currentquest->npc);
+                currentquest->completed = true;
             }
         }
         execute(o ? ok : notok);
     }
-    
+
     void givetoplayer(char *name)
     {
         rpgobj *o = stack[0]->take(name);
@@ -139,13 +139,13 @@
             playerobj->add(o, false);
         }
     }
-    
+
     void addquest(rpgaction *a, const char *questline, const char *npc)
     {
         a->q = quests = new rpgquest(quests, npc, questline);
         conoutf("\f2you have accepted a quest for %s", npc);
     }
-    
+
     void listquests(bool completed, g3d_gui &g)
     {
         for(rpgquest *q = quests; q; q = q->next) if(q->completed==completed)
@@ -154,7 +154,7 @@
             g.text(info, 0xAAAAAA, "info");
         }
     }
-    
+
     char *stringpool(char *name)
     {
         char **n = names.access(name);
@@ -163,7 +163,7 @@
         names[name] = name;
         return name;
     }
-    
+
     void render()       { loopv(set) set[i]->render();   }
-    void g3d_npcmenus() { loopv(set) set[i]->g3d_menu(); } 
+    void g3d_npcmenus() { loopv(set) set[i]->g3d_menu(); }
 };
--- orig/rpggame/stats.h
+++ mod/rpggame/stats.h
@@ -52,8 +52,8 @@
     N(attrc) \
     \
     N(usesound)
-   
-   
+
+
 #define RPGNAMES RPGSTATNAMES RPGATTRNAMES
 
 struct rpgobj;
@@ -63,57 +63,57 @@
     #define N(n) static int pointscale_##n, percentscale_##n; \
                  static void def_##n(int a, int b) { pointscale_##n = a; percentscale_##n = b; } \
                  int eff_##n() { return int(logf(s_##n/pointscale_##n+1)*percentscale_##n)+100; }
-    RPGSTATNAMES 
+    RPGSTATNAMES
     #undef N
     #define N(n) int s_##n;
     RPGNAMES
     #undef N
-    
+
     int statupdatetime;
-        
+
     stats() : statupdatetime(0)
     {
         st_reset();
         #define N(n) s_##n = 0;
-        RPGATTRNAMES 
+        RPGATTRNAMES
         #undef N
     }
-    
+
     void st_reset()
     {
         #define N(n) s_##n = 0;
-        RPGSTATNAMES 
+        RPGSTATNAMES
         #undef N
     }
-    
+
     void st_accumulate(rpgobj &o)
     {
         #define N(n) s_##n += o.s_##n;
-        RPGSTATNAMES 
+        RPGSTATNAMES
         #undef N
     }
-    
+
     void st_show(g3d_gui &g)
     {
         #define N(n) if(s_##n) { s_sprintfd(s)(#n ": %d => %d%%", s_##n, eff_##n()); g.text(s, 0xFFFFFF, "info"); }
-        RPGSTATNAMES 
+        RPGSTATNAMES
         #undef N
         #define N(n) if(s_##n) { s_sprintfd(s)(#n ": %d", s_##n); g.text(s, 0xFFAAAA, "info"); }
-        RPGATTRNAMES 
+        RPGATTRNAMES
         #undef N
     }
-    
+
     void st_init()
     {
         s_hp   = eff_maxhp();
         s_mana = eff_maxmana();
     }
-    
+
     void st_respawn()   // player only
     {
         s_hp = 10;
     }
-    
+
     void st_update(int lastmillis)
     {
         if(lastmillis-statupdatetime>1000)
