mirror of
https://github.com/ZDoom/Raze.git
synced 2025-02-02 05:01:58 +00:00
8f19dc12d8
* a large number of code pointer records were removed because none of these functions ever gets assigned to a pointer * instead of looking up entries by index, do it by name. This is far less fragile and will survive deeper refactoring. The old storage by table index will break as soon as a single entry gets removed. Since the old savegames got broken due to this problem recently it was a good time to change the setup.
649 lines
16 KiB
C++
649 lines
16 KiB
C++
//-------------------------------------------------------------------------
|
|
/*
|
|
Copyright (C) 1997, 2005 - 3D Realms Entertainment
|
|
|
|
This file is part of Shadow Warrior version 1.2
|
|
|
|
Shadow Warrior is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
Original Source: 1997 - Frank Maddin and Jim Norwood
|
|
Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
|
|
*/
|
|
//-------------------------------------------------------------------------
|
|
#include "ns.h"
|
|
|
|
#include "build.h"
|
|
|
|
#include "names2.h"
|
|
#include "game.h"
|
|
#include "tags.h"
|
|
#include "ai.h"
|
|
#include "weapon.h"
|
|
#include "misc.h"
|
|
|
|
BEGIN_SW_NS
|
|
|
|
DECISION EelBattle[] =
|
|
{
|
|
{649, InitActorMoveCloser },
|
|
{650, InitActorAlertNoise },
|
|
{1024, InitActorMoveCloser }
|
|
};
|
|
|
|
DECISION EelOffense[] =
|
|
{
|
|
{649, InitActorMoveCloser },
|
|
{750, InitActorAlertNoise },
|
|
{1024, InitActorMoveCloser }
|
|
};
|
|
|
|
DECISION EelBroadcast[] =
|
|
{
|
|
{3, InitActorAlertNoise },
|
|
{6, InitActorAmbientNoise },
|
|
{1024, InitActorDecide }
|
|
};
|
|
|
|
DECISION EelSurprised[] =
|
|
{
|
|
{701, InitActorMoveCloser },
|
|
{1024, InitActorDecide }
|
|
};
|
|
|
|
DECISION EelEvasive[] =
|
|
{
|
|
{ 790, InitActorRunAway },
|
|
{1024, InitActorMoveCloser },
|
|
};
|
|
|
|
DECISION EelLostTarget[] =
|
|
{
|
|
{900, InitActorFindPlayer },
|
|
{1024, InitActorWanderAround }
|
|
};
|
|
|
|
DECISION EelCloseRange[] =
|
|
{
|
|
{950, InitActorAttack },
|
|
{1024, InitActorReposition }
|
|
};
|
|
|
|
ANIMATOR InitEelFire;
|
|
|
|
DECISION EelTouchTarget[] =
|
|
{
|
|
{1024, InitActorAttack },
|
|
};
|
|
|
|
PERSONALITY EelPersonality =
|
|
{
|
|
EelBattle,
|
|
EelOffense,
|
|
EelBroadcast,
|
|
EelSurprised,
|
|
EelEvasive,
|
|
EelLostTarget,
|
|
EelCloseRange,
|
|
EelTouchTarget
|
|
};
|
|
|
|
ATTRIBUTE EelAttrib =
|
|
{
|
|
{100, 110, 120, 130}, // Speeds
|
|
{3, 0, -2, -3}, // Tic Adjusts
|
|
3, // MaxWeapons;
|
|
{
|
|
0, 0, 0,
|
|
0, 0, 0,
|
|
0,0,0,0
|
|
}
|
|
};
|
|
|
|
//////////////////////
|
|
// EEL RUN
|
|
//////////////////////
|
|
|
|
#define EEL_RUN_RATE 20
|
|
|
|
ANIMATOR DoEelMove,DoStayOnFloor, DoActorDebris, NullEel;
|
|
|
|
STATE s_EelRun[5][4] =
|
|
{
|
|
{
|
|
{EEL_RUN_R0 + 0, EEL_RUN_RATE, DoEelMove, &s_EelRun[0][1]},
|
|
{EEL_RUN_R0 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[0][2]},
|
|
{EEL_RUN_R0 + 2, EEL_RUN_RATE, DoEelMove, &s_EelRun[0][3]},
|
|
{EEL_RUN_R0 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[0][0]},
|
|
},
|
|
{
|
|
{EEL_RUN_R1 + 0, EEL_RUN_RATE, DoEelMove, &s_EelRun[1][1]},
|
|
{EEL_RUN_R1 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[1][2]},
|
|
{EEL_RUN_R1 + 2, EEL_RUN_RATE, DoEelMove, &s_EelRun[1][3]},
|
|
{EEL_RUN_R1 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[1][0]},
|
|
},
|
|
{
|
|
{EEL_RUN_R2 + 0, EEL_RUN_RATE, DoEelMove, &s_EelRun[2][1]},
|
|
{EEL_RUN_R2 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[2][2]},
|
|
{EEL_RUN_R2 + 2, EEL_RUN_RATE, DoEelMove, &s_EelRun[2][3]},
|
|
{EEL_RUN_R2 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[2][0]},
|
|
},
|
|
{
|
|
{EEL_RUN_R3 + 0, EEL_RUN_RATE, DoEelMove, &s_EelRun[3][1]},
|
|
{EEL_RUN_R3 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[3][2]},
|
|
{EEL_RUN_R3 + 2, EEL_RUN_RATE, DoEelMove, &s_EelRun[3][3]},
|
|
{EEL_RUN_R3 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[3][0]},
|
|
},
|
|
{
|
|
{EEL_RUN_R4 + 0, EEL_RUN_RATE, DoEelMove, &s_EelRun[4][1]},
|
|
{EEL_RUN_R4 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[4][2]},
|
|
{EEL_RUN_R4 + 2, EEL_RUN_RATE, DoEelMove, &s_EelRun[4][3]},
|
|
{EEL_RUN_R4 + 1, EEL_RUN_RATE, DoEelMove, &s_EelRun[4][0]},
|
|
}
|
|
};
|
|
|
|
STATEp sg_EelRun[] =
|
|
{
|
|
&s_EelRun[0][0],
|
|
&s_EelRun[1][0],
|
|
&s_EelRun[2][0],
|
|
&s_EelRun[3][0],
|
|
&s_EelRun[4][0]
|
|
};
|
|
|
|
//////////////////////
|
|
//
|
|
// EEL STAND
|
|
//
|
|
//////////////////////
|
|
|
|
|
|
STATE s_EelStand[5][1] =
|
|
{
|
|
{
|
|
{EEL_RUN_R0 + 0, EEL_RUN_RATE, DoEelMove, &s_EelStand[0][0]},
|
|
},
|
|
{
|
|
{EEL_RUN_R1 + 0, EEL_RUN_RATE, DoEelMove, &s_EelStand[1][0]},
|
|
},
|
|
{
|
|
{EEL_RUN_R2 + 0, EEL_RUN_RATE, DoEelMove, &s_EelStand[2][0]},
|
|
},
|
|
{
|
|
{EEL_RUN_R3 + 0, EEL_RUN_RATE, DoEelMove, &s_EelStand[3][0]},
|
|
},
|
|
{
|
|
{EEL_RUN_R4 + 0, EEL_RUN_RATE, DoEelMove, &s_EelStand[4][0]},
|
|
}
|
|
};
|
|
|
|
STATEp sg_EelStand[] =
|
|
{
|
|
&s_EelStand[0][0],
|
|
&s_EelStand[1][0],
|
|
&s_EelStand[2][0],
|
|
&s_EelStand[3][0],
|
|
&s_EelStand[4][0]
|
|
};
|
|
|
|
//////////////////////
|
|
//
|
|
// EEL FIRE
|
|
//
|
|
//////////////////////
|
|
|
|
ANIMATOR InitEelFire, EelShock;
|
|
#define EEL_FIRE_RATE 12
|
|
|
|
STATE s_EelAttack[5][7] =
|
|
{
|
|
{
|
|
{EEL_FIRE_R0 + 0, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[0][1]},
|
|
{EEL_FIRE_R0 + 1, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[0][2]},
|
|
{EEL_FIRE_R0 + 2, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[0][3]},
|
|
{EEL_FIRE_R0 + 2, 0|SF_QUICK_CALL, InitEelFire, &s_EelAttack[0][4]},
|
|
{EEL_FIRE_R0 + 2, EEL_FIRE_RATE, NullEel, &s_EelAttack[0][5]},
|
|
{EEL_FIRE_R0 + 3, 0|SF_QUICK_CALL, InitActorDecide, &s_EelAttack[0][6]},
|
|
{EEL_RUN_R0 + 3, EEL_FIRE_RATE, DoEelMove, &s_EelAttack[0][6]}
|
|
},
|
|
{
|
|
{EEL_FIRE_R1 + 0, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[1][1]},
|
|
{EEL_FIRE_R1 + 1, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[1][2]},
|
|
{EEL_FIRE_R1 + 2, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[1][3]},
|
|
{EEL_FIRE_R1 + 2, 0|SF_QUICK_CALL, InitEelFire, &s_EelAttack[1][5]},
|
|
{EEL_FIRE_R1 + 2, EEL_FIRE_RATE, NullEel, &s_EelAttack[1][6]},
|
|
{EEL_FIRE_R1 + 3, 0|SF_QUICK_CALL, InitActorDecide, &s_EelAttack[1][7]},
|
|
{EEL_RUN_R0 + 3, EEL_FIRE_RATE, DoEelMove, &s_EelAttack[1][7]}
|
|
},
|
|
{
|
|
{EEL_FIRE_R2 + 0, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[2][1]},
|
|
{EEL_FIRE_R2 + 1, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[2][2]},
|
|
{EEL_FIRE_R2 + 2, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[2][3]},
|
|
{EEL_FIRE_R2 + 2, 0|SF_QUICK_CALL, InitEelFire, &s_EelAttack[2][4]},
|
|
{EEL_FIRE_R2 + 2, EEL_FIRE_RATE, NullEel, &s_EelAttack[2][5]},
|
|
{EEL_FIRE_R2 + 3, 0|SF_QUICK_CALL, InitActorDecide, &s_EelAttack[2][6]},
|
|
{EEL_RUN_R0 + 3, EEL_FIRE_RATE, DoEelMove, &s_EelAttack[2][6]}
|
|
},
|
|
{
|
|
{EEL_RUN_R3 + 0, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[3][1]},
|
|
{EEL_RUN_R3 + 1, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[3][2]},
|
|
{EEL_RUN_R3 + 2, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[3][3]},
|
|
{EEL_RUN_R3 + 2, 0|SF_QUICK_CALL, InitEelFire, &s_EelAttack[3][4]},
|
|
{EEL_RUN_R3 + 2, EEL_FIRE_RATE, NullEel, &s_EelAttack[3][5]},
|
|
{EEL_RUN_R3 + 3, 0|SF_QUICK_CALL, InitActorDecide, &s_EelAttack[3][6]},
|
|
{EEL_RUN_R0 + 3, EEL_FIRE_RATE, DoEelMove, &s_EelAttack[3][6]}
|
|
},
|
|
{
|
|
{EEL_RUN_R4 + 0, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[4][1]},
|
|
{EEL_RUN_R4 + 1, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[4][2]},
|
|
{EEL_RUN_R4 + 2, EEL_FIRE_RATE*2, NullEel, &s_EelAttack[4][3]},
|
|
{EEL_RUN_R4 + 2, 0|SF_QUICK_CALL, InitEelFire, &s_EelAttack[4][4]},
|
|
{EEL_RUN_R4 + 2, EEL_FIRE_RATE, NullEel, &s_EelAttack[4][5]},
|
|
{EEL_RUN_R4 + 3, 0|SF_QUICK_CALL, InitActorDecide, &s_EelAttack[4][6]},
|
|
{EEL_RUN_R0 + 3, EEL_FIRE_RATE, DoEelMove, &s_EelAttack[4][6]}
|
|
}
|
|
};
|
|
|
|
STATEp sg_EelAttack[] =
|
|
{
|
|
&s_EelAttack[0][0],
|
|
&s_EelAttack[1][0],
|
|
&s_EelAttack[2][0],
|
|
&s_EelAttack[3][0],
|
|
&s_EelAttack[4][0]
|
|
};
|
|
|
|
|
|
//////////////////////
|
|
//
|
|
// EEL DIE
|
|
//
|
|
//////////////////////
|
|
|
|
#define EEL_DIE_RATE 20
|
|
|
|
ANIMATOR DoEelDeath;
|
|
STATE s_EelDie[] =
|
|
{
|
|
{EEL_DIE + 0, EEL_DIE_RATE, DoEelDeath, &s_EelDie[1]},
|
|
{EEL_DIE + 0, EEL_DIE_RATE, DoEelDeath, &s_EelDie[2]},
|
|
{EEL_DIE + 0, EEL_DIE_RATE, DoEelDeath, &s_EelDie[3]},
|
|
{EEL_DIE + 0, EEL_DIE_RATE, DoEelDeath, &s_EelDie[4]},
|
|
{EEL_DIE + 0, EEL_DIE_RATE, DoEelDeath, &s_EelDie[5]},
|
|
{EEL_DIE + 0, EEL_DIE_RATE, DoEelDeath, &s_EelDie[5]},
|
|
};
|
|
|
|
STATEp sg_EelDie[] =
|
|
{
|
|
s_EelDie
|
|
};
|
|
|
|
STATE s_EelDead[] =
|
|
{
|
|
// {EEL_DEAD, SF_QUICK_CALL , QueueFloorBlood, &s_EelDead[1]},
|
|
{EEL_DEAD, EEL_DIE_RATE, DoActorDebris, &s_EelDead[0]},
|
|
};
|
|
|
|
STATEp sg_EelDead[] =
|
|
{
|
|
s_EelDead
|
|
};
|
|
|
|
|
|
/*
|
|
STATEp *Stand[MAX_WEAPONS];
|
|
STATEp *Run;
|
|
STATEp *Jump;
|
|
STATEp *Fall;
|
|
STATEp *Crawl;
|
|
STATEp *Swim;
|
|
STATEp *Fly;
|
|
STATEp *Rise;
|
|
STATEp *Sit;
|
|
STATEp *Look;
|
|
STATEp *Climb;
|
|
STATEp *Pain;
|
|
STATEp *Death1;
|
|
STATEp *Death2;
|
|
STATEp *Dead;
|
|
STATEp *DeathJump;
|
|
STATEp *DeathFall;
|
|
STATEp *CloseAttack[2];
|
|
STATEp *Attack[6];
|
|
STATEp *Special[2];
|
|
*/
|
|
|
|
|
|
ACTOR_ACTION_SET EelActionSet =
|
|
{
|
|
sg_EelStand,
|
|
sg_EelRun,
|
|
nullptr,
|
|
nullptr,
|
|
nullptr,
|
|
sg_EelRun,
|
|
nullptr,
|
|
nullptr,
|
|
sg_EelStand,
|
|
nullptr,
|
|
nullptr, //climb
|
|
sg_EelStand, //pain
|
|
sg_EelDie,
|
|
nullptr,
|
|
sg_EelDead,
|
|
nullptr,
|
|
nullptr,
|
|
{sg_EelAttack},
|
|
{1024},
|
|
{sg_EelAttack},
|
|
{1024},
|
|
{nullptr,nullptr},
|
|
nullptr,
|
|
nullptr
|
|
};
|
|
|
|
int DoEelMatchPlayerZ(DSWActor* actor);
|
|
|
|
|
|
void
|
|
EelCommon(short SpriteNum)
|
|
{
|
|
SPRITEp sp = &sprite[SpriteNum];
|
|
USERp u = User[SpriteNum].Data();
|
|
|
|
sp->clipdist = (100) >> 2;
|
|
u->floor_dist = Z(16);
|
|
u->floor_dist = Z(16);
|
|
u->ceiling_dist = Z(20);
|
|
|
|
u->sz = sp->z;
|
|
|
|
sp->xrepeat = 35;
|
|
sp->yrepeat = 27;
|
|
u->Radius = 400;
|
|
}
|
|
|
|
int
|
|
SetupEel(short SpriteNum)
|
|
{
|
|
SPRITEp sp = &sprite[SpriteNum];
|
|
USERp u;
|
|
ANIMATOR DoActorDecide;
|
|
|
|
if (TEST(sp->cstat, CSTAT_SPRITE_RESTORE))
|
|
{
|
|
u = User[SpriteNum].Data();
|
|
ASSERT(u);
|
|
}
|
|
else
|
|
{
|
|
u = SpawnUser(SpriteNum,EEL_RUN_R0,s_EelRun[0]);
|
|
u->Health = 40;
|
|
}
|
|
|
|
ChangeState(SpriteNum, s_EelRun[0]);
|
|
u->Attrib = &EelAttrib;
|
|
DoActorSetSpeed(SpriteNum, NORM_SPEED);
|
|
u->StateEnd = s_EelDie;
|
|
u->Rot = sg_EelRun;
|
|
|
|
EnemyDefaults(SpriteNum, &EelActionSet, &EelPersonality);
|
|
|
|
SET(u->Flags, SPR_NO_SCAREDZ|SPR_XFLIP_TOGGLE);
|
|
|
|
EelCommon(SpriteNum);
|
|
|
|
RESET(u->Flags, SPR_SHADOW); // Turn off shadows
|
|
u->zclip = Z(8);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int NullEel(DSWActor* actor)
|
|
{
|
|
USER* u = actor->u();
|
|
int SpriteNum = u->SpriteNum;
|
|
|
|
if (TEST(u->Flags,SPR_SLIDING))
|
|
DoActorSlide(actor);
|
|
|
|
DoEelMatchPlayerZ(actor);
|
|
|
|
DoActorSectorDamage(actor);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DoEelMatchPlayerZ(DSWActor* actor)
|
|
{
|
|
USER* u = actor->u();
|
|
int SpriteNum = u->SpriteNum;
|
|
SPRITEp sp = &sprite[SpriteNum];
|
|
SPRITEp tsp = User[SpriteNum]->tgt_sp;
|
|
int zdiff,zdist;
|
|
int loz,hiz;
|
|
int dist,a,b,c;
|
|
|
|
int bound;
|
|
|
|
if (FAF_ConnectArea(sp->sectnum))
|
|
{
|
|
if (u->hi_sectp)
|
|
{
|
|
u->hiz = sector[sp->sectnum].ceilingz + Z(16);
|
|
u->hi_sectp = §or[sp->sectnum];
|
|
}
|
|
else
|
|
{
|
|
if (u->hiz < sector[sp->sectnum].ceilingz + Z(16))
|
|
u->hiz = sector[sp->sectnum].ceilingz + Z(16);
|
|
}
|
|
}
|
|
|
|
// actor does a sine wave about u->sz - this is the z mid point
|
|
|
|
zdiff = (SPRITEp_BOS(tsp) - Z(8)) - u->sz;
|
|
|
|
// check z diff of the player and the sprite
|
|
zdist = Z(20 + RandomRange(64)); // put a random amount
|
|
if (labs(zdiff) > zdist)
|
|
{
|
|
if (zdiff > 0)
|
|
// manipulate the z midpoint
|
|
u->sz += 160 * ACTORMOVETICS;
|
|
else
|
|
u->sz -= 160 * ACTORMOVETICS;
|
|
}
|
|
|
|
#define EEL_BOB_AMT (Z(4))
|
|
|
|
// save off lo and hi z
|
|
loz = u->loz;
|
|
hiz = u->hiz;
|
|
|
|
// adjust loz/hiz for water depth
|
|
if (u->lo_sectp && SectUser[u->lo_sectp - sector].Data() && FixedToInt(SectUser[u->lo_sectp - sector]->depth_fixed))
|
|
loz -= Z(FixedToInt(SectUser[u->lo_sectp - sector]->depth_fixed)) - Z(8);
|
|
|
|
// lower bound
|
|
if (u->lo_sp && u->tgt_sp == u->hi_sp)
|
|
{
|
|
DISTANCE(sp->x, sp->y, u->lo_sp->x, u->lo_sp->y, dist, a, b, c);
|
|
if (dist <= 300)
|
|
bound = u->sz;
|
|
else
|
|
bound = loz - u->floor_dist;
|
|
}
|
|
else
|
|
bound = loz - u->floor_dist - EEL_BOB_AMT;
|
|
|
|
if (u->sz > bound)
|
|
{
|
|
u->sz = bound;
|
|
}
|
|
|
|
// upper bound
|
|
if (u->hi_sp && u->tgt_sp == u->hi_sp)
|
|
{
|
|
DISTANCE(sp->x, sp->y, u->hi_sp->x, u->hi_sp->y, dist, a, b, c);
|
|
if (dist <= 300)
|
|
bound = u->sz;
|
|
else
|
|
bound = hiz + u->ceiling_dist;
|
|
}
|
|
else
|
|
bound = hiz + u->ceiling_dist + EEL_BOB_AMT;
|
|
|
|
if (u->sz < bound)
|
|
{
|
|
u->sz = bound;
|
|
}
|
|
|
|
u->sz = min(u->sz, loz - u->floor_dist);
|
|
u->sz = max(u->sz, hiz + u->ceiling_dist);
|
|
|
|
u->Counter = (u->Counter + (ACTORMOVETICS << 3) + (ACTORMOVETICS << 1)) & 2047;
|
|
sp->z = u->sz + MulScale(EEL_BOB_AMT, bsin(u->Counter), 14);
|
|
|
|
bound = u->hiz + u->ceiling_dist + EEL_BOB_AMT;
|
|
if (sp->z < bound)
|
|
{
|
|
// bumped something
|
|
sp->z = u->sz = bound + EEL_BOB_AMT;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
DoEelDeath(DSWActor* actor)
|
|
{
|
|
USER* u = actor->u();
|
|
int SpriteNum = u->SpriteNum;
|
|
SPRITEp sp = &sprite[SpriteNum];
|
|
int nx, ny;
|
|
if (TEST(u->Flags, SPR_FALLING))
|
|
{
|
|
DoFall(SpriteNum);
|
|
}
|
|
else
|
|
{
|
|
DoFindGroundPoint(SpriteNum);
|
|
u->floor_dist = 0;
|
|
DoBeginFall(SpriteNum);
|
|
}
|
|
|
|
if (TEST(u->Flags, SPR_SLIDING))
|
|
DoActorSlide(actor);
|
|
|
|
// slide while falling
|
|
nx = MulScale(sp->xvel, bcos(sp->ang), 14);
|
|
ny = MulScale(sp->xvel, bsin(sp->ang), 14);
|
|
|
|
u->ret = move_sprite(SpriteNum, nx, ny, 0L, u->ceiling_dist, u->floor_dist, CLIPMASK_MISSILE, ACTORMOVETICS);
|
|
DoFindGroundPoint(SpriteNum);
|
|
|
|
// on the ground
|
|
if (sp->z >= u->loz)
|
|
{
|
|
RESET(u->Flags, SPR_FALLING|SPR_SLIDING);
|
|
if (RandomRange(1000) > 500)
|
|
SET(sp->cstat, CSTAT_SPRITE_XFLIP);
|
|
if (RandomRange(1000) > 500)
|
|
SET(sp->cstat, CSTAT_SPRITE_YFLIP);
|
|
NewStateGroup(SpriteNum, u->ActorActionSet->Dead);
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int DoEelMove(DSWActor* actor)
|
|
{
|
|
USER* u = actor->u();
|
|
int SpriteNum = u->SpriteNum;
|
|
|
|
ASSERT(u->Rot != nullptr);
|
|
|
|
if (SpriteOverlap(SpriteNum, int16_t(u->tgt_sp - sprite)))
|
|
NewStateGroup(SpriteNum, u->ActorActionSet->CloseAttack[0]);
|
|
|
|
if (TEST(u->Flags,SPR_SLIDING))
|
|
DoActorSlide(actor);
|
|
|
|
if (u->track >= 0)
|
|
ActorFollowTrack(SpriteNum, ACTORMOVETICS);
|
|
else
|
|
(*u->ActorActionFunc)(actor);
|
|
|
|
DoEelMatchPlayerZ(actor);
|
|
|
|
DoActorSectorDamage(actor);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
#include "saveable.h"
|
|
|
|
static saveable_code saveable_eel_code[] =
|
|
{
|
|
SAVE_CODE(DoEelMatchPlayerZ),
|
|
SAVE_CODE(DoEelDeath),
|
|
SAVE_CODE(DoEelMove)
|
|
};
|
|
|
|
static saveable_data saveable_eel_data[] =
|
|
{
|
|
SAVE_DATA(EelBattle),
|
|
SAVE_DATA(EelOffense),
|
|
SAVE_DATA(EelBroadcast),
|
|
SAVE_DATA(EelSurprised),
|
|
SAVE_DATA(EelEvasive),
|
|
SAVE_DATA(EelLostTarget),
|
|
SAVE_DATA(EelCloseRange),
|
|
SAVE_DATA(EelTouchTarget),
|
|
|
|
SAVE_DATA(EelPersonality),
|
|
|
|
SAVE_DATA(EelAttrib),
|
|
|
|
SAVE_DATA(s_EelRun),
|
|
SAVE_DATA(sg_EelRun),
|
|
SAVE_DATA(s_EelStand),
|
|
SAVE_DATA(sg_EelStand),
|
|
SAVE_DATA(s_EelAttack),
|
|
SAVE_DATA(sg_EelAttack),
|
|
SAVE_DATA(s_EelDie),
|
|
SAVE_DATA(sg_EelDie),
|
|
SAVE_DATA(s_EelDead),
|
|
SAVE_DATA(sg_EelDead),
|
|
|
|
SAVE_DATA(EelActionSet)
|
|
};
|
|
|
|
saveable_module saveable_eel =
|
|
{
|
|
// code
|
|
saveable_eel_code,
|
|
SIZ(saveable_eel_code),
|
|
|
|
// data
|
|
saveable_eel_data,
|
|
SIZ(saveable_eel_data)
|
|
};
|
|
END_SW_NS
|