2015-05-19 21:54:34 +00:00
|
|
|
//-------------------------------------------------------------------------
|
|
|
|
/*
|
|
|
|
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
|
|
|
|
*/
|
|
|
|
//-------------------------------------------------------------------------
|
2019-10-09 16:09:05 +00:00
|
|
|
|
|
|
|
#include "ns.h"
|
2019-11-17 17:02:17 +00:00
|
|
|
// Added Ninja Sliced fix
|
|
|
|
// Fixed Ninja sliced dead and rotation
|
|
|
|
// Added s_NinjaDieSlicedHack[]
|
|
|
|
//
|
2019-10-09 16:09:05 +00:00
|
|
|
|
2015-05-19 21:54:34 +00:00
|
|
|
#include "build.h"
|
|
|
|
|
|
|
|
#include "names2.h"
|
|
|
|
#include "panel.h"
|
2020-08-05 22:18:45 +00:00
|
|
|
#include "misc.h"
|
2015-05-19 21:54:34 +00:00
|
|
|
#include "tags.h"
|
|
|
|
#include "weapon.h"
|
|
|
|
#include "sprite.h"
|
|
|
|
|
2019-10-09 16:09:05 +00:00
|
|
|
BEGIN_SW_NS
|
|
|
|
|
2021-10-29 18:49:57 +00:00
|
|
|
DSWActor swActors[MAXSPRITES];
|
|
|
|
|
2015-05-19 21:54:34 +00:00
|
|
|
extern int jump_grav;
|
|
|
|
|
|
|
|
extern STATE s_DebrisNinja[];
|
|
|
|
extern STATE s_DebrisRat[];
|
|
|
|
extern STATE s_DebrisCrab[];
|
|
|
|
extern STATE s_DebrisStarFish[];
|
|
|
|
extern STATE s_NinjaDieSliced[];
|
2019-11-17 17:02:17 +00:00
|
|
|
extern STATE s_NinjaDieSlicedHack[];
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
extern STATEp sg_NinjaGrabThroat[];
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-10-29 19:06:37 +00:00
|
|
|
int DoScaleSprite(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 19:06:37 +00:00
|
|
|
auto u = actor->u();
|
|
|
|
auto sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
int scale_value;
|
|
|
|
|
|
|
|
if (u->scale_speed)
|
|
|
|
{
|
|
|
|
u->scale_value += u->scale_speed * ACTORMOVETICS;
|
|
|
|
|
|
|
|
scale_value = u->scale_value >> 8;
|
|
|
|
|
|
|
|
if (u->scale_speed > 0)
|
|
|
|
{
|
|
|
|
if (scale_value > u->scale_tgt)
|
|
|
|
u->scale_speed = 0;
|
|
|
|
else
|
|
|
|
sp->xrepeat = sp->yrepeat = scale_value;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (scale_value < u->scale_tgt)
|
|
|
|
u->scale_speed = 0;
|
|
|
|
else
|
|
|
|
sp->xrepeat = sp->yrepeat = scale_value;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-29 20:00:27 +00:00
|
|
|
int DoActorDie(DSWActor* actor, DSWActor* weapActor, int meansofdeath)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 20:00:27 +00:00
|
|
|
auto u = actor->u();
|
|
|
|
auto sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
|
2021-10-30 18:00:02 +00:00
|
|
|
change_actor_stat(actor, STAT_DEAD_ACTOR);
|
2015-05-19 21:54:34 +00:00
|
|
|
SET(u->Flags, SPR_DEAD);
|
|
|
|
RESET(u->Flags, SPR_FALLING | SPR_JUMPING);
|
|
|
|
u->floor_dist = Z(40);
|
|
|
|
|
|
|
|
// test for gibable dead bodies
|
|
|
|
SET(sp->extra, SPRX_BREAKABLE);
|
|
|
|
SET(sp->cstat, CSTAT_SPRITE_BREAKABLE);
|
|
|
|
|
2021-10-29 20:00:27 +00:00
|
|
|
if (weapActor == nullptr)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
// killed by one of these non-sprites
|
2021-10-29 20:00:27 +00:00
|
|
|
switch (meansofdeath)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
case WPN_NM_LAVA:
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
u->RotNum = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WPN_NM_SECTOR_SQUISH:
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
u->RotNum = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-29 20:00:27 +00:00
|
|
|
if (!weapActor->hasU()) return 0;
|
|
|
|
auto wu = weapActor->u();
|
|
|
|
auto wp = &weapActor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// killed by one of these sprites
|
2021-10-29 20:00:27 +00:00
|
|
|
switch (wu->ID)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
// Coolie actually explodes himself
|
2021-10-30 22:29:54 +00:00
|
|
|
// he is the Sprite AND weapon
|
2015-05-19 21:54:34 +00:00
|
|
|
case COOLIE_RUN_R0:
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
u->RotNum = 0;
|
|
|
|
sp->xvel <<= 1;
|
2021-07-10 12:25:18 +00:00
|
|
|
u->ActorActionFunc = nullptr;
|
2021-10-29 20:00:27 +00:00
|
|
|
sp->ang = NORM_ANGLE(sp->ang + 1024);
|
2015-05-19 21:54:34 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case NINJA_RUN_R0:
|
|
|
|
if (u->ID == NINJA_RUN_R0) // Cut in half!
|
|
|
|
{
|
2021-10-29 20:00:27 +00:00
|
|
|
if (wu->WeaponNum != WPN_FIST)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2019-11-17 17:02:17 +00:00
|
|
|
if (sw_ninjahack)
|
2021-10-30 19:02:14 +00:00
|
|
|
SpawnBlood(actor, actor, -1, -1, -1, -1);
|
2015-05-19 21:54:34 +00:00
|
|
|
InitPlasmaFountain(wp, sp);
|
|
|
|
InitPlasmaFountain(wp, sp);
|
2019-12-18 10:09:01 +00:00
|
|
|
PlaySound(DIGI_NINJAINHALF, sp, v3df_none);
|
2019-11-17 17:02:17 +00:00
|
|
|
if (sw_ninjahack)
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, &s_NinjaDieSlicedHack[5]);
|
2019-11-17 17:02:17 +00:00
|
|
|
else
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, &s_NinjaDieSliced[0]);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-09-20 06:59:54 +00:00
|
|
|
if (RandomRange(1000) > 500)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
InitPlasmaFountain(wp, sp);
|
|
|
|
}
|
|
|
|
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
u->RotNum = 0;
|
2021-07-10 12:25:18 +00:00
|
|
|
u->ActorActionFunc = nullptr;
|
2021-09-20 06:59:54 +00:00
|
|
|
sp->xvel = 200 + RandomRange(200);
|
|
|
|
u->jump_speed = -200 - RandomRange(250);
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorBeginJump(actor);
|
2021-10-29 20:00:27 +00:00
|
|
|
sp->ang = wp->ang;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// test for gibable dead bodies
|
2021-09-20 06:59:54 +00:00
|
|
|
if (RandomRange(1000) > 500)
|
2015-05-19 21:54:34 +00:00
|
|
|
SET(sp->cstat, CSTAT_SPRITE_YFLIP);
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
sp->xvel = 0;
|
|
|
|
u->jump_speed = 0;
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorBeginJump(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
u->RotNum = 0;
|
|
|
|
|
2021-07-10 12:25:18 +00:00
|
|
|
u->ActorActionFunc = nullptr;
|
2015-05-19 21:54:34 +00:00
|
|
|
//u->ActorActionFunc = NullAnimator;
|
2019-11-17 17:02:17 +00:00
|
|
|
if (!sw_ninjahack)
|
2021-10-29 20:00:27 +00:00
|
|
|
sp->ang = wp->ang;
|
2015-05-19 21:54:34 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case COOLG_RUN_R0:
|
|
|
|
case SKEL_RUN_R0:
|
|
|
|
case RIPPER_RUN_R0:
|
|
|
|
case RIPPER2_RUN_R0:
|
|
|
|
case EEL_RUN_R0:
|
|
|
|
case STAR1:
|
|
|
|
case SUMO_RUN_R0:
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
u->RotNum = 0;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case UZI_SMOKE:
|
2021-09-20 06:59:54 +00:00
|
|
|
if (RandomRange(1000) > 500)
|
2015-05-19 21:54:34 +00:00
|
|
|
SET(sp->cstat, CSTAT_SPRITE_YFLIP);
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
u->RotNum = 0;
|
|
|
|
// Rippers still gotta jump or they fall off walls weird
|
|
|
|
if (u->ID == RIPPER_RUN_R0 || u->ID == RIPPER2_RUN_R0)
|
|
|
|
{
|
|
|
|
sp->xvel <<= 1;
|
2021-09-20 06:59:54 +00:00
|
|
|
u->jump_speed = -100 - RandomRange(250);
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorBeginJump(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sp->xvel = 0;
|
2021-09-20 06:59:54 +00:00
|
|
|
u->jump_speed = -10 - RandomRange(25);
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorBeginJump(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
2021-07-10 12:25:18 +00:00
|
|
|
u->ActorActionFunc = nullptr;
|
2015-05-19 21:54:34 +00:00
|
|
|
// Get angle to player
|
2021-10-30 11:16:40 +00:00
|
|
|
sp->ang = NORM_ANGLE(getangle(u->targetActor->s().x - sp->x, u->targetActor->s().y - sp->y) + 1024);
|
2015-05-19 21:54:34 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case UZI_SMOKE+1: // Shotgun
|
2021-09-20 06:59:54 +00:00
|
|
|
if (RandomRange(1000) > 500)
|
2015-05-19 21:54:34 +00:00
|
|
|
SET(sp->cstat, CSTAT_SPRITE_YFLIP);
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
u->RotNum = 0;
|
|
|
|
|
|
|
|
// Rippers still gotta jump or they fall off walls weird
|
|
|
|
if (u->ID == RIPPER_RUN_R0 || u->ID == RIPPER2_RUN_R0)
|
|
|
|
{
|
2021-09-20 06:59:54 +00:00
|
|
|
sp->xvel = 75 + RandomRange(100);
|
|
|
|
u->jump_speed = -100 - RandomRange(150);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-09-20 06:59:54 +00:00
|
|
|
sp->xvel = 100 + RandomRange(200);
|
|
|
|
u->jump_speed = -100 - RandomRange(250);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorBeginJump(actor);
|
2021-07-10 12:25:18 +00:00
|
|
|
u->ActorActionFunc = nullptr;
|
2015-05-19 21:54:34 +00:00
|
|
|
// Get angle to player
|
2021-10-30 11:16:40 +00:00
|
|
|
sp->ang = NORM_ANGLE(getangle(u->targetActor->s().x - sp->x, u->targetActor->s().y - sp->y) + 1024);
|
2015-05-19 21:54:34 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
switch (u->ID)
|
|
|
|
{
|
|
|
|
case SKULL_R0:
|
|
|
|
case BETTY_R0:
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2021-09-20 06:59:54 +00:00
|
|
|
if (RandomRange(1000) > 700)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
InitPlasmaFountain(wp, sp);
|
|
|
|
}
|
|
|
|
|
2021-09-20 06:59:54 +00:00
|
|
|
if (RandomRange(1000) > 500)
|
2015-05-19 21:54:34 +00:00
|
|
|
SET(sp->cstat, CSTAT_SPRITE_YFLIP);
|
2021-10-30 18:11:31 +00:00
|
|
|
ChangeState(actor, u->StateEnd);
|
2015-05-19 21:54:34 +00:00
|
|
|
u->RotNum = 0;
|
2021-07-10 12:25:18 +00:00
|
|
|
u->ActorActionFunc = nullptr;
|
2021-09-20 06:59:54 +00:00
|
|
|
sp->xvel = 300 + RandomRange(400);
|
|
|
|
u->jump_speed = -300 - RandomRange(350);
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorBeginJump(actor);
|
2021-10-29 20:00:27 +00:00
|
|
|
sp->ang = wp->ang;
|
2015-05-19 21:54:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// These are too big to flip upside down
|
|
|
|
switch (u->ID)
|
|
|
|
{
|
|
|
|
case RIPPER2_RUN_R0:
|
|
|
|
case COOLIE_RUN_R0:
|
|
|
|
case SUMO_RUN_R0:
|
|
|
|
case ZILLA_RUN_R0:
|
|
|
|
RESET(sp->cstat, CSTAT_SPRITE_YFLIP);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
u->ID = 0;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-29 20:08:56 +00:00
|
|
|
void DoDebrisCurrent(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
int nx, ny;
|
|
|
|
int ret=0;
|
2021-10-29 20:08:56 +00:00
|
|
|
USERp u = actor->u();
|
|
|
|
auto sp = &actor->s();
|
2021-04-02 10:55:58 +00:00
|
|
|
SECT_USERp sectu = SectUser[sp->sectnum].Data();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
//sp->clipdist = (256+128)>>2;
|
|
|
|
|
2021-01-04 11:36:54 +00:00
|
|
|
nx = MulScale(DIV4(sectu->speed), bcos(sectu->ang), 14);
|
|
|
|
ny = MulScale(DIV4(sectu->speed), bsin(sectu->ang), 14);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// faster than move_sprite
|
|
|
|
//move_missile(sp-sprite, nx, ny, 0, Z(2), Z(0), 0, ACTORMOVETICS);
|
2021-05-11 22:48:41 +00:00
|
|
|
ret = move_sprite(int(sp-sprite), nx, ny, 0, u->ceiling_dist, u->floor_dist, 0, ACTORMOVETICS);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// attempt to move away from wall
|
|
|
|
if (ret)
|
|
|
|
{
|
|
|
|
short rang = RANDOM_P2(2048);
|
|
|
|
|
2021-01-04 11:36:54 +00:00
|
|
|
nx = MulScale(DIV4(sectu->speed), bcos(sectu->ang + rang), 14);
|
|
|
|
nx = MulScale(DIV4(sectu->speed), bsin(sectu->ang + rang), 14);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-05-11 22:48:41 +00:00
|
|
|
move_sprite(int(sp-sprite), nx, ny, 0, u->ceiling_dist, u->floor_dist, 0, ACTORMOVETICS);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
sp->z = u->loz;
|
|
|
|
}
|
|
|
|
|
2021-10-29 20:08:56 +00:00
|
|
|
int DoActorSectorDamage(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2021-10-29 20:08:56 +00:00
|
|
|
SPRITEp sp = &actor->s();
|
2021-04-02 10:55:58 +00:00
|
|
|
SECT_USERp sectu = SectUser[sp->sectnum].Data();
|
2015-05-19 21:54:34 +00:00
|
|
|
SECTORp sectp = §or[sp->sectnum];
|
|
|
|
|
|
|
|
if (u->Health <= 0)
|
2020-09-09 17:52:52 +00:00
|
|
|
return false;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
if (sectu && sectu->damage)
|
|
|
|
{
|
|
|
|
if (TEST(sectu->flags, SECTFU_DAMAGE_ABOVE_SECTOR))
|
|
|
|
{
|
|
|
|
if ((u->DamageTics -= synctics) < 0)
|
|
|
|
{
|
|
|
|
u->DamageTics = 60;
|
|
|
|
u->Health -= sectu->damage;
|
|
|
|
|
|
|
|
if (u->Health <= 0)
|
|
|
|
{
|
2021-10-30 19:07:15 +00:00
|
|
|
UpdateSinglePlayKills(actor);
|
2021-10-29 20:00:27 +00:00
|
|
|
DoActorDie(actor, nullptr, WPN_NM_LAVA);
|
2020-09-09 17:52:52 +00:00
|
|
|
return true;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (SPRITEp_BOS(sp) >= sectp->floorz)
|
|
|
|
{
|
|
|
|
if ((u->DamageTics -= synctics) < 0)
|
|
|
|
{
|
|
|
|
u->DamageTics = 60;
|
|
|
|
u->Health -= sectu->damage;
|
|
|
|
|
|
|
|
if (u->Health <= 0)
|
|
|
|
{
|
2021-10-30 19:07:15 +00:00
|
|
|
UpdateSinglePlayKills(actor);
|
2021-10-29 20:00:27 +00:00
|
|
|
DoActorDie(actor, nullptr, WPN_NM_LAVA);
|
2020-09-09 17:52:52 +00:00
|
|
|
return true;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// note that most squishing is done in vator.c
|
|
|
|
if (u->lo_sectp && u->hi_sectp && labs(u->loz - u->hiz) < DIV2(SPRITEp_SIZE_Z(sp)))
|
|
|
|
//if (u->lo_sectp && u->hi_sectp && labs(u->loz - u->hiz) < SPRITEp_SIZE_Z(sp))
|
|
|
|
{
|
|
|
|
u->Health = 0;
|
2021-10-30 19:44:51 +00:00
|
|
|
if (SpawnShrap(actor, nullptr, WPN_NM_SECTOR_SQUISH))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-30 19:07:15 +00:00
|
|
|
UpdateSinglePlayKills(actor);
|
2021-10-30 20:44:16 +00:00
|
|
|
SetSuicide(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-09-09 17:52:52 +00:00
|
|
|
ASSERT(true == false);
|
2021-10-29 20:00:27 +00:00
|
|
|
//DoActorDie(actor, nullptr, WPN_NM_SECTOR_SQUISH);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
2020-09-09 17:52:52 +00:00
|
|
|
return true;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
2020-09-09 17:52:52 +00:00
|
|
|
return false;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-29 20:08:56 +00:00
|
|
|
bool move_debris(DSWActor* actor, int xchange, int ychange, int zchange)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 20:08:56 +00:00
|
|
|
USERp u = actor->u();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-10-29 20:08:56 +00:00
|
|
|
u->ret = move_sprite(actor->GetSpriteIndex(), xchange, ychange, zchange,
|
2015-05-19 21:54:34 +00:00
|
|
|
u->ceiling_dist, u->floor_dist, 0, ACTORMOVETICS);
|
|
|
|
|
|
|
|
return !u->ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
// !AIC - Supposed to allow floating of DEBRIS (dead bodies, flotsam, jetsam). Or if water has
|
|
|
|
// current move with the current.
|
|
|
|
|
2021-10-29 20:08:56 +00:00
|
|
|
int DoActorDebris(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2021-10-29 20:08:56 +00:00
|
|
|
SPRITEp sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
SECTORp sectp = §or[sp->sectnum];
|
|
|
|
int nx, ny;
|
|
|
|
|
|
|
|
// This was move from DoActorDie so actor's can't be walked through until they are on the floor
|
|
|
|
RESET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
|
|
|
|
|
|
|
|
// Don't let some actors float
|
|
|
|
switch (u->ID)
|
|
|
|
{
|
|
|
|
case HORNET_RUN_R0:
|
|
|
|
case BUNNY_RUN_R0:
|
2021-10-30 20:53:24 +00:00
|
|
|
KillActor(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
case ZILLA_RUN_R0:
|
|
|
|
getzsofslope(sp->sectnum, sp->x, sp->y, &u->hiz, &u->loz);
|
|
|
|
u->lo_sectp = §or[sp->sectnum];
|
|
|
|
u->hi_sectp = §or[sp->sectnum];
|
2021-10-30 22:29:54 +00:00
|
|
|
u->lowActor = nullptr;
|
2021-10-30 22:39:02 +00:00
|
|
|
u->highActor = nullptr;
|
2015-05-19 21:54:34 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TEST(sectp->extra, SECTFX_SINK))
|
|
|
|
{
|
|
|
|
if (TEST(sectp->extra, SECTFX_CURRENT))
|
|
|
|
{
|
2021-10-29 20:08:56 +00:00
|
|
|
DoDebrisCurrent(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-11-15 09:45:03 +00:00
|
|
|
//nx = sp->xvel * ACTORMOVETICS * bcos(sp->ang) >> 14;
|
|
|
|
//ny = sp->xvel * ACTORMOVETICS * bsin(sp->ang) >> 14;
|
2021-01-04 11:36:54 +00:00
|
|
|
nx = MulScale(ACTORMOVETICS, bcos(sp->ang), 14);
|
|
|
|
ny = MulScale(ACTORMOVETICS, bsin(sp->ang), 14);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
//sp->clipdist = (256+128)>>2;
|
|
|
|
|
2021-10-29 20:08:56 +00:00
|
|
|
if (!move_debris(actor, nx, ny, 0L))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
sp->ang = RANDOM_P2(2048);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-18 22:24:25 +00:00
|
|
|
if (SectUser[sp->sectnum].Data() && FixedToInt(SectUser[sp->sectnum]->depth_fixed) > 10) // JBF: added null check
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
u->WaitTics = (u->WaitTics + (ACTORMOVETICS << 3)) & 1023;
|
2020-11-15 09:45:03 +00:00
|
|
|
//sp->z = Z(2) + u->loz + ((Z(4) * (int) bsin(u->WaitTics)) >> 14);
|
2021-01-04 11:36:54 +00:00
|
|
|
sp->z = u->loz - MulScale(Z(2), bsin(u->WaitTics), 14);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sp->z = u->loz;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-29 20:08:56 +00:00
|
|
|
int DoFireFly(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2021-10-29 20:08:56 +00:00
|
|
|
SPRITEp sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
int nx, ny;
|
|
|
|
|
2020-11-15 09:45:03 +00:00
|
|
|
nx = 4 * ACTORMOVETICS * bcos(sp->ang) >> 14;
|
|
|
|
ny = 4 * ACTORMOVETICS * bsin(sp->ang) >> 14;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
sp->clipdist = 256>>2;
|
2021-10-30 21:03:26 +00:00
|
|
|
if (!move_actor(actor, nx, ny, 0L))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
sp->ang = NORM_ANGLE(sp->ang + 1024);
|
|
|
|
}
|
|
|
|
|
|
|
|
u->WaitTics = (u->WaitTics + (ACTORMOVETICS << 1)) & 2047;
|
|
|
|
|
2021-01-04 11:36:54 +00:00
|
|
|
sp->z = u->sz + MulScale(Z(32), bsin(u->WaitTics), 14);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-29 20:08:56 +00:00
|
|
|
int DoGenerateSewerDebris(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 20:08:56 +00:00
|
|
|
SPRITEp sp = &actor->s();
|
|
|
|
USERp u = actor->u();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
static STATEp Debris[] =
|
|
|
|
{
|
|
|
|
s_DebrisNinja,
|
|
|
|
s_DebrisRat,
|
|
|
|
s_DebrisCrab,
|
|
|
|
s_DebrisStarFish
|
|
|
|
};
|
|
|
|
|
|
|
|
u->Tics -= ACTORMOVETICS;
|
|
|
|
|
|
|
|
if (u->Tics <= 0)
|
|
|
|
{
|
|
|
|
u->Tics = u->WaitTics;
|
|
|
|
|
2021-10-30 14:12:19 +00:00
|
|
|
auto spawned = SpawnActor(STAT_DEAD_ACTOR, 0, Debris[RANDOM_P2(4<<8)>>8], sp->sectnum, sp->x, sp->y, sp->z, sp->ang, 200);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-10-30 14:12:19 +00:00
|
|
|
SetOwner(actor, spawned);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// !AIC - Tries to keep actors correctly on the floor. More that a bit messy.
|
|
|
|
|
2021-10-29 20:34:54 +00:00
|
|
|
void KeepActorOnFloor(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 20:34:54 +00:00
|
|
|
USERp u = actor->u();
|
|
|
|
SPRITEp sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
SECTORp sectp;
|
|
|
|
int depth;
|
|
|
|
|
|
|
|
sectp = §or[sp->sectnum];
|
|
|
|
|
|
|
|
RESET(sp->cstat, CSTAT_SPRITE_YFLIP); // If upside down, reset it
|
|
|
|
|
|
|
|
if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
|
|
|
|
return;
|
|
|
|
|
2021-04-02 10:55:58 +00:00
|
|
|
if (u->lo_sectp && SectUser[u->lo_sectp - sector].Data())
|
2021-04-18 22:24:25 +00:00
|
|
|
depth = FixedToInt(SectUser[u->lo_sectp - sector]->depth_fixed);
|
2015-05-19 21:54:34 +00:00
|
|
|
else
|
|
|
|
depth = 0;
|
|
|
|
|
|
|
|
if (TEST(sectp->extra, SECTFX_SINK) &&
|
|
|
|
depth > 35 &&
|
|
|
|
u->ActorActionSet && u->ActorActionSet->Swim)
|
|
|
|
{
|
|
|
|
if (TEST(u->Flags, SPR_SWIMMING))
|
|
|
|
{
|
|
|
|
if (u->Rot != u->ActorActionSet->Run && u->Rot != u->ActorActionSet->Swim && u->Rot != u->ActorActionSet->Stand)
|
|
|
|
{
|
|
|
|
// was swimming but have now stopped
|
|
|
|
RESET(u->Flags, SPR_SWIMMING);
|
|
|
|
RESET(sp->cstat, CSTAT_SPRITE_YCENTER);
|
2021-02-28 11:35:34 +00:00
|
|
|
u->oz = sp->z = u->loz;
|
2021-01-05 12:43:49 +00:00
|
|
|
sp->backupz();
|
2015-05-19 21:54:34 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (u->Rot == u->ActorActionSet->Run)
|
|
|
|
{
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->ActorActionSet->Swim);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// are swimming
|
2021-02-28 11:35:34 +00:00
|
|
|
u->oz = sp->z = u->loz - Z(depth);
|
2021-01-05 12:43:49 +00:00
|
|
|
sp->backupz();
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// only start swimming if you are running
|
|
|
|
if (u->Rot == u->ActorActionSet->Run || u->Rot == u->ActorActionSet->Swim)
|
|
|
|
{
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->ActorActionSet->Swim);
|
2021-02-28 11:35:34 +00:00
|
|
|
u->oz = sp->z = u->loz - Z(depth);
|
2021-01-05 12:43:49 +00:00
|
|
|
sp->backupz();
|
2015-05-19 21:54:34 +00:00
|
|
|
SET(u->Flags, SPR_SWIMMING);
|
|
|
|
SET(sp->cstat, CSTAT_SPRITE_YCENTER);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RESET(u->Flags, SPR_SWIMMING);
|
|
|
|
RESET(sp->cstat, CSTAT_SPRITE_YCENTER);
|
2021-02-28 11:35:34 +00:00
|
|
|
u->oz = sp->z = u->loz;
|
2021-01-05 12:43:49 +00:00
|
|
|
sp->backupz();
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// NOT in a swimming situation
|
|
|
|
RESET(u->Flags, SPR_SWIMMING);
|
|
|
|
RESET(sp->cstat, CSTAT_SPRITE_YCENTER);
|
|
|
|
|
|
|
|
#if 1
|
|
|
|
if (TEST(u->Flags, SPR_MOVED))
|
|
|
|
{
|
2021-02-28 11:35:34 +00:00
|
|
|
u->oz = sp->z = u->loz;
|
2021-01-05 12:43:49 +00:00
|
|
|
sp->backupz();
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int ceilz,ceilhit,florz,florhit;
|
|
|
|
FAFgetzrangepoint(sp->x, sp->y, sp->z, sp->sectnum,
|
|
|
|
&ceilz, &ceilhit, &florz, &florhit);
|
|
|
|
|
2021-02-28 11:35:34 +00:00
|
|
|
u->oz = sp->z = florz;
|
2021-01-05 12:43:49 +00:00
|
|
|
sp->backupz();
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-10-29 20:39:36 +00:00
|
|
|
int DoActorBeginSlide(DSWActor* actor, short ang, short vel, short dec)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 20:39:36 +00:00
|
|
|
USERp u = actor->u();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
SET(u->Flags, SPR_SLIDING);
|
|
|
|
|
|
|
|
u->slide_ang = ang;
|
|
|
|
u->slide_vel = vel;
|
|
|
|
u->slide_dec = dec;
|
|
|
|
|
2021-10-29 18:49:57 +00:00
|
|
|
//DoActorSlide(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// !AIC - Sliding can occur in different directions from movement of the actor.
|
|
|
|
// Has its own set of variables
|
|
|
|
|
2021-10-29 20:42:09 +00:00
|
|
|
int DoActorSlide(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2015-05-19 21:54:34 +00:00
|
|
|
int nx, ny;
|
|
|
|
|
2021-01-04 11:36:54 +00:00
|
|
|
nx = MulScale(u->slide_vel, bcos(u->slide_ang), 14);
|
|
|
|
ny = MulScale(u->slide_vel, bsin(u->slide_ang), 14);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-10-30 21:03:26 +00:00
|
|
|
if (!move_actor(actor, nx, ny, 0L))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
RESET(u->Flags, SPR_SLIDING);
|
2020-09-09 17:52:52 +00:00
|
|
|
return false;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
u->slide_vel -= u->slide_dec * ACTORMOVETICS;
|
|
|
|
|
|
|
|
if (u->slide_vel < 20)
|
|
|
|
{
|
|
|
|
RESET(u->Flags, SPR_SLIDING);
|
|
|
|
}
|
|
|
|
|
2020-09-09 17:52:52 +00:00
|
|
|
return true;
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// !AIC - Actor jumping and falling
|
|
|
|
|
2021-10-29 20:42:09 +00:00
|
|
|
int DoActorBeginJump(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
SET(u->Flags, SPR_JUMPING);
|
|
|
|
RESET(u->Flags, SPR_FALLING);
|
|
|
|
|
|
|
|
// u->jump_speed = should be set before calling
|
|
|
|
|
|
|
|
// set up individual actor jump gravity
|
|
|
|
u->jump_grav = ACTOR_GRAVITY;
|
|
|
|
|
|
|
|
// Change sprites state to jumping
|
|
|
|
if (u->ActorActionSet)
|
|
|
|
{
|
|
|
|
if (TEST(u->Flags, SPR_DEAD))
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->ActorActionSet->DeathJump);
|
2015-05-19 21:54:34 +00:00
|
|
|
else
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->ActorActionSet->Jump);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
2021-07-10 12:25:18 +00:00
|
|
|
u->StateFallOverride = nullptr;
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
//DO NOT CALL DoActorJump! DoActorStopFall can cause an infinite loop and
|
|
|
|
//stack overflow if it is called.
|
2021-10-29 18:49:57 +00:00
|
|
|
//DoActorJump(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-29 20:42:09 +00:00
|
|
|
int DoActorJump(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2021-10-29 20:42:09 +00:00
|
|
|
SPRITEp sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
int jump_adj;
|
|
|
|
|
|
|
|
// precalculate jump value to adjust jump speed by
|
|
|
|
jump_adj = u->jump_grav * ACTORMOVETICS;
|
|
|
|
|
|
|
|
// adjust jump speed by gravity - if jump speed greater than 0 player
|
|
|
|
// have started falling
|
|
|
|
if ((u->jump_speed += jump_adj) > 0)
|
|
|
|
{
|
|
|
|
//DSPRINTF(ds,"Actor Jump Height %d", labs(sp->z - sector[sp->sectnum].floorz)>>8 );
|
|
|
|
MONO_PRINT(ds);
|
|
|
|
|
|
|
|
// Start falling
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorBeginFall(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// adjust height by jump speed
|
|
|
|
sp->z += u->jump_speed * ACTORMOVETICS;
|
|
|
|
|
|
|
|
// if player gets to close the ceiling while jumping
|
2021-10-30 21:18:58 +00:00
|
|
|
if (sp->z < u->hiz + Z(PIC_SIZY(sp)))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
// put player at the ceiling
|
2021-10-30 21:18:58 +00:00
|
|
|
sp->z = u->hiz + Z(PIC_SIZY(sp));
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// reverse your speed to falling
|
|
|
|
u->jump_speed = -u->jump_speed;
|
|
|
|
|
|
|
|
// Change sprites state to falling
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorBeginFall(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-29 20:42:09 +00:00
|
|
|
int DoActorBeginFall(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2015-05-19 21:54:34 +00:00
|
|
|
SET(u->Flags, SPR_FALLING);
|
|
|
|
RESET(u->Flags, SPR_JUMPING);
|
|
|
|
|
|
|
|
u->jump_grav = ACTOR_GRAVITY;
|
|
|
|
|
|
|
|
// Change sprites state to falling
|
|
|
|
if (u->ActorActionSet)
|
|
|
|
{
|
|
|
|
if (TEST(u->Flags, SPR_DEAD))
|
|
|
|
{
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->ActorActionSet->DeathFall);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->ActorActionSet->Fall);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
if (u->StateFallOverride)
|
|
|
|
{
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->StateFallOverride);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorFall(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-29 20:42:09 +00:00
|
|
|
int DoActorFall(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2021-10-29 20:42:09 +00:00
|
|
|
SPRITEp sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// adjust jump speed by gravity
|
|
|
|
u->jump_speed += u->jump_grav * ACTORMOVETICS;
|
|
|
|
|
|
|
|
// adjust player height by jump speed
|
|
|
|
sp->z += u->jump_speed * ACTORMOVETICS;
|
|
|
|
|
|
|
|
// Stick like glue when you hit the ground
|
|
|
|
if (sp->z > u->loz)
|
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorStopFall(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-29 20:42:09 +00:00
|
|
|
int DoActorStopFall(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2021-10-29 20:42:09 +00:00
|
|
|
SPRITEp sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
sp->z = u->loz;
|
|
|
|
|
|
|
|
RESET(u->Flags, SPR_FALLING | SPR_JUMPING);
|
|
|
|
RESET(sp->cstat, CSTAT_SPRITE_YFLIP);
|
|
|
|
|
|
|
|
|
|
|
|
// don't stand on face or wall sprites - jump again
|
2021-10-30 22:29:54 +00:00
|
|
|
if (u->lowActor && !TEST(u->lowActor->s().cstat, CSTAT_SPRITE_ALIGNMENT_FLOOR))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
//sp->ang = NORM_ANGLE(sp->ang + (RANDOM_P2(64<<8)>>8) - 32);
|
|
|
|
sp->ang = NORM_ANGLE(sp->ang + 1024 + (RANDOM_P2(512<<8)>>8));
|
|
|
|
u->jump_speed = -350;
|
|
|
|
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorBeginJump(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Change sprites state to running
|
|
|
|
if (u->ActorActionSet)
|
|
|
|
{
|
|
|
|
if (TEST(u->Flags, SPR_DEAD))
|
|
|
|
{
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->ActorActionSet->Dead);
|
2019-12-18 10:09:01 +00:00
|
|
|
PlaySound(DIGI_ACTORBODYFALL1, sp, v3df_none);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2019-12-18 10:09:01 +00:00
|
|
|
PlaySound(DIGI_ACTORHITGROUND, sp, v3df_none);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->ActorActionSet->Run);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
if ((u->track >= 0) && (u->jump_speed) > 800 && (u->ActorActionSet->Sit))
|
|
|
|
{
|
|
|
|
u->WaitTics = 80;
|
2021-10-30 21:12:31 +00:00
|
|
|
NewStateGroup(actor, u->ActorActionSet->Sit);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-29 20:42:09 +00:00
|
|
|
int DoActorDeathMove(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 18:49:57 +00:00
|
|
|
USER* u = actor->u();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
2021-10-29 20:42:09 +00:00
|
|
|
SPRITEp sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
int nx, ny;
|
|
|
|
|
|
|
|
if (TEST(u->Flags, SPR_JUMPING | SPR_FALLING))
|
|
|
|
{
|
|
|
|
if (TEST(u->Flags, SPR_JUMPING))
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorJump(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
else
|
2021-10-29 18:49:57 +00:00
|
|
|
DoActorFall(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
2021-01-04 11:36:54 +00:00
|
|
|
nx = MulScale(sp->xvel, bcos(sp->ang), 14);
|
|
|
|
ny = MulScale(sp->xvel, bsin(sp->ang), 14);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
sp->clipdist = (128+64)>>2;
|
2021-10-30 21:03:26 +00:00
|
|
|
move_actor(actor, nx, ny, 0);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// only fall on top of floor sprite or sector
|
2021-10-30 22:01:08 +00:00
|
|
|
DoFindGroundPoint(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// !AIC - Jumping a falling for shrapnel and other stuff, not actors.
|
|
|
|
|
2021-10-29 21:03:47 +00:00
|
|
|
int DoBeginJump(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 21:03:47 +00:00
|
|
|
USERp u = actor->u();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
SET(u->Flags, SPR_JUMPING);
|
|
|
|
RESET(u->Flags, SPR_FALLING);
|
|
|
|
|
|
|
|
// set up individual actor jump gravity
|
|
|
|
u->jump_grav = ACTOR_GRAVITY;
|
|
|
|
|
2021-10-29 21:38:21 +00:00
|
|
|
DoJump(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-29 21:38:21 +00:00
|
|
|
int DoJump(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 21:38:21 +00:00
|
|
|
USERp u = actor->u();
|
|
|
|
SPRITEp sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
int jump_adj;
|
|
|
|
|
|
|
|
// precalculate jump value to adjust jump speed by
|
|
|
|
jump_adj = u->jump_grav * ACTORMOVETICS;
|
|
|
|
|
|
|
|
// adjust jump speed by gravity - if jump speed greater than 0 player
|
|
|
|
// have started falling
|
|
|
|
if ((u->jump_speed += jump_adj) > 0)
|
|
|
|
{
|
|
|
|
// Start falling
|
2021-10-29 21:41:33 +00:00
|
|
|
DoBeginFall(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// adjust height by jump speed
|
|
|
|
sp->z += u->jump_speed * ACTORMOVETICS;
|
|
|
|
|
|
|
|
// if player gets to close the ceiling while jumping
|
2021-10-30 21:18:58 +00:00
|
|
|
if (sp->z < u->hiz + Z(PIC_SIZY(sp)))
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
|
|
|
// put player at the ceiling
|
2021-10-30 21:18:58 +00:00
|
|
|
sp->z = u->hiz + Z(PIC_SIZY(sp));
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// reverse your speed to falling
|
|
|
|
u->jump_speed = -u->jump_speed;
|
|
|
|
|
|
|
|
// Change sprites state to falling
|
2021-10-29 21:41:33 +00:00
|
|
|
DoBeginFall(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2021-10-29 21:41:33 +00:00
|
|
|
int DoBeginFall(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 21:41:33 +00:00
|
|
|
USERp u = actor->u();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
SET(u->Flags, SPR_FALLING);
|
|
|
|
RESET(u->Flags, SPR_JUMPING);
|
|
|
|
|
|
|
|
u->jump_grav = ACTOR_GRAVITY;
|
|
|
|
|
2021-10-29 21:41:33 +00:00
|
|
|
DoFall(actor);
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-10-29 21:41:33 +00:00
|
|
|
int DoFall(DSWActor* actor)
|
2015-05-19 21:54:34 +00:00
|
|
|
{
|
2021-10-29 21:41:33 +00:00
|
|
|
USERp u = actor->u();
|
|
|
|
SPRITEp sp = &actor->s();
|
2015-05-19 21:54:34 +00:00
|
|
|
|
|
|
|
// adjust jump speed by gravity
|
|
|
|
u->jump_speed += u->jump_grav * ACTORMOVETICS;
|
|
|
|
|
|
|
|
// adjust player height by jump speed
|
|
|
|
sp->z += u->jump_speed * ACTORMOVETICS;
|
|
|
|
|
|
|
|
// Stick like glue when you hit the ground
|
|
|
|
if (sp->z > u->loz - u->floor_dist)
|
|
|
|
{
|
|
|
|
sp->z = u->loz - u->floor_dist;
|
|
|
|
RESET(u->Flags, SPR_FALLING);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#include "saveable.h"
|
|
|
|
|
|
|
|
static saveable_code saveable_actor_code[] =
|
|
|
|
{
|
|
|
|
SAVE_CODE(DoActorDebris),
|
|
|
|
SAVE_CODE(DoFireFly),
|
|
|
|
SAVE_CODE(DoGenerateSewerDebris),
|
|
|
|
SAVE_CODE(DoActorDeathMove),
|
|
|
|
};
|
|
|
|
|
|
|
|
saveable_module saveable_actor =
|
|
|
|
{
|
|
|
|
// code
|
|
|
|
saveable_actor_code,
|
|
|
|
SIZ(saveable_actor_code),
|
|
|
|
|
|
|
|
// data
|
2021-07-10 12:25:18 +00:00
|
|
|
nullptr,0
|
2015-05-19 21:54:34 +00:00
|
|
|
};
|
2019-10-09 16:09:05 +00:00
|
|
|
|
|
|
|
END_SW_NS
|