shithub: rott

Download patch

ref: ed4eeab77001fee4b5c7c2f95211aa671f85a653
parent: 78c28930f3c185f25d51d74560c1d367faadf52f
author: levesqu8 <levesqu8@msu.edu>
date: Fri Sep 22 06:58:41 EDT 2017

wrote versions of bat attack functions that work with obtypes instead of playerobjs

--- a/rott/rt_actor.c
+++ b/rott/rt_actor.c
@@ -1609,24 +1609,32 @@
         ob->temp3 = stat_drunkmissile;
         ob->temp2 = 3;
     }
-    else if (number > 200 && number <= 225)
+    else if (number > 200 && number <= 250)
     {
         ob->temp3 = stat_firewall;
         ob->temp2 = 3;
     }
-    else if (number > 225 && number <= 250)
+    else if (number > 250 && number <= 300)
     {
         ob->temp3 = stat_firebomb;
         ob->temp2 = 3;
     }
 #if (SHAREWARE == 0)
-    else if (number > 250)
+    else if (number > 300 && number <= 350)
     {
+        //excalibat
+        ob->temp3 = stat_bat;
+        ob->temp2 = 3;
+    }
+    else if (number > 350)
+    {
         //dark staff
         ob->temp3 = stat_kes;
         ob->temp2 = 3;
     }
     //TODO: Figure out a way to allow biltzguards to attack with excalibat w/o crashing the game
+    
+   //TODO: Figure out a way to allow blitzguards to attack effectively with split missiles (like actually split them)
 
 #endif
     else
@@ -1650,7 +1658,8 @@
         {
             OutfitBlitzguardWith(ob);
         }
-        else {
+        else 
+        {
             ob->temp3 = stat_bazooka;
             ob->temp2 = 3;
         }
@@ -1657,8 +1666,173 @@
     }
 }
 
+void EnemyBatAttack(objtype*ob)
+{   
+    objtype *temp,*temp2;
+    //objtype *grenadetarget;
+    statobj_t*tstat;
+    int dx,dy,dz,angle,momx,momy,op,magangle;
+    int tilexlow,tilexhigh;
+    int tileylow,tileyhigh;
+    int radius =0x10000;
+    int x,y;
 
+    SD_PlaySoundRTP(SD_EXCALISWINGSND,ob->x,ob->y);
+    for(temp=firstareaactor[ob->areanumber]; temp; temp=temp->nextinarea)
+    {   if (temp == ob)
+            continue;
+
+        if (temp->flags & FL_DYING)
+            continue;
+
+        if ((temp->obclass != grenadeobj) &&
+                (!((temp->obclass >= grenadeobj) && (temp->obclass <= p_godballobj))) &&
+                (!(temp->flags & FL_SHOOTABLE) ||
+                 (temp->obclass >= roboguardobj))
+           )
+            continue;
+
+        dx = abs(temp->x - ob->x);
+        dy = abs(temp->y - ob->y);
+        dz = abs(temp->z - ob->z);
+        if ((dx > 0x10000) || (dy > 0x10000) || (dz > 20))
+            continue;
+
+        magangle = abs(ob->angle - AngleBetween(ob,temp));
+        if (magangle > VANG180)
+            magangle = ANGLES - magangle;
+
+        if (magangle > ANGLES/8)
+            continue;
+
+
+        angle= ob->angle+ANGLES/16;
+        Fix(angle);
+
+        if ((temp->obclass >= grenadeobj) && (temp->obclass <= p_godballobj))
+        {
+            temp->angle += ANGLES/2;
+            Fix(temp->angle);
+            temp->momentumx = temp->momentumy = temp->momentumz = 0;
+            ParseMomentum(temp,temp->angle);
+            temp->whatever = ob;
+            temp->target = NULL;
+            continue;
+        }
+
+
+        else if (temp->obclass != grenadeobj)
+        {   momx = FixedMul(0x3000l,costable[angle]);
+            momy = -FixedMul(0x3000l,sintable[angle]);
+            if (levelheight > 2)
+            {   op = FixedMul(GRAVITY,(maxheight-100)<<16) << 1;
+                temp->momentumz = -FixedSqrtHP(op);
+            }
+            temp->flags |= FL_NOFRICTION;
+            SD_PlaySoundRTP(SD_EXCALIHITSND,ob->x,ob->y);
+            if ((gamestate.violence == vl_excessive) && (GameRandomNumber("Bat Gibs",0) < 150))
+            {   temp->flags |= FL_HBM;
+                DamageThing(temp,50);
+            }
+            else
+                DamageThing(temp,10);
+            if ((temp->flags & FL_HBM) && (temp->hitpoints > 0))
+                temp->flags &= ~FL_HBM;
+            Collision(temp,ob,momx,momy);
 /*
+            if ((temp->obclass == blitzguardobj) && (temp->state == &s_blitzplead7))
+            {   temp->shapeoffset += deathshapeoffset[temp->obclass];
+                temp->flags |= FL_ALTERNATE;
+                NewState(temp,&s_blitzdie3);
+                temp->momentumx = temp->momentumy = 0;
+            }
+*/
+        }
+        
+        //an enemy probably doesn't want to play baseball with a friend's grenade...
+/*
+        else // find target to hit grenade back at
+        {   int rand;
+
+            rand = GameRandomNumber("bat/grenade target",0);
+            if (rand < 80)
+            {   grenadetarget = (objtype*)(temp->whatever); // hit back at george
+                GetMomenta(grenadetarget,ob,&(temp->momentumx),&(temp->momentumy),&(temp->momentumz),0x3000);
+            }
+            else if (rand < 160) // hit back at first eligible
+            {
+
+                for(temp2 = firstareaactor[ob->areanumber]; temp2; temp2 = temp2->nextinarea)
+                {   magangle = abs(ob->angle-AngleBetween(ob,temp2));
+                    if (magangle > VANG180)
+                        magangle = ANGLES - magangle;
+
+                    if (magangle > ANGLES/8)
+                        continue;
+                    GetMomenta(temp2,ob,&(temp->momentumx),&(temp->momentumy),&(temp->momentumz),0x3000);
+                    break;
+                }
+            }
+            else // hit wherever
+            {   ob->angle += (rand >> 1);
+                Fix(ob->angle);
+                ob->momentumx = ob->momentumy = 0;
+                ParseMomentum(ob,ob->angle);
+            }
+
+
+            temp->temp1 = 0x70000;
+            NewState(temp,&s_grenade1);
+        }
+        break;
+*/
+    }
+
+    for(tstat=firstactivestat; tstat; tstat=tstat->statnext)
+    {
+        if (!(tstat->flags & FL_SHOOTABLE))
+            continue;
+
+        dx = abs(tstat->x - ob->x);
+        dy = abs(tstat->y - ob->y);
+        dz = abs(tstat->z - ob->z);
+
+        if ((dx > 0xc000) || (dy > 0xc000) || (dz > 20))
+            continue;
+
+        magangle = abs(ob->angle - AngleBetween(ob,(objtype*)tstat));
+        if (magangle > VANG180)
+            magangle = ANGLES - magangle;
+
+        if (magangle > ANGLES/8)
+            continue;
+
+        DamageThing(tstat,50);
+        
+        
+    }
+
+    tilexlow = (int)((ob->x-radius) >>TILESHIFT);
+    tileylow = (int)((ob->y-radius) >>TILESHIFT);
+
+    tilexhigh = (int)((ob->x+radius) >>TILESHIFT);
+    tileyhigh = (int)((ob->y+radius) >>TILESHIFT);
+
+    for (y=tileylow; y<=tileyhigh; y++)
+        for (x=tilexlow; x<=tilexhigh; x++)
+        {   if ((tilemap[x][y]&0x8000) && (tilemap[x][y]&0x4000))
+            {   maskedwallobj_t * mw;
+
+                mw=maskobjlist[tilemap[x][y]&0x3ff];
+                if (mw->flags&MW_SHOOTABLE)
+                    UpdateMaskedWall(tilemap[x][y]&0x3ff);
+            }
+        }
+
+}
+
+
+/*
 ===============
 =
 = SpawnStand
@@ -5607,7 +5781,7 @@
                         ob->momentumx = -ob->momentumx;
                         int rand;
 
-                        rand = RandomNumber("Spawn Ricochet Sound in SpawnGunSmoke",0);
+                        rand = RandomNumber("Spawn Ricochet Sound",0);
                         if (rand < 80)
                             SD_PlaySoundRTP(SD_RICOCHET1SND,ob->x,ob->y);
                         else if (rand < 160)
@@ -5621,7 +5795,7 @@
                         ob->momentumy = -ob->momentumy;
                         int rand;
 
-                        rand = RandomNumber("Spawn Ricochet Sound in SpawnGunSmoke",0);
+                        rand = RandomNumber("Spawn Ricochet Sound",0);
                         if (rand < 80)
                             SD_PlaySoundRTP(SD_RICOCHET1SND,ob->x,ob->y);
                         else if (rand < 160)
@@ -7729,7 +7903,8 @@
 }
 
 void ActorMovement (objtype *ob)
-{   int tryx,tryy,tryz,limitok,max,friction,ocl;
+{   
+    int tryx,tryy,tryz,limitok,max,friction,ocl;
 
 
 
@@ -11635,6 +11810,7 @@
                 chance = 400/dist;
             else
                 chance = 300/dist;
+            
 
             if (GameRandomNumber("T_Chase",ocl) <chance)
             {   if ((ocl == b_heinrichobj) && (Near(ob,PLAYER[0],4)))
@@ -12061,8 +12237,130 @@
 }
 
 
+void A_Shoot (objtype *ob)
+{
+    int   dx,dy,dz,dist;
+    int   accuracy,damage,sound;
+    objtype * target;
+    int   num;
+    int   savedangle;
 
+    ActorMovement(ob);
 
+    //ob->flags |= FL_FULLLIGHT; bats don't emit light
+//if (!(ob->flags & FL_SHOOTABLE))
+    //Error("\na dead instance of %s is shooting at you",debugstr[ob->obclass]);
+
+    if (!ob->ticcount)
+    {   if (ob->obclass == strikeguardobj)
+            ob->flags &= ~FL_NOFRICTION;
+
+        target = (objtype*)(ob->target);
+        if (!target)
+            Error("an instance of %s called shoot without a target\n",debugstr[ob->obclass]);
+
+        if(!(ob->obclass == blitzguardobj && ob->temp3 == stat_bat))
+        {
+            ob->flags &= ~FL_FULLLIGHT;
+        }
+        
+
+
+        dx = (target->x - ob->x);
+        dy = (ob->y - target->y);
+        dz = target->z-ob->z;
+
+
+        if((ob->obclass == blitzguardobj && ob->temp3 == stat_bat && abs(dx)< 0x10000 && abs(dy) < 0x10000 && ob->z < 20))
+        {
+            EnemyBatAttack(ob);
+        }
+        
+        else if ((ob->obclass == blitzguardobj) && (ob->temp3) &&
+                (ob->temp3 != stat_gasmask) && (ob->temp3 != stat_asbesto) &&
+                (ob->temp3 != stat_bulletproof) &&
+                (gamestate.difficulty >= gd_medium) &&
+                ((abs(dx) > 0xc000) || (abs(dy) > 0xc000))
+           )
+        {
+            int i;
+            missile_stats* newmissiledata;
+
+            newmissiledata = &PlayerMissileData[GetWeaponForItem(ob->temp3)];
+
+            // ready to annihilate this poor bastard
+
+            SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,
+                         AngleBetween(ob,player), newmissiledata->state,
+                         newmissiledata->offset);
+
+            if (newmissiledata->obclass == p_drunkmissileobj)
+            {
+                for(i=0; i<4; i++)
+                {
+                    SpawnMissile(ob,newmissiledata->obclass,newmissiledata->speed,
+                                 AngleBetween(ob,player), newmissiledata->state,
+                                 newmissiledata->offset);
+                }
+            }
+            ob->target = NULL;
+            ob->temp2 --;
+            if (ob->temp2 == 0)
+                ob->temp3 = 0;
+            return;
+        }
+
+
+        if ((!areabyplayer[ob->areanumber]) && (target->obclass ==  playerobj))
+            return;
+
+        //if (!CheckLine(ob,target,SHOOT))       // player is behind a wall
+        //return;
+
+
+        savedangle=ob->angle;
+        ob->angle = atan2_appx (dx,dy);
+        dist = FindDistance(dx,dy);
+        ob->yzangle = FINEANGLES-atan2_appx(dist, dz<<10);
+
+        if ((ob->yzangle>MAXYZANGLE) && (ob->yzangle<FINEANGLES-MAXYZANGLE))
+            ob->yzangle=MAXYZANGLE;
+
+        dist>>=16;
+
+        accuracy=(WHICHACTOR<<4)+((gamestate.difficulty) << 6);
+
+        num = GameRandomNumber("A_Shoot3",ob->obclass);
+
+        if (num<128) num=128; // Don't let accuracy fall below 50% original
+
+        accuracy=FixedMulShift(num,accuracy,8); // scale accuracy based off randomness
+
+        // check for maximum accuracy;
+
+        if (accuracy>255) accuracy=255;
+
+        if (ob->obclass==highguardobj)
+            damage=DMG_MP40;
+        else if (ob->obclass == triadenforcerobj)
+            damage=DMG_MP40;
+        else
+            damage=DMG_ENEMYBULLETWEAPON;
+
+
+        RayShoot (ob, damage, 255-accuracy);
+
+        ob->angle=savedangle;
+        sound = BAS[ob->obclass].fire;
+        SD_PlaySoundRTP(sound,ob->x,ob->y);
+        MISCVARS->madenoise = true;
+        if ((!(ob->flags& FL_HASAUTO)) || (!ob->temp3))
+            ob->target = NULL;
+    }
+}
+
+
+
 /*
 ===============
 =
@@ -12073,6 +12371,7 @@
 ===============
 */
 
+/*
 void A_Shoot (objtype *ob)
 {
     int   dx,dy,dz,dist;
@@ -12186,6 +12485,7 @@
             ob->target = NULL;
     }
 }
+*/
 
 
 
--