/*
        ===================
        =
        = KillRefugee
        =
        ===================
        */
        private void KillRefugee(objtype hit, bool player)
        {
            // as: Support for extra sound effects
            ushort sound = HOSTAGEDEADSND;
            if(player)
            {
                if(hit.temp1 == MAN1PIC)
                    sound = SNDEX_HSTAGEDEAD3;
                else
                    sound = SNDEX_HSTAGEDEAD4;
            }
            else
            {
                if(hit.temp1 != MAN1PIC)
                    sound = SNDEX_HSTAGEDEAD2;
            }
            PlaySound(sound); // HOSTAGEDEADSND

            if(hit.radarx != 0)
                XPlot(hit.radarx, hit.radary, hit.radarcolor);

            killedcount++;

            DrawPic((ushort) (2 * (totalrefugees - killedcount) + 1), 6, DEADGUYPIC);
            if(--numrefugees == 0)
            {
                // as: Support for extra sound effects
                if(player)
                {
                    if(hit.temp1 == MAN1PIC)
                        sound = SNDEX_LASTDEAD3;
                    else
                        sound = SNDEX_LASTDEAD4;
                }
                else
                {
                    if(hit.temp1 == MAN1PIC)
                        sound = SNDEX_LASTDEAD1;
                    else
                        sound = SNDEX_LASTDEAD2;
                }
                PlaySound(sound); // WARPGATESND

                SpawnWarp(warpx, warpy);
            }

            hit.radarcolor = 0;
            hit._class = classtype.inertobj;

            if(hit.temp1 == MAN1PIC)
            {
                hit.shapenum = hit.temp1 = MANDIE1PIC;
            }
            else
            {
                hit.shapenum = hit.temp1 = WOMANDIE1PIC;
            }

            hit.think = ExplodeThink;
            hit.stage = hit.ticcount = 0;
        }
        /*
        ===================
        =
        = KillTank
        =
        ===================
        */
        private void KillTank(objtype hit)
        {
            // as: Enemy stats
            enemiesKilled++;

            // as: Support for extra sound effects
            PlaySound(SNDEX_TANKDIE); // SHOOTTHINGSND

            if(hit.radarx != 0)
                XPlot(hit.radarx, hit.radary, hit.radarcolor);

            hit.radarcolor = 0;
            hit._class = classtype.inertobj;
            hit.shapenum = hit.temp1 = TANKDIE1PIC;
            hit.think = ExplodeThink;
            hit.stage = hit.ticcount = 0;
        }
        /*
        ======================
        =
        = ChaseThing
        =
        = Hunt for player
        =
        ======================
        */
        private void ChaseThing(objtype chase)
        {
            dirtype olddir = obon.dir;
            dirtype turnaround = opposite[(short) olddir];

            int deltax = chase.x - obon.x;
            int deltay = chase.y - obon.y;

            // as: d[3] changed to d1, d2
            dirtype d1 = dirtype.nodir;
            dirtype d2 = dirtype.nodir;

            if(deltax > MINCHASE)
                d1 = dirtype.east;
            else if(deltax < -MINCHASE)
                d1 = dirtype.west;

            if(deltay > MINCHASE)
                d2 = dirtype.south;
            else if(deltay < -MINCHASE)
                d2 = dirtype.north;

            dirtype tdir;
            if(LABS(deltay) > LABS(deltax))
            {
                tdir = d1;
                d1 = d2;
                d2 = tdir;
            }

            if(d1 == turnaround)
                d1 = dirtype.nodir;

            if(d2 == turnaround)
                d2 = dirtype.nodir;

            if(d1 != dirtype.nodir)
            {
                obon.dir = d1;
                if(Walk())
                {
                    if(d2 != dirtype.nodir)
                    {
                        obon.dir = d2;
                        Walk(); // try to go diagonal if possible
                    }
                    return;
                }
            }

            if(d2 != dirtype.nodir)
            {
                obon.dir = d2;

                if(Walk())
                    return;
            }

            // there is no direct path to the player, so pick another direction

            obon.dir = olddir;

            if(Walk())
                return;

            if(RndT() > 128) // randomly determine direction of search
            {
                for(tdir = dirtype.north; tdir <= dirtype.west; tdir += 2)
                {
                    if(tdir != turnaround)
                    {
                        obon.dir = tdir;

                        if(Walk())
                            return;
                    }
                }
            }
            else
            {
                for(tdir = dirtype.west; tdir >= dirtype.north; tdir -= 2)
                {
                    if(tdir != turnaround)
                    {
                        obon.dir = tdir;

                        if(Walk())
                            return;
                    }
                }
            }

            obon.dir = turnaround;

            Walk(); // last chance, don't worry about returned value
        }
        /*
        ===================
        =
        = GetRefugee
        =
        ===================
        */
        private void GetRefugee(objtype hit)
        {
            // as: Support for extra sound effects
            if(hit.temp1 == MAN1PIC)
                PlaySound(SAVEHOSTAGESND);
            else
                PlaySound(SNDEX_SAVHOSTAGE2); // SAVEHOSTAGESND

            hit._class = classtype.nothing;

            if(hit.radarx != 0)
                XPlot(hit.radarx, hit.radary, hit.radarcolor);

            DrawPic((ushort) (2 * savedcount + 1), 6, SAVEDGUYPIC);

            savedcount++;
            if(--numrefugees == 0)
            {
                // as: Support for extra sound effects
                if(hit.temp1 == MAN1PIC)
                    PlaySound(LASTHOSTAGESND);
                else
                    PlaySound(SNDEX_LSTHOSTAGE2); // LASTHOSTAGESND

                SpawnWarp(warpx, warpy);
            }
        }
 /// <summary>Copies the objtype to another.</summary>
 /// <remarks>For struct assignment.</remarks>
 /// <param name="destination">The destination objtype.</param>
 public void CopyTo(objtype destination)
 {
     destination.active = active;
     destination._class = _class;
     destination.x = x;
     destination.y = y;
     destination.viewx = viewx; // x,y in view coordinate space (NOT pixels!)
     destination.viewy = viewy;
     destination.angle = angle;
     destination.hitpoints = hitpoints;
     destination.radarx = radarx;
     destination.radary = radary;
     destination.radarcolor = radarcolor;
     destination.speed = speed;
     destination.size = size; // global radius for hit rect calculation
     destination.xl = xl; // hit rectangle
     destination.xh = xh;
     destination.yl = yl;
     destination.yh = yh;
     destination.ticcount = ticcount;
     destination.shapenum = shapenum;
     destination.stage = stage;
     destination.temp1 = temp1;
     destination.temp2 = temp2;
     destination.dir = dir;
     destination.think = think;
 }
        //==========================================================================
        /*
        ===================
        =
        = PlayLoop
        =
        ===================
        */
        private void PlayLoop()
        {
            do
            {
                c = ControlPlayer(1);

                screenofs = 0; // draw in split screen (radar, time, etc)

                for(short objIndex = 0; objIndex <= lastobjIndex; objIndex++)
                {
                    obj = objlist[objIndex];

                    if(obj._class != 0)
                    {
                        obj.CopyTo(obon);
                        obon.think();
                        obon.CopyTo(obj);
                    }
                }

                DropTime();

                if(keydown[0x57]) // DEBUG!
                {
                    // as: Support for extra sound effects
                    DamagePlayer(TAKEDAMAGESND);
                    ClearKeys();
                }

                if(bordertime != 0 && (bordertime -= tics) <= 0)
                {
                    bordertime = 0;
                    ColorBorder(0);
                }

                FinishView(); // base drawn by player think

                CheckKeys();

            } while(leveldone == 0);
        }
        private void PlayGame()
        {
            level = startlevel = 0;

            if(bestlevel > 1)
            {
                ExpWin(28, 3);
                py += 6;
                PPrint(_strings[Strings.PlayGame1]); // as: string replacements
                PPrint(bestlevel.ToString());
                PPrint(_strings[Strings.PlayGame2]); // as: string replacements

                short i = (short) InputInt();
                if(i >= 1 && i <= bestlevel)
                {
                    startlevel = (short) (i - 1);
                    level = startlevel;
                }
            }

            restart:
            score = 0;
            resetgame = false;

            do
            {
                lastobjIndex = 0;

            #if TESTCASE
                level = 12;
            #endif
                BaseScreen();

                if(level == 21)
                    break;

            #if TESTCASE
                objlist[0].x = 3126021;
                objlist[0].y = 522173;
                objlist[0].angle = 170;
            #endif

                savedcount = killedcount = 0;

                timestruct.min = levmin[level - 1];
                timestruct.sec = levsec[level - 1]; // as: modified games

                screenofs = 0;
                DrawPic(6, 48, (short) (DIGIT0PIC + timestruct.min));
                DrawPic(9, 48, (short) (DIGIT0PIC + timestruct.sec / 10));
                DrawPic(11, 48, (short) (DIGIT0PIC + timestruct.sec % 10));

                lasttimecount = (int) timecount;
                tics = 1;
                leveldone = 0;

                if(level > bestlevel)
                    bestlevel = level;

                PlayLoop();

                screenofs = 0;
                for(short objIndex = 1; objIndex < lastobjIndex; objIndex++)
                {
                    obj = objlist[objIndex];
                    if(obj._class != 0 && obj.radarx != 0)
                        XPlot(obj.radarx, obj.radary, obj.radarcolor);
                }

                if(bordertime != 0)
                {
                    bordertime = 0;
                    ColorBorder(0);
                }
            }
            while(leveldone > 0);

            if(resetgame)
                return;

            GameOver();

            //
            // continue
            //
            if(level > 2 && level < 21)
            {
                DrawWindow(10, 20, 30, 23);
                py += 3;
                CPPrint(_strings[Strings.PlayGame3]); // as: string replacements
                ClearKeys();

                ch = (sbyte) PGet();
                if(_sys.toupper(ch) == 'Y')
                {
                    level--;
                    startlevel = level; // don't show base screen
                    goto restart;
                }
            }
        }
 private void HovLoopInitialise()
 {
     for(short i = 0; i < MAXOBJECTS; i++)
         objlist[i] = new objtype();
 }
        /*
        ===============
        =
        = FindFreeobj
        =
        = Assigned global variable *new to a free spot in the object list
        =
        ===============
        */
        private short FindFreeObj()
        {
            short newIndex = 1;
            while(objlist[newIndex]._class != classtype.nothing && newIndex <= lastobjIndex)
                newIndex++;

            if(newIndex > lastobjIndex)
            {
                lastobjIndex++;

                if(lastobjIndex >= MAXOBJECTS)
                    Quit("Object list overflow!");
            }

            _new = objlist[newIndex];

            _new.Clear();

            _new.think = BadThink;

            // as: Return the index of the object that was found
            return newIndex;
        }