8215 lines
210 KiB
C
8215 lines
210 KiB
C
// FIXME: copy-pasta of snake/sna_init.c
|
|
|
|
#include "sna_init.h"
|
|
|
|
#include <stdio.h>
|
|
#include <sys/types.h>
|
|
#include <libgte.h>
|
|
#include <libgpu.h>
|
|
|
|
#include "common.h"
|
|
#include "chara/snake/afterse.h"
|
|
#include "chara/snake/shadow.h"
|
|
#include "libgv/libgv.h"
|
|
#include "libdg/libdg.h"
|
|
#include "libgcl/libgcl.h"
|
|
#include "game/game.h"
|
|
#include "linkvar.h"
|
|
#include "okajima/blood.h"
|
|
#include "bullet/bakudan.h"
|
|
#include "game/vibrate.h"
|
|
#include "anime/animconv/anime.h"
|
|
#include "equip/equip.h"
|
|
#include "okajima/d_blood.h"
|
|
#include "takabe/goggle.h"
|
|
#include "takabe/goggleir.h"
|
|
#include "weapon/weapon.h"
|
|
#include "sd/g_sound.h"
|
|
#include "strcode.h"
|
|
|
|
int SECTION(".sbss") gSnaMoveDir_800ABBA4;
|
|
int SECTION(".sbss") dword_800ABBA8;
|
|
SVECTOR *SECTION(".sbss") dword_800ABBAC;
|
|
void *SECTION(".sbss") dword_800ABBB0;
|
|
char *SECTION(".sbss") dword_800ABBB4;
|
|
int SECTION(".sbss") sna_800ABBA0_pad;
|
|
HZD_FLR *SECTION(".sbss") flr_800ABBB8[2];
|
|
int SECTION(".sbss") dword_800ABBC0;
|
|
int SECTION(".sbss") dword_800ABBC4;
|
|
SVECTOR *SECTION(".sbss") pVec_800ABBC8;
|
|
SVECTOR *SECTION(".sbss") pVec_800ABBCC;
|
|
int SECTION(".sbss") dword_800ABBD0;
|
|
short SECTION(".sbss") dword_800ABBD4;
|
|
void *SECTION(".sbss") GM_BombSeg;
|
|
short SECTION(".sbss") dword_800ABBDC;
|
|
|
|
extern GM_CAMERA GM_Camera;
|
|
extern unsigned short GM_WeaponTypes[];
|
|
extern unsigned short GM_ItemTypes[];
|
|
extern void *dword_8009EEA4[];
|
|
extern int bakudan_count_8009F42C;
|
|
//extern int gSnaMoveDir_800ABBA4;
|
|
extern int counter_8009F448;
|
|
extern int tabako_dword_8009F2C0;
|
|
extern UnkCameraStruct gUnkCameraStruct_800B77B8;
|
|
extern CONTROL *tenage_ctrls_800BDD30[16];
|
|
extern HITTABLE GM_C4Datas_800BDD78[C4_COUNT];
|
|
extern HITTABLE GM_ClayDatas_800BDE78[8];
|
|
extern unsigned char gBulNames_800BDC78[64];
|
|
unsigned char gBulNames_800BDC78[64];
|
|
extern int dword_8009F440;
|
|
extern int dword_8009F444;
|
|
extern int dword_8009F46C[];
|
|
extern int dword_8009F470;
|
|
extern int dword_8009F474;
|
|
extern TARGET *target_800BDF00;
|
|
extern int dword_800BDD28;
|
|
extern int tenage_ctrls_count_800BDD70;
|
|
extern int dword_8009F434;
|
|
extern void *dword_8009EEB0[];
|
|
extern void *dword_8009EEB8[];
|
|
extern short HzdHeights_8009EEC4[];
|
|
extern int DG_CurrentGroupID;
|
|
extern char dword_8009EF1C[];
|
|
extern char dword_8009EF20[];
|
|
extern TSnakeEquipFuncion gSnakeEquips_8009EF8C[];
|
|
extern char dword_8009EEE0[];
|
|
extern char dword_8009EEE4[];
|
|
extern char dword_8009EEF0[];
|
|
extern char dword_8009EEF4[];
|
|
extern char dword_8009EED4[];
|
|
extern char dword_8009EED8[];
|
|
extern short snake_weapon_idx_800BDCBA;
|
|
extern short snake_mag_size_800BDCB8;
|
|
extern short snake_weapon_max_ammo_800BDCBC;
|
|
|
|
#define TARGET_FLAG ( TARGET_POWER | TARGET_CAPTURE | TARGET_PUSH | TARGET_TOUCH | TARGET_SEEK )
|
|
#define BODY_FLAG ( DG_FLAG_TEXT | DG_FLAG_TRANS | DG_FLAG_GBOUND | DG_FLAG_SHADE | DG_FLAG_AMBIENT | DG_FLAG_IRTEXTURE )
|
|
|
|
#define SEGMENT_ATR ( HZD_SEG_NO_COLLIDE )
|
|
|
|
ACTMOVE NoneMove = {12u, 82u, 19u, 23u, 24u, 29u, 30u, 12u, 0u, 0u};
|
|
ACTMOVE SocomMove = {10u, 8u, 17u, 23u, 24u, 27u, 28u, 80u, 106u, 107u};
|
|
ACTMOVE FamasMove = {11u, 9u, 18u, 23u, 24u, 27u, 28u, 73u, 110u, 111u};
|
|
ACTMOVE NikitaMove = {75u, 77u, 79u, 23u, 24u, 27u, 28u, 75u, 0u, 0u};
|
|
ACTMOVE C4Move = {92u, 91u, 93u, 23u, 24u, 29u, 30u, 92u, 0u, 0u};
|
|
ACTMOVE ClaymoreMove = {97u, 96u, 98u, 101u, 24u, 29u, 30u, 97u, 0u, 0u};
|
|
ACTMOVE GrenadeMove = {104u, 103u, 19u, 23u, 24u, 29u, 30u, 104u, 0u, 0u};
|
|
|
|
ACTDAMAGE NoneDamage = {63u, 65u, 67u, 68u, 69u, 70u, 71u, 72u, 66u, 123u, 130u, 131u};
|
|
ACTDAMAGE SocomDamage = {61u, 64u, 67u, 68u, 69u, 70u, 71u, 72u, 66u, 123u, 130u, 131u};
|
|
ACTDAMAGE FamasDamage = {62u, 83u, 67u, 68u, 69u, 70u, 71u, 72u, 66u, 123u, 130u, 131u};
|
|
|
|
ACTATTACK NoneAttack = {136u, 136u, 35u, 136u, 36u, 37u, 38u, 39u, 0u, 0u};
|
|
ACTATTACK SocomAttack = {42u, 51u, 35u, 45u, 47u, 0u, 0u, 0u, 0u, 0u};
|
|
ACTATTACK FamasAttack = {5u, 52u, 34u, 46u, 48u, 0u, 0u, 0u, 0u, 0u};
|
|
ACTATTACK StingerAttack = {74u, 136u, 136u, 136u, 105u, 0u, 0u, 0u, 0u, 0u};
|
|
ACTATTACK NikitaAttack = {74u, 136u, 34u, 46u, 81u, 0u, 0u, 0u, 0u, 0u};
|
|
ACTATTACK C4Attack = {43u, 136u, 35u, 136u, 53u, 55u, 49u, 54u, 56u, 0u};
|
|
ACTATTACK ClaymoreAttack = {57u, 136u, 35u, 136u, 58u, 59u, 0u, 0u, 0u, 0u};
|
|
ACTATTACK GrenadeAttack = {60u, 136u, 35u, 136u, 50u, 0u, 0u, 0u, 0u, 0u};
|
|
ACTATTACK PSG1Attack = {44u, 136u, 136u, 136u, 136u, 0u, 0u, 0u, 0u, 0u};
|
|
|
|
Sna_E6 e6_8009ED48[] = {
|
|
{115u, 133u, 0u, 0u},
|
|
{112u, 133u, 0u, 0u},
|
|
{113u, 133u, 0u, 0u},
|
|
{136u, 136u, 0u, 0u},
|
|
{114u, 132u, 0u, 0u},
|
|
{116u, 133u, 0u, 0u},
|
|
{117u, 133u, 0u, 0u},
|
|
{118u, 133u, 0u, 0u}
|
|
};
|
|
|
|
// TODO: Why is this in .data despite fitting into .sdata?
|
|
ACTSPECIAL SECTION(".data") e7_8009ED68 = {7u, 13u, 4u, 14u, 32u, 119u, 124u, 0u};
|
|
|
|
ACTSTILL NoneStill = {2u, 6u, 16u, 22u, 26u, 129u, 88u, 89u};
|
|
ACTSTILL SocomStill = {0u, 0u, 15u, 22u, 25u, 31u, 40u, 41u};
|
|
ACTSTILL FamasStill = {1u, 5u, 15u, 22u, 25u, 31u, 40u, 41u};
|
|
ACTSTILL GrenadeStill = {3u, 3u, 16u, 22u, 26u, 129u, 88u, 89u};
|
|
ACTSTILL C4Still = {90u, 90u, 16u, 22u, 43u, 53u, 88u, 89u};
|
|
ACTSTILL NikitaSill = {76u, 76u, 78u, 85u, 25u, 87u, 40u, 41u};
|
|
ACTSTILL ClaymoreStill = {95u, 95u, 99u, 100u, 26u, 102u, 88u, 89u};
|
|
|
|
ACTTRANS AllTrans = {20u, 21u, 84u };
|
|
|
|
unsigned short short_8009ED6C = 980;
|
|
|
|
ACTPACK actions_no_weapon_8009ED70 =
|
|
{
|
|
&NoneStill, &NoneMove, &AllTrans, &NoneDamage, &NoneAttack, &e6_8009ED48[0], &e7_8009ED68
|
|
};
|
|
|
|
ACTPACK weapon_actions_8009ED8C[10] =
|
|
{
|
|
{&SocomStill, &SocomMove, &AllTrans, &SocomDamage, &SocomAttack, &e6_8009ED48[1], &e7_8009ED68},
|
|
{&FamasStill, &FamasMove, &AllTrans, &FamasDamage, &FamasAttack, &e6_8009ED48[2], &e7_8009ED68},
|
|
{&GrenadeStill, &GrenadeMove, &AllTrans, &NoneDamage, &GrenadeAttack, &e6_8009ED48[7], &e7_8009ED68},
|
|
{&NikitaSill, &NikitaMove, &AllTrans, &FamasDamage, &NikitaAttack, &e6_8009ED48[4], &e7_8009ED68},
|
|
{&FamasStill, &FamasMove, &AllTrans, &FamasDamage, &StingerAttack, &e6_8009ED48[3], &e7_8009ED68},
|
|
{&ClaymoreStill, &ClaymoreMove, &AllTrans, &NoneDamage, &ClaymoreAttack, &e6_8009ED48[6], &e7_8009ED68},
|
|
{&C4Still, &C4Move, &AllTrans, &NoneDamage, &C4Attack, &e6_8009ED48[5], &e7_8009ED68},
|
|
{&GrenadeStill, &GrenadeMove, &AllTrans, &NoneDamage, &GrenadeAttack, &e6_8009ED48[7], &e7_8009ED68},
|
|
{&GrenadeStill, &GrenadeMove, &AllTrans, &NoneDamage, &GrenadeAttack, &e6_8009ED48[7], &e7_8009ED68},
|
|
{&NoneStill, NULL, &AllTrans, &NoneDamage, &PSG1Attack, &e6_8009ED48[3], &e7_8009ED68}
|
|
};
|
|
|
|
void *dword_8009EEA4[] = {
|
|
sna_anim_idle_8005275C,
|
|
sna_anim_crouch_800527DC,
|
|
sna_anim_prone_idle_800528BC
|
|
};
|
|
|
|
void *SECTION(".data") dword_8009EEB0[] = {
|
|
sna_anim_wall_idle_and_c4_80052A5C,
|
|
sna_anim_wall_crouch_80052CCC
|
|
};
|
|
|
|
void *dword_8009EEB8[] = {
|
|
sna_anim_run_8005292C,
|
|
sna_anim_run_8005292C,
|
|
sna_anim_prone_move_800529C0
|
|
};
|
|
|
|
short SECTION(".data") HzdHeights_8009EEC4[] = {750, 250, 250, 0};
|
|
|
|
short SECTION(".data") dword_8009EECC[] = {1100, 496, 136, 0};
|
|
|
|
char SECTION(".data") dword_8009EED4[] = {127, 4, 0, 0};
|
|
char SECTION(".data") dword_8009EED8[] = {225, 1, 255, 2, 0, 0, 0, 0};
|
|
char SECTION(".data") dword_8009EEE0[] = {127, 6, 0, 0};
|
|
char SECTION(".data") dword_8009EEE4[] = {225, 1, 255, 4, 225, 2, 75, 8, 0, 0, 0, 0};
|
|
char SECTION(".data") dword_8009EEF0[] = {127, 1, 0, 0};
|
|
char SECTION(".data") dword_8009EEF4[] = {155, 3, 0, 0};
|
|
char SECTION(".data") dword_8009EEF8[] = {0, 2, 127, 2, 0, 0, 0, 0};
|
|
char SECTION(".data") dword_8009EF00[] = {140, 4, 80, 6, 0, 0, 0, 0};
|
|
char SECTION(".data") dword_8009EF08[] = {0, 10, 127, 2, 0, 0, 0, 0};
|
|
char SECTION(".data") dword_8009EF10[] = {80, 2, 50, 8, 140, 4, 80, 6, 0, 0, 0, 0};
|
|
char SECTION(".data") dword_8009EF1C[] = {196, 4, 0, 0};
|
|
char SECTION(".data") dword_8009EF20[] = {148, 4, 0, 0};
|
|
char SECTION(".data") dword_8009EF24[] = {0, 2, 127, 2, 0, 0, 0, 0};
|
|
char SECTION(".data") dword_8009EF2C[] = {60, 2, 200, 4, 40, 2, 0, 0};
|
|
|
|
typedef struct WeaponCreateEntry
|
|
{
|
|
void *mCreateActorFn;
|
|
void *mStateFn;
|
|
} WeaponCreateEntry;
|
|
|
|
WeaponCreateEntry gSnakeWeapons_8009EF3C[] = {
|
|
{NULL, sna_anim_chokethrow_begin1_80054210},
|
|
{NewSOCOM, sna_gun_800540D0},
|
|
{NewFAMAS, sna_gun_800540D0},
|
|
{NewGrenade, sna_anim_grenade_80058470},
|
|
{NewRCM, sna_gun_800540D0},
|
|
{NewAAM, sna_anim_stinger_800570C0},
|
|
{NewMine, sna_anim_claymore_80057474},
|
|
{NewBomb, sna_bomb_800541A8},
|
|
{NewStanGrenade, sna_anim_grenade_80058470},
|
|
{NewChaffGrenade, sna_anim_grenade_80058470},
|
|
{NewRifle, sna_anim_psg1_80056DDC}};
|
|
|
|
TSnakeEquipFuncion gSnakeEquips_8009EF8C[] = {
|
|
NewTabako, // 0
|
|
NewScope, // 1
|
|
NewBox, // 2
|
|
NewBox, // 3
|
|
NewBox, // 4
|
|
NewGoggle, // 5
|
|
NewGoggleIr, // 6
|
|
NewGasMask, // 7
|
|
NewBodyArmor, // 8
|
|
NewKetchap, // 9
|
|
NewKogaku2, // 10
|
|
NewBandana, // 11
|
|
NULL, // 12
|
|
};
|
|
|
|
short word_8009EFC0[] = {0, 500, 0, 320, 400, 320, 400, 32, 32, 0};
|
|
|
|
SVECTOR stru_8009EFD4[2] = {{-100, 200, 200, 0}, {-150, 18, 200, 0}};
|
|
|
|
Target_Data stru_8009EFE4[4] =
|
|
{
|
|
{{0, 0, 300, 0}, {400, 600, 400, 0}, 0, 0, 64, 0}, // TODO: Might not be part of this array, might be its own element
|
|
{{-400, 0, 600, 0}, {400, 600, 400, 0}, 0, 0, 36, 5},
|
|
{{400, 0, 600, 0}, {400, 600, 400, 0}, 0, 0, 36, 5},
|
|
{{0, 0, 0, 0}, {501, 600, 501, 0}, 0, 0, 7, 0}
|
|
};
|
|
|
|
typedef struct _PUNCH
|
|
{
|
|
SVECTOR field_0;
|
|
SVECTOR size;
|
|
SVECTOR field_10;
|
|
int life;
|
|
int faint;
|
|
} PUNCH;
|
|
|
|
PUNCH punch_info[] =
|
|
{
|
|
{{-200, 200, 600}, {400, 200, 400}, {5, 0, 50}, 0, 1},
|
|
{ {200, 200, 600}, {400, 200, 400}, {-5, 0, 50}, 0, 1},
|
|
{{0, 200, 600}, {500, 250, 500}, {0, 0, 100}, 0, 3}
|
|
};
|
|
|
|
GV_PAD GV_PadData_8009F0C4 = {0, 0, 0, 0, -1, 0, 0, 0, 0, 0};
|
|
|
|
int snainit_item_800A9420 = -1;
|
|
SnaInitWork *snainit_actor_800A9424 = NULL;
|
|
|
|
SVECTOR svector_800AB7CC = {150, 0, 50, 0};
|
|
SVECTOR svector_800AB7D4 = {0, 0, 100, 0};
|
|
SVECTOR svector_800AB7DC = {-1024, 0, 0, 0};
|
|
SVECTOR svector_800AB7E4 = {5, 500, 80, 0};
|
|
SVECTOR svector_800AB7EC = {0, 0, 800, 0};
|
|
SVECTOR svector_800AB7F4 = {0, 100, -300, 0};
|
|
SVECTOR svector_800AB7FC = {0, 0, -300, 0};
|
|
|
|
#define RIFLE_TEBURE_TIME 90 // delay before camera shake
|
|
#define TEBURE 122
|
|
#define GetAction( work ) (work->body.action)
|
|
#define EndMotion( work ) (work->body.is_end != 0)
|
|
#define SET work->actpack->attack->aim
|
|
#define DispEmpty( work ) (work->field_9A0 = 4)
|
|
|
|
void sub_8004EB74(SnaInitWork *work)
|
|
{
|
|
if (GM_Camera.first_person == 0)
|
|
{
|
|
if (work->field_9B0_pad_ptr->dir == (short)-1)
|
|
{
|
|
work->field_A20 = -6;
|
|
}
|
|
else
|
|
{
|
|
work->field_A20 = -3;
|
|
}
|
|
}
|
|
|
|
GM_Camera.first_person = 1;
|
|
work->field_A56 = 0;
|
|
GM_SetPlayerStatusFlag(PLAYER_MENU_DISABLE | PLAYER_WATCH);
|
|
|
|
if (!(work->field_920_tbl & 0x200))
|
|
{
|
|
sd_set_cli(0x01ffff20, SD_ASYNC);
|
|
}
|
|
}
|
|
|
|
void sna_8004EC00(SnaInitWork *work)
|
|
{
|
|
if (GM_Camera.first_person == 1)
|
|
{
|
|
work->field_A20 = 6;
|
|
}
|
|
|
|
GM_Camera.first_person = 0;
|
|
work->field_A56 = 0;
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_NORMAL_WATCH | PLAYER_WATCH);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK16);
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
sd_set_cli(0x01ffff21, SD_ASYNC);
|
|
}
|
|
}
|
|
|
|
void sna_8004EC8C(SnaInitWork *work)
|
|
{
|
|
u_short v2; // $v1
|
|
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK12);
|
|
work->field_A28 = 460;
|
|
GM_Camera.first_person = 1;
|
|
v2 = short_8009ED6C;
|
|
work->field_A20 = -6;
|
|
work->field_9D0[2] = 320;
|
|
work->field_9D0[4] = v2;
|
|
work->field_9D0[6] = v2;
|
|
sd_set_cli(0x01ffff20, SD_ASYNC);
|
|
}
|
|
|
|
void sub_8004ED08(SnaInitWork *work)
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK12);
|
|
work->field_A28 = 0x1c2;
|
|
GM_Camera.first_person = 0; // weapon related?
|
|
work->field_A20 = 6;
|
|
sna_8004EB14(work);
|
|
sd_set_cli(0x01ffff21, SD_ASYNC);
|
|
}
|
|
|
|
void sna_act_helper2_helper3_8004ED6C(SnaInitWork *work)
|
|
{
|
|
if (work->field_A20 != 0)
|
|
{
|
|
if (work->field_A20 >= 1)
|
|
{
|
|
|
|
if ((GM_Camera.first_person == 0) && (--work->field_A20 == 0))
|
|
{
|
|
DG_VisibleObjs(work->body.objs);
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_ACT_ONLY))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE);
|
|
}
|
|
}
|
|
}
|
|
else if ((GM_Camera.first_person != 0) && (++work->field_A20 == 0))
|
|
{
|
|
DG_InvisibleObjs(work->body.objs);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_8004EE28(SnaInitWork *snake)
|
|
{
|
|
MATRIX mat1;
|
|
MATRIX mat2;
|
|
SVECTOR vec;
|
|
int vx;
|
|
MATRIX *world = &snake->body.objs->objs[6].world;
|
|
|
|
ReadRotMatrix(&mat1);
|
|
DG_TransposeMatrix(&mat1, &mat2);
|
|
MulMatrix0(&mat2, world, &mat2);
|
|
DG_MatrixRotZYX(&mat2, &vec);
|
|
SetRotMatrix(&mat1);
|
|
|
|
vx = (vec.vx / 16) * 16;
|
|
gUnkCameraStruct_800B77B8.rotate2.vx = vx;
|
|
}
|
|
|
|
void sub_8004EEB0(SnaInitWork *work)
|
|
{
|
|
short sVar1;
|
|
int iVar2;
|
|
int arg0;
|
|
|
|
if (gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
arg0 = work->control.turn.vy;
|
|
if (GV_DiffDirS(arg0, gSnaMoveDir_800ABBA4))
|
|
{
|
|
iVar2 = GV_NearPhase(arg0, gSnaMoveDir_800ABBA4);
|
|
sVar1 = GV_NearSpeed(iVar2, gSnaMoveDir_800ABBA4, 0x40);
|
|
work->control.turn.vy = sVar1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_8004EF14(SnaInitWork *work)
|
|
{
|
|
int actionFlag;
|
|
int diff;
|
|
int y;
|
|
|
|
y = work->control.turn.vy;
|
|
|
|
diff = GV_DiffDirS(y, gSnaMoveDir_800ABBA4);
|
|
if (diff == 0)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
y = work->actpack->still->setup;
|
|
SetAction_8004E22C(work, y, 4);
|
|
}
|
|
else
|
|
{
|
|
short sVar2;
|
|
int iVar4;
|
|
|
|
if (diff < 0)
|
|
{
|
|
actionFlag = work->actpack->move->aim_stance_l;
|
|
}
|
|
else
|
|
{
|
|
actionFlag = work->actpack->move->aim_stance_r;
|
|
}
|
|
|
|
SetAction_8004E22C(work, actionFlag, 4);
|
|
iVar4 = GV_NearPhase(y, gSnaMoveDir_800ABBA4);
|
|
sVar2 = GV_NearSpeed(iVar4, gSnaMoveDir_800ABBA4, 0x40);
|
|
work->control.turn.vy = sVar2;
|
|
}
|
|
}
|
|
|
|
int sub_8004EFE4(SnaInitWork *work, int set)
|
|
{
|
|
MOTION_INFO *info;
|
|
int action;
|
|
|
|
if (set == 1)
|
|
{
|
|
info = &work->m_ctrl.info1;
|
|
}
|
|
else
|
|
{
|
|
info = &work->m_ctrl.info2;
|
|
}
|
|
|
|
if (set == 1)
|
|
{
|
|
action = GetAction(work);
|
|
}
|
|
else
|
|
{
|
|
action = work->body.action2;
|
|
}
|
|
|
|
if (info->frames_left + info->frame == 1)
|
|
{
|
|
return action;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void sna_8004F034(SnaInitWork *work, unsigned int bits)
|
|
{
|
|
if ( bits != work->m_ctrl.info1.mask )
|
|
{
|
|
work->m_ctrl.info2.mask = ~bits;
|
|
work->m_ctrl.info1.mask = bits;
|
|
if ( bits == 0xFFFF && sub_8004EFE4(work, 2) >= 0 )
|
|
{
|
|
work->m_ctrl.interp = 4;
|
|
work->m_ctrl.info2.field_14 = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_act_helper2_helper4_8004F090(SnaInitWork *work, int param_2)
|
|
{
|
|
int iVar1;
|
|
MATRIX mtx;
|
|
|
|
DG_SetPos(&work->body.objs->objs[6].world);
|
|
DG_MovePos(&svector_800AB7D4);
|
|
DG_RotatePos(&svector_800AB7DC);
|
|
ReadRotMatrix(&mtx);
|
|
|
|
iVar1 = -1;
|
|
switch (param_2)
|
|
{
|
|
case 3:
|
|
iVar1 = 0;
|
|
break;
|
|
case 1:
|
|
case 4:
|
|
iVar1 = 1;
|
|
break;
|
|
case 2:
|
|
iVar1 = 2;
|
|
break;
|
|
}
|
|
|
|
if (iVar1 >= 0)
|
|
{
|
|
NewBlood(&mtx, iVar1);
|
|
}
|
|
}
|
|
|
|
void sub_8004F14C(SnaInitWork *work)
|
|
{
|
|
work->field_91C_weapon_idx = WP_None;
|
|
GM_CurrentWeaponId = WP_None;
|
|
|
|
if (work->field_908_weapon_actor != 0)
|
|
{
|
|
GV_DestroyActorQuick(work->field_908_weapon_actor);
|
|
}
|
|
|
|
work->field_908_weapon_actor = 0;
|
|
work->field_920_tbl = GM_WeaponTypes[0];
|
|
work->field_918_n_bullets = 0;
|
|
work->actpack = &actions_no_weapon_8009ED70;
|
|
work->field_90C_pWeaponFn = &sna_anim_chokethrow_begin1_80054210;
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) != 0)
|
|
{
|
|
work->field_A56 = 0;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE |
|
|
PLAYER_NORMAL_WATCH | PLAYER_WATCH);
|
|
}
|
|
else
|
|
{
|
|
sna_8004EC00(work);
|
|
}
|
|
}
|
|
|
|
void sub_8004F204(SnaInitWork *work)
|
|
{
|
|
if (work->field_9A4_item_actor != 0)
|
|
{
|
|
GV_DestroyActorQuick(work->field_9A4_item_actor);
|
|
}
|
|
|
|
work->field_9A4_item_actor = 0;
|
|
work->field_9A8_current_item = IT_None;
|
|
GM_CurrentItemId = IT_None;
|
|
work->field_9AC = GM_ItemTypes[0];
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) != 0)
|
|
{
|
|
work->field_A56 = 0;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE |
|
|
PLAYER_NORMAL_WATCH | PLAYER_WATCH);
|
|
}
|
|
else
|
|
{
|
|
sna_8004EC00(work);
|
|
}
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_CB_BOX);
|
|
}
|
|
|
|
void sna_set_invuln_8004F2A0(SnaInitWork *work, char invuln_frames)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_INVINCIBLE);
|
|
work->field_A24_invuln_frames = invuln_frames;
|
|
work->field_89C_pTarget->class &= ~0x96;
|
|
}
|
|
|
|
void sna_clear_invuln_8004F2EC(SnaInitWork *work)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_INVINCIBLE);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK1);
|
|
work->field_89C_pTarget->class |= TARGET_FLAG;
|
|
}
|
|
|
|
void sub_8004F338(SnaInitWork *work)
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
work->field_A56 = 0;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE
|
|
| PLAYER_NORMAL_WATCH
|
|
| PLAYER_WATCH);
|
|
}
|
|
else
|
|
{
|
|
sna_8004EC00(work);
|
|
}
|
|
|
|
sna_clear_invuln_8004F2EC(work);
|
|
work->field_A24_invuln_frames = 0;
|
|
sna_sub_8004E41C(work, 2);
|
|
GM_ConfigMotionAdjust(&work->body, 0);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK9);
|
|
work->field_9C0 = 0;
|
|
sna_8004E260(work, 0, 4, 0);
|
|
DG_InvisiblePrim(work->field_92C);
|
|
|
|
GM_ExitBehindCamera();
|
|
|
|
GM_PlayerStatus &= PLAYER_SECOND_AVAILABLE | PLAYER_NOT_SIGHT |
|
|
PLAYER_GAME_OVER | PLAYER_CB_BOX | PLAYER_INTRUDE |
|
|
PLAYER_ACT_ONLY | PLAYER_SQUAT | PLAYER_GROUND;
|
|
|
|
if ((work->field_920_tbl & 0x200) != 0)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_WATCH);
|
|
}
|
|
|
|
work->field_A28 = 0x1c2;
|
|
work->field_894_flags1 &= (SNA_FLAG1_UNK20 | SNA_FLAG1_UNK28 | SNA_FLAG1_UNK29);
|
|
work->control.skip_flag &= ~CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
void sub_8004F454(SnaInitWork *work)
|
|
{
|
|
int i;
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE | PLAYER_ATTACK | PLAYER_CHECK_WALL);
|
|
GM_ConfigMotionAdjust(&work->body, NULL);
|
|
|
|
for (i = 0; i < SNAKEJOINT_NUM; i++)
|
|
{
|
|
work->adjust[i] = DG_ZeroVector;
|
|
}
|
|
|
|
sna_8004E260(work, 0, 4, 0);
|
|
sna_sub_8004E41C(work, 2);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK2 | SNA_FLAG1_UNK3 | SNA_FLAG1_UNK26);
|
|
DG_InvisiblePrim(work->field_92C);
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_CAUTION) == 0)
|
|
{
|
|
work->field_A28 = 450;
|
|
GM_ExitBehindCamera();
|
|
}
|
|
|
|
work->control.skip_flag &= ~CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
int sna_8004F544(SnaInitWork *work, SVECTOR param_2, int a3, int a4, int a5)
|
|
{
|
|
MATRIX mtx;
|
|
SVECTOR vec1;
|
|
SVECTOR vec2;
|
|
SVECTOR vec3;
|
|
|
|
int bVar1;
|
|
int iVar2;
|
|
|
|
vec1 = param_2;
|
|
|
|
vec3.vy = 0;
|
|
vec3.vx = 0;
|
|
vec3.vz = a3;
|
|
|
|
ReadRotMatrix(&mtx);
|
|
DG_SetPos2(¶m_2, &work->control.turn);
|
|
DG_PutVector(&vec3, &vec2, 1);
|
|
DG_SetPos(&mtx);
|
|
|
|
iVar2 = sna_line_check(&vec1, work->control.map->hzd, a4, a5);
|
|
|
|
bVar1 = a3 < iVar2;
|
|
|
|
if (a3 < 0)
|
|
{
|
|
a3 = -a3;
|
|
bVar1 = a3 < iVar2;
|
|
}
|
|
|
|
if (bVar1)
|
|
{
|
|
iVar2 = -1;
|
|
}
|
|
|
|
return iVar2;
|
|
}
|
|
|
|
int sna_8004F628(SnaInitWork *work, SVECTOR *param_2, int param_3, int param_4, int param_5, int param_6)
|
|
{
|
|
SVECTOR vec;
|
|
|
|
DG_SetPos2(&work->control.mov, &work->control.rot);
|
|
DG_PutVector(param_2, &vec, 1);
|
|
|
|
if (param_6 >= 1)
|
|
{
|
|
vec.vy = work->control.levels[0] + param_6;
|
|
}
|
|
|
|
return sna_8004F544(work, vec, param_3, param_4, param_5) >= 0;
|
|
}
|
|
|
|
static inline int sna_update_life_helper_8004F6E8(int health, int item)
|
|
{
|
|
int temp;
|
|
|
|
if ((health == 0) &&
|
|
(GM_GameOverTimer == 0) &&
|
|
(item == IT_Ration) &&
|
|
(GM_Items[IT_Ration] > 0) &&
|
|
!GM_FrozenItemsState)
|
|
{
|
|
temp = (GM_DifficultyFlag > DIFFICULTY_EASY) ? 256 : 384;
|
|
|
|
if (GM_DifficultyFlag < DIFFICULTY_EASY)
|
|
{
|
|
temp = GM_SnakeMaxHealth;
|
|
}
|
|
|
|
health = temp;
|
|
|
|
if (health > GM_SnakeMaxHealth)
|
|
{
|
|
health = GM_SnakeMaxHealth;
|
|
}
|
|
|
|
GM_Items[IT_Ration] -= 1;
|
|
|
|
if (GM_Items[IT_Ration] == 0)
|
|
{
|
|
GM_CurrentItemId = IT_None;
|
|
}
|
|
|
|
GM_TotalRationsUsed += 1;
|
|
GM_SeSet2(0, 63, SE_RECOVER_LIFE);
|
|
}
|
|
|
|
return health;
|
|
}
|
|
|
|
void UpdateLife_8004F6E8(SnaInitWork *work)
|
|
{
|
|
TARGET *target;
|
|
int health;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_ACT_ONLY))
|
|
{
|
|
target = work->field_89C_pTarget;
|
|
|
|
if (target->life_lost > 0)
|
|
{
|
|
target->life += target->life_lost;
|
|
|
|
sna_act_unk2_80051170(work->field_89C_pTarget);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK25);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK23))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (sna_check_flags1_8004E31C(work,SNA_FLAG1_UNK25) &&
|
|
(GM_SnakeCurrentHealth == work->field_89C_pTarget->life))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ((work->field_9A8_current_item == IT_BodyArmor) && (work->field_89C_pTarget->a_mode == 1))
|
|
{
|
|
work->field_89C_pTarget->life_lost /= 2;
|
|
work->field_89C_pTarget->life += work->field_89C_pTarget->life_lost;
|
|
work->field_89C_pTarget->life_lost = 0;
|
|
}
|
|
|
|
health = work->field_89C_pTarget->life + GM_SnakeCurrentHealth - work->field_A22_snake_current_health;
|
|
|
|
if (health > GM_SnakeMaxHealth)
|
|
{
|
|
health = GM_SnakeMaxHealth;
|
|
}
|
|
|
|
if (health < 0)
|
|
{
|
|
health = 0;
|
|
}
|
|
|
|
if (work->field_89C_pTarget->weapon != WP_Max)
|
|
{
|
|
health = sna_update_life_helper_8004F6E8(health, work->field_9A8_current_item);
|
|
}
|
|
else
|
|
{
|
|
health = 0;
|
|
}
|
|
|
|
work->field_89C_pTarget->life = health;
|
|
work->field_A22_snake_current_health = health;
|
|
GM_SnakeCurrentHealth = health;
|
|
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK25);
|
|
}
|
|
|
|
void sna_8004F8E4(SnaInitWork *work, int a2)
|
|
{
|
|
GV_MSG msg;
|
|
|
|
if ((GM_GameOverTimer == -1) || (GM_GameOverTimer == 0))
|
|
{
|
|
// スネーク
|
|
msg.address = GV_StrCode("スネーク");
|
|
msg.message_len = 6;
|
|
msg.message[0] = HASH_GO_MOTION;
|
|
msg.message[1] = a2;
|
|
msg.message[2] = -1;
|
|
msg.message[3] = -1;
|
|
msg.message[4] = 2;
|
|
msg.message[5] = 2042;
|
|
|
|
work->field_7A4_msgs[work->field_7A0_msg_count] = msg;
|
|
work->field_7A0_msg_count++;
|
|
|
|
GM_GameOverTimer = 0;
|
|
GM_GameOver();
|
|
|
|
GM_GameStatus |= STATE_PADRELEASE;
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK20);
|
|
|
|
if (work->field_A70 >= 0)
|
|
{
|
|
GCL_ForceExecProc(work->field_A70, NULL);
|
|
}
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_CB_BOX))
|
|
{
|
|
sub_8004F204(work);
|
|
}
|
|
}
|
|
}
|
|
|
|
int sna_act_unk_helper4_8004FA3C(void)
|
|
{
|
|
if (GM_SnakeCurrentHealth == 0 || GM_GameOverTimer != 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sna_current_item_8004FB38(void)
|
|
{
|
|
if (snainit_actor_800A9424)
|
|
{
|
|
return snainit_actor_800A9424->field_9A8_current_item;
|
|
}
|
|
|
|
return snainit_item_800A9420;
|
|
}
|
|
|
|
int sna_ration_available_8004FB4C(void)
|
|
{
|
|
if ((snainit_actor_800A9424->field_9A8_current_item == IT_Ration) &&
|
|
(GM_Items[IT_Ration] > 0) &&
|
|
(GM_FrozenItemsState == 0))
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
HZD_FLR ** sub_8004FB90(void)
|
|
{
|
|
return flr_800ABBB8;
|
|
}
|
|
|
|
int GM_Next_BulName_8004FBA0()
|
|
{
|
|
int i; // $a0
|
|
for (i = 1; i < 64; i++) // for some reason skip the first one ??
|
|
{
|
|
if (!gBulNames_800BDC78[i])
|
|
{
|
|
gBulNames_800BDC78[i] = 1;
|
|
return i;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void GM_ClearBulName(int idx)
|
|
{
|
|
gBulNames_800BDC78[idx] = 0;
|
|
}
|
|
|
|
void GM_CheckShukanReverse(unsigned short *pInput)
|
|
{
|
|
unsigned short old;
|
|
unsigned int v2; // $v1
|
|
unsigned int v3; // $v0
|
|
|
|
if ((GM_OptionFlag & OPTION_SHUKAN_REVERSE) != 0)
|
|
{
|
|
old = *pInput;
|
|
|
|
*pInput = old & ~0x5000;
|
|
|
|
v2 = old & 0x5000;
|
|
v3 = v2 & 0x1000;
|
|
|
|
if (v3)
|
|
{
|
|
*pInput |= 0x4000;
|
|
}
|
|
|
|
if (v2 & 0x4000)
|
|
{
|
|
*pInput |= 0x1000;
|
|
}
|
|
}
|
|
}
|
|
|
|
void GM_CheckShukanReverseAnalog(unsigned char *pInput)
|
|
{
|
|
if ((GM_OptionFlag & OPTION_SHUKAN_REVERSE) != 0)
|
|
{
|
|
*pInput = ~*pInput;
|
|
}
|
|
}
|
|
|
|
int sub_8004FCB8(SnaInitWork *work, PUNCH *punch, int a_mode)
|
|
{
|
|
TARGET *target;
|
|
SVECTOR vec;
|
|
SVECTOR line[2];
|
|
|
|
target = &work->field_8A0_target;
|
|
GM_SetTarget(target, 4, PLAYER_SIDE, &punch->size);
|
|
DG_RotVector(&punch->field_10, &vec, 1);
|
|
GM_Target_8002DCCC(target, 3, a_mode, punch->life, punch->faint, &vec);
|
|
DG_PutVector(&punch->field_0, &vec, 1);
|
|
|
|
line[0].vx = work->body.objs->objs[5].world.t[0];
|
|
line[0].vy = work->body.objs->objs[5].world.t[1];
|
|
line[0].vz = work->body.objs->objs[5].world.t[2];
|
|
line[1] = vec;
|
|
|
|
if ( sna_line_check(line, work->control.map->hzd, HZD_CHECK_ALL, SEGMENT_ATR) < 0 )
|
|
{
|
|
GM_MoveTarget(target, &vec);
|
|
return GM_PowerTarget(target);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sna_8004FDE8(SnaInitWork *work, Target_Data *pTargetData)
|
|
{
|
|
int flags = 0x2;
|
|
TARGET *pTarget;
|
|
SVECTOR vec;
|
|
SVECTOR vecs[2];
|
|
|
|
if (pTargetData->field_18 == 0x40)
|
|
{
|
|
flags = 0x40;
|
|
}
|
|
|
|
GM_SetTarget(&work->field_8A0_target, flags, PLAYER_SIDE, &pTargetData->field_8_size);
|
|
GM_Target_8002DCB4(&work->field_8A0_target, pTargetData->field_18, pTargetData->field_1C, &work->field_8F4, &work->field_8FC);
|
|
DG_PutVector(&pTargetData->field_0, &vec, 1);
|
|
GM_MoveTarget(&work->field_8A0_target, &vec);
|
|
|
|
work->field_8E8_pTarget = NULL;
|
|
|
|
if (flags == 2)
|
|
{
|
|
pTarget = GM_CaptureTarget(&work->field_8A0_target);
|
|
}
|
|
else
|
|
{
|
|
pTarget = GM_C4Target(&work->field_8A0_target);
|
|
}
|
|
|
|
if (pTarget)
|
|
{
|
|
if (pTarget->class & 0x20)
|
|
{
|
|
pTarget->damaged &= ~flags;
|
|
pTarget->faint += pTargetData->field_1C;
|
|
return 0;
|
|
}
|
|
|
|
vecs[0] = work->control.mov;
|
|
vecs[1] = pTarget->center;
|
|
|
|
if (sna_line_check(vecs, work->control.map->hzd, HZD_CHECK_ALL, SEGMENT_ATR) < 0)
|
|
{
|
|
work->field_8E8_pTarget = pTarget;
|
|
return 1;
|
|
}
|
|
|
|
pTarget->damaged &= ~flags;
|
|
pTarget->faint += pTargetData->field_1C;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sna_act_helper2_helper5_8004FF88(SnaInitWork *work)
|
|
{
|
|
void *pAnim;
|
|
|
|
if (!(GM_GameStatus & (STATE_PADRELEASE | STATE_PADDEMO | STATE_DEMO)) && (GM_AlertMode != 3))
|
|
{
|
|
if (!GM_CheckPlayerStatusFlag(0x20001304) &&
|
|
!sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK9) &&
|
|
(GM_SnakeCurrentHealth != 0) &&
|
|
(GM_GameOverTimer == 0) &&
|
|
(GM_StreamStatus() == -1) &&
|
|
(work->body.action2 == 0))
|
|
{
|
|
pAnim = work->field_9B8_fn_anim;
|
|
|
|
if ((pAnim == sna_anim_idle_8005275C) ||
|
|
(pAnim == sna_anim_crouch_800527DC) ||
|
|
(pAnim == sna_anim_prone_idle_800528BC) ||
|
|
(pAnim == sna_anim_wall_idle_and_c4_80052A5C) ||
|
|
(pAnim == sna_anim_wall_crouch_80052CCC) ||
|
|
(pAnim == sna_anim_duct_move_80054424))
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sna_8005009C(SnaInitWork *work)
|
|
{
|
|
GV_PAD *pPad = work->field_9B0_pad_ptr;
|
|
int tbl = work->field_920_tbl;
|
|
unsigned short press = pPad->press;
|
|
unsigned short input = press;
|
|
void *pAnimFn;
|
|
|
|
if (!(tbl & 0x100))
|
|
{
|
|
input = pPad->status;
|
|
}
|
|
|
|
if (input & PAD_SQUARE)
|
|
{
|
|
work->field_910 = 0;
|
|
|
|
if (tbl & 0x10)
|
|
{
|
|
sna_start_anim_8004E1F4(work, work->field_90C_pWeaponFn);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK3);
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
return 1;
|
|
}
|
|
|
|
if (tbl & 8)
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_MOVE))
|
|
{
|
|
pAnimFn = sna_anim_rungun_80056C3C;
|
|
}
|
|
else
|
|
{
|
|
pAnimFn = sna_anim_shoot_weapon_80056B88;
|
|
}
|
|
|
|
sna_start_anim_8004E1F4(work, pAnimFn);
|
|
GM_SetPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_ITEM_DISABLE);
|
|
}
|
|
else
|
|
{
|
|
if ((input & PAD_CROSS) && (work->field_9B0_pad_ptr->dir >= 0))
|
|
{
|
|
pAnimFn = sna_anim_rungun_80056C3C;
|
|
}
|
|
else
|
|
{
|
|
pAnimFn = sna_anim_shoot_weapon_80056B88;
|
|
}
|
|
|
|
sna_start_anim_8004E1F4(work, pAnimFn);
|
|
}
|
|
|
|
GM_SetPlayerStatusFlag(PLAYER_ATTACK);
|
|
return 1;
|
|
}
|
|
|
|
if ((press & PAD_CIRCLE) && ((work->actpack->attack->punch ^ 0x88) != 0))
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_punch_80058C10);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK3);
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void sna_check_knock_800501F8(SnaInitWork *work, int time)
|
|
{
|
|
void *func;
|
|
|
|
if (time >= 8)
|
|
{
|
|
if (work->field_91C_weapon_idx != WP_C4 || GM_CheckPlayerStatusFlag(PLAYER_MOVE) != 0)
|
|
{
|
|
if ((work->field_9B0_pad_ptr->press & PAD_CIRCLE) != 0)
|
|
{
|
|
func = sna_knock_80054D68;
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK9);
|
|
work->field_9C0 = func;
|
|
work->field_9C4 = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_8005027C(SnaInitWork *work, int time)
|
|
{
|
|
SVECTOR *pVec;
|
|
|
|
if (work->field_91C_weapon_idx != WP_C4)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_MOVE))
|
|
{
|
|
work->control.turn.vy = dword_800ABBD0;
|
|
}
|
|
|
|
if ((time < 8) || !(work->field_9B0_pad_ptr->press & PAD_SQUARE) || (work->field_9C0 == sna_80057378))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ((*work->field_918_n_bullets != 0) && (bakudan_count_8009F42C < 16))
|
|
{
|
|
pVec = &stru_8009EFD4[0];
|
|
|
|
if (work->field_A26_stance != SNA_STANCE_STANDING)
|
|
{
|
|
pVec = &stru_8009EFD4[1];
|
|
}
|
|
|
|
if (sna_8004F628(work, pVec, 300, HZD_CHECK_DYNSEG | HZD_CHECK_SEG, SEGMENT_ATR | HZD_SEG_NO_BEHIND | HZD_SEG_NO_HARITSUKI, -1) > 0)
|
|
{
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK9);
|
|
work->field_9C0 = sna_80057378;
|
|
work->field_9C4 = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
GM_SeSet2(0, 63, SE_BUZZER);
|
|
}
|
|
|
|
int sna_prone_check_standup_80050398(SnaInitWork *work)
|
|
{
|
|
if ((work->field_9B0_pad_ptr->press & PAD_CROSS) != 0 && !sna_8004E808(work, 1, 0, -622, 1500))
|
|
{
|
|
work->field_A28 = 450;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, sna_anim_prone_standup_80053D74);
|
|
SetAction_8004E22C(work, work->actpack->trans->stand, 4);
|
|
work->control.turn.vy = work->control.rot.vy;
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void sna_80050440(SnaInitWork *work)
|
|
{
|
|
CONTROL *pCtrl;
|
|
unsigned short *pArr;
|
|
int inDuct;
|
|
int i;
|
|
|
|
// TODO: There is probably a better way to match this...
|
|
SnaInitWork *work2;
|
|
int a;
|
|
|
|
if ((GM_GameOverTimer == 0) && (GM_SnakeCurrentHealth != 0))
|
|
{
|
|
pCtrl = &work->control;
|
|
pArr = pCtrl->event.triggers;
|
|
|
|
inDuct = GM_CheckPlayerStatusFlag(PLAYER_INTRUDE);
|
|
GM_ClearPlayerStatusFlag(PLAYER_INTRUDE);
|
|
|
|
for (i = pCtrl->event.n_triggers; i > 0; pArr++, i--)
|
|
{
|
|
if (*pArr == 0x73D2)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_INTRUDE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!inDuct)
|
|
{
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
return;
|
|
}
|
|
|
|
sna_8004EC8C(work);
|
|
// TODO: There is probably a better way to match this...
|
|
work2 = work;
|
|
a = 4;
|
|
dword_800ABA1C = 0x100;
|
|
}
|
|
else
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
return;
|
|
}
|
|
|
|
sub_8004ED08(work);
|
|
// TODO: There is probably a better way to match this...
|
|
work2 = work;
|
|
a = 4;
|
|
dword_800ABA1C = 0;
|
|
}
|
|
|
|
sna_set_flags1_8004E2F4(work2, a);
|
|
|
|
work->control.turn.vy = work->control.rot.vy;
|
|
}
|
|
}
|
|
|
|
void sna_80050568(SnaInitWork *work)
|
|
{
|
|
SVECTOR diff;
|
|
DG_OBJS *objs;
|
|
short dir;
|
|
|
|
sna_80050440(work);
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
return;
|
|
}
|
|
|
|
objs = work->body.objs;
|
|
work->control.turn.vz = 0;
|
|
work->control.turn.vx = 0;
|
|
work->control.step.vz = 0;
|
|
work->control.step.vx = 0;
|
|
|
|
DG_InvisibleObjs(objs);
|
|
|
|
sna_start_anim_8004E1F4(work, sna_anim_duct_move_80054424);
|
|
work->field_A54.prone_bool_thing = 0;
|
|
sna_set_invuln_8004F2A0(work, 24);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK1);
|
|
GM_ClearPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_DOWNED | PLAYER_DAMAGED);
|
|
sna_clear_flags1_8004E308(work, (SNA_FLAG1_UNK2 | SNA_FLAG1_UNK3 | SNA_FLAG1_UNK5));
|
|
SetAction_8004E22C(work, work->actpack->still->crouch, 0);
|
|
|
|
objs = work->body.objs;
|
|
diff.vx = objs->objs[6].world.t[0] - objs->objs[0].world.t[0];
|
|
|
|
objs = work->body.objs;
|
|
diff.vz = objs->objs[6].world.t[2] - objs->objs[0].world.t[2];
|
|
|
|
dir = GV_VecDir2(&diff);
|
|
work->control.turn.vy = dir;
|
|
work->control.rot.vy = dir;
|
|
work->control.skip_flag &= ~CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
void snake_vr_sna_init_80053198(SnaInitWork *work, int time);
|
|
|
|
void sna_knockdown_getup_80050668(SnaInitWork *work)
|
|
{
|
|
SVECTOR vec;
|
|
int var_a2;
|
|
int var_a3;
|
|
int dir;
|
|
DG_OBJS *pObjs;
|
|
|
|
var_a2 = 500;
|
|
|
|
if (work->field_A54.knockdown_thing == 1)
|
|
{
|
|
var_a2 = 2;
|
|
var_a3 = -630;
|
|
}
|
|
else
|
|
{
|
|
var_a3 = -18;
|
|
}
|
|
|
|
if (!sna_8004E808(work, 1, var_a2, var_a3, 1500))
|
|
{
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_knockdown_getup_80054A10);
|
|
}
|
|
else
|
|
{
|
|
work->field_A54.knockdown_thing = 0;
|
|
|
|
sna_set_invuln_8004F2A0(work, 24);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK1);
|
|
GM_ClearPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_DOWNED | PLAYER_DAMAGED);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK5 | SNA_FLAG1_UNK3 | SNA_FLAG1_UNK2);
|
|
|
|
DG_VisibleObjs(work->body.objs);
|
|
|
|
if (GetAction(work) == 0x45)
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->still->crouch, 4);
|
|
|
|
// TODO: Duplication is probably from an inline
|
|
pObjs = work->body.objs;
|
|
vec.vx = pObjs->objs[6].world.t[0] - pObjs->objs[0].world.t[0];
|
|
|
|
pObjs = work->body.objs;
|
|
vec.vz = pObjs->objs[6].world.t[2] - pObjs->objs[0].world.t[2];
|
|
|
|
dir = GV_VecDir2(&vec);
|
|
work->control.turn.vy = dir;
|
|
work->control.rot.vy = dir;
|
|
|
|
sna_start_anim_8004E1F4(work, &sna_anim_prone_idle_800528BC);
|
|
}
|
|
else
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_DOWNED);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
sna_set_flags1_8004E2F4(work, 4);
|
|
sna_start_anim_8004E1F4(work, &snake_vr_sna_init_80053198);
|
|
}
|
|
}
|
|
}
|
|
|
|
int sub_800507D8(SnaInitWork *work)
|
|
{
|
|
if (dword_800ABBC4 == 0 && work->field_A38_local_data == 0)
|
|
{
|
|
work->field_A28 = 450;
|
|
GM_ClearPlayerStatusFlag(PLAYER_CHECK_WALL | PLAYER_CAUTION | PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[work->field_A26_stance]);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK9);
|
|
work->field_9C0 = NULL;
|
|
sna_8004E260(work, 0, 4, 0);
|
|
GM_ExitBehindCamera();
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void CheckMessage0_80050878(SnaInitWork *work)
|
|
{
|
|
int ret;
|
|
int length;
|
|
GV_MSG *pEntry;
|
|
GV_MSG *pMsg;
|
|
unsigned short id;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_TIMERBOMB_THROWN) &&
|
|
(GM_SnakeCurrentHealth != 0) &&
|
|
(GM_GameOverTimer == 0) &&
|
|
!GM_CheckPlayerStatusFlag(PLAYER_ACT_ONLY))
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_act_helper3_helper_80056650);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
sna_act_unk2_80051170(work->field_89C_pTarget);
|
|
GM_ClearPlayerStatusFlag(PLAYER_TIMERBOMB_THROWN);
|
|
GM_SetPlayerStatusFlag(PLAYER_ACT_ONLY);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK28);
|
|
}
|
|
|
|
if (sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK20))
|
|
{
|
|
return;
|
|
}
|
|
|
|
ret = GV_ReceiveMessage(work->control.name, &pMsg);
|
|
|
|
if (ret == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
length = ret;
|
|
|
|
pEntry = &work->field_7A4_msgs[work->field_7A0_msg_count];
|
|
pMsg = (pMsg + length) - 1;
|
|
|
|
for (; length > 0; work->field_7A0_msg_count++, pMsg--, pEntry++, length--)
|
|
{
|
|
if (work->field_7A0_msg_count == 8)
|
|
{
|
|
break;
|
|
}
|
|
|
|
id = pMsg->message[0];
|
|
|
|
if ((id == HASH_MOTION) || (id == HASH_RUN_MOVE) || (id == HASH_STANCE) || (id == HASH_GO_MOTION))
|
|
{
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_ACT_ONLY))
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_ACT_ONLY);
|
|
}
|
|
}
|
|
|
|
*pEntry = *pMsg;
|
|
}
|
|
}
|
|
|
|
static inline void sna_act_unk_helper_80050A64(SnaInitWork *work, GV_MSG *pMsg, int var_s4)
|
|
{
|
|
int flags;
|
|
int len;
|
|
UnkSnakeStruct2 *pStr;
|
|
|
|
if (sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK28))
|
|
{
|
|
return;
|
|
}
|
|
|
|
flags = 0;
|
|
len = pMsg->message_len;
|
|
pStr = &work->field_9E4;
|
|
|
|
pMsg->message_len = 0;
|
|
pStr->field_9E4 = pMsg->message[1];
|
|
pStr->field_9E6 = -1;
|
|
pStr->field_9E8 = -1;
|
|
pStr->field_9EA = -1;
|
|
pStr->field_9EC_flags3 = 0;
|
|
|
|
if (len > 2)
|
|
{
|
|
pStr->field_9E6 = pMsg->message[2];
|
|
}
|
|
|
|
if (len > 3)
|
|
{
|
|
pStr->field_9E8 = pMsg->message[3];
|
|
}
|
|
|
|
if (len > 4)
|
|
{
|
|
pStr->field_9EA = pMsg->message[4];
|
|
}
|
|
|
|
if (len > 5)
|
|
{
|
|
flags = pStr->field_9EC_flags3 = pMsg->message[5];
|
|
}
|
|
|
|
if (sna_act_unk_helper4_8004FA3C() && (var_s4 == 0))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_ACT_ONLY);
|
|
pMsg->message_len = 0;
|
|
printf("force act cancel %d\n", pMsg->message[1]);
|
|
}
|
|
else
|
|
{
|
|
pStr->field_9F2 = 0;
|
|
|
|
if (var_s4 != 0)
|
|
{
|
|
pStr->field_9F2 = 1;
|
|
}
|
|
|
|
if (!(flags & 0x80))
|
|
{
|
|
if (!work->field_A5A)
|
|
{
|
|
return;
|
|
}
|
|
|
|
GM_ConfigMotionControl(&work->body, &work->m_ctrl, work->field_A5A,
|
|
work->m_segs1, work->m_segs2, &work->control,
|
|
work->rots);
|
|
}
|
|
|
|
if (flags & 4)
|
|
{
|
|
if (len <= 6)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pStr->field_9EE = work->control.mov.vy - pMsg->message[6];
|
|
}
|
|
else
|
|
{
|
|
pStr->field_9EE = work->control.levels[0];
|
|
}
|
|
|
|
if (flags & 1)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_INTRUDE);
|
|
sub_8004ED08(work);
|
|
}
|
|
|
|
if (flags & 0x10)
|
|
{
|
|
work->control.skip_flag |= CTRL_SKIP_TRAP;
|
|
}
|
|
|
|
pStr->field_9F0 = 1;
|
|
|
|
sna_start_anim_8004E1F4(work, &sna_anim_dying_80055524);
|
|
GM_SetPlayerStatusFlag(4);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK28);
|
|
}
|
|
}
|
|
|
|
static inline void sna_act_unk_helper2_80050A64(SnaInitWork *work, GV_MSG *pMsg)
|
|
{
|
|
UnkSnakeStruct2 *pStr;
|
|
|
|
if (sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK28))
|
|
{
|
|
return;
|
|
}
|
|
|
|
pStr = &work->field_9E4;
|
|
|
|
pStr->field_9E8 = -1;
|
|
pStr->field_9F4.vx = pMsg->message[1];
|
|
pStr->field_9F4.vy = pMsg->message[2];
|
|
pStr->field_9F4.vz = pMsg->message[3];
|
|
pStr->field_9F4.pad = pMsg->message[4];
|
|
pStr->field_9EC_flags3 = 0;
|
|
|
|
if (pMsg->message_len > 5)
|
|
{
|
|
pStr->field_9EC_flags3 = pMsg->message[5];
|
|
}
|
|
|
|
if (sna_act_unk_helper4_8004FA3C() && !(pStr->field_9EC_flags3 & 0x400))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_ACT_ONLY);
|
|
pMsg->message_len = 0;
|
|
printf("run move cancel\n");
|
|
}
|
|
else
|
|
{
|
|
if (pMsg->message_len > 6)
|
|
{
|
|
pStr->field_9E8 = pMsg->message[6];
|
|
}
|
|
|
|
if (pStr->field_9EC_flags3 & 4)
|
|
{
|
|
work->control.skip_flag |= CTRL_SKIP_TRAP;
|
|
}
|
|
|
|
pStr->field_9F0 = 0;
|
|
sna_start_anim_8004E1F4(work, &sna_anim_mini_cutscene_800559D8);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK28);
|
|
pMsg->message_len = 0;
|
|
}
|
|
}
|
|
|
|
static inline void sna_act_unk_helper3_80050A64(SnaInitWork *work, GV_MSG *pMsg)
|
|
{
|
|
UnkSnakeStruct2 *pStr;
|
|
|
|
if (sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK28))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_ACT_ONLY);
|
|
pMsg->message_len = 0;
|
|
}
|
|
else
|
|
{
|
|
pStr = &work->field_9E4;
|
|
|
|
work->field_9FC = work->field_9B8_fn_anim;
|
|
pStr->field_9EE = 0;
|
|
pStr->field_9E8 = -1;
|
|
pStr->field_9EA = pMsg->message[1];
|
|
pStr->field_9EC_flags3 = 0;
|
|
|
|
if (pMsg->message_len > 2)
|
|
{
|
|
pStr->field_9E8 = pMsg->message[2];
|
|
}
|
|
|
|
if (pMsg->message_len > 3)
|
|
{
|
|
pStr->field_9EC_flags3 = pMsg->message[3];
|
|
}
|
|
|
|
if (sna_act_unk_helper4_8004FA3C() && !(pStr->field_9EC_flags3 & 0x400))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_ACT_ONLY);
|
|
pMsg->message_len = 0;
|
|
printf("force stance cancel\n");
|
|
}
|
|
else
|
|
{
|
|
if (pStr->field_9EC_flags3 & 4)
|
|
{
|
|
work->control.skip_flag |= CTRL_SKIP_TRAP;
|
|
}
|
|
|
|
sna_start_anim_8004E1F4(work, &sna_act_unk_helper3_80055DD8);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK28);
|
|
pMsg->message_len = 0;
|
|
pStr->field_9F0 = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_act_unk_80050A64(SnaInitWork *work)
|
|
{
|
|
int levels[2];
|
|
GV_MSG *pMsg;
|
|
GV_MSG *pMsgIter;
|
|
int msgCount;
|
|
int count;
|
|
int state;
|
|
|
|
if ((work->field_7A0_msg_count == 0) || sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK18))
|
|
{
|
|
return;
|
|
}
|
|
|
|
msgCount = 0;
|
|
pMsgIter = work->field_7A4_msgs;
|
|
pMsg = work->field_7A4_msgs;
|
|
|
|
for (count = work->field_7A0_msg_count; count > 0; count--, pMsg++)
|
|
{
|
|
switch (pMsg->message[0])
|
|
{
|
|
case 0xc000:
|
|
pMsg->message_len = 0;
|
|
break;
|
|
|
|
case HASH_MOTION:
|
|
state = 0;
|
|
goto helper3;
|
|
|
|
case HASH_GO_MOTION:
|
|
state = 1;
|
|
helper3:
|
|
sna_act_unk_helper_80050A64(work, pMsg, state);
|
|
break;
|
|
|
|
case HASH_RUN_MOVE:
|
|
sna_act_unk_helper2_80050A64(work, pMsg);
|
|
break;
|
|
|
|
case HASH_STANCE:
|
|
sna_act_unk_helper3_80050A64(work, pMsg);
|
|
break;
|
|
|
|
case HASH_STOP:
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK19);
|
|
pMsg->message_len = 0;
|
|
break;
|
|
|
|
case HASH_START:
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK19);
|
|
pMsg->message_len = 0;
|
|
break;
|
|
|
|
case HASH_KILL:
|
|
GV_DestroyActor(&work->actor);
|
|
pMsg->message_len = 0;
|
|
break;
|
|
|
|
case HASH_PADON:
|
|
GM_ClearPlayerStatusFlag(PLAYER_PAD_OFF);
|
|
pMsg->message_len = 0;
|
|
break;
|
|
|
|
case HASH_PADOFF:
|
|
GM_SetPlayerStatusFlag(PLAYER_PAD_OFF);
|
|
pMsg->message_len = 0;
|
|
break;
|
|
|
|
case HASH_TABAKO:
|
|
tabako_dword_8009F2C0 = pMsg->message[1];
|
|
pMsg->message_len = 0;
|
|
break;
|
|
|
|
case HASH_POSITION:
|
|
work->control.mov.vx = pMsg->message[1];
|
|
work->control.mov.vy = pMsg->message[2];
|
|
work->control.mov.vz = pMsg->message[3];
|
|
work->control.step = DG_ZeroVector;
|
|
sub_8004E588(work->control.map->hzd, &work->control.mov, levels);
|
|
work->control.levels[0] = levels[0];
|
|
work->control.levels[1] = levels[1];
|
|
pMsg->message_len = 0;
|
|
break;
|
|
|
|
case HASH_SLOW:
|
|
if (pMsg->message[1] == HASH_ON)
|
|
{
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG2_UNK27);
|
|
pMsg->message_len = 0;
|
|
}
|
|
else
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG2_UNK27);
|
|
pMsg->message_len = 0;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
pMsg->message_len = 0;
|
|
break;
|
|
}
|
|
|
|
|
|
if (pMsg->message_len != 0)
|
|
{
|
|
*pMsgIter = *pMsg;
|
|
pMsgIter++;
|
|
msgCount++;
|
|
}
|
|
}
|
|
|
|
work->field_7A0_msg_count = msgCount;
|
|
}
|
|
|
|
void sna_act_unk2_80051170(TARGET *param_1)
|
|
{
|
|
param_1->life_lost = 0;
|
|
param_1->faint = 0;
|
|
param_1->damaged &= ~(0x80 | 0x04);
|
|
param_1->scale = DG_ZeroVector;
|
|
param_1->weapon = WP_None;
|
|
param_1->a_mode = 0;
|
|
}
|
|
|
|
static inline int sna_weapon_switching_helper_800511BC(SnaInitWork *work)
|
|
{
|
|
if (sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK5))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_CB_BOX | PLAYER_DOWNED | PLAYER_DAMAGED | PLAYER_ACT_ONLY))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (!(work->field_920_tbl & 0x200) && GM_CheckPlayerStatusFlag(PLAYER_WATCH))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_PAD_OFF) || (GM_GameStatus & STATE_PADRELEASE))
|
|
{
|
|
if (GM_WeaponTypes[GM_CurrentWeaponId + 1] & 0x200)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int sna_weapon_switching_helper2_800511BC(SnaInitWork *work, int callback)
|
|
{
|
|
WeaponCreateEntry *pWeaponEntry;
|
|
void *(*pWeaponCreateFn)(void *, void *, int, void *, int);
|
|
GV_ACT *pWeaponActor;
|
|
|
|
pWeaponActor = work->field_908_weapon_actor;
|
|
|
|
if (pWeaponActor)
|
|
{
|
|
GV_DestroyActorQuick(pWeaponActor);
|
|
}
|
|
|
|
pWeaponEntry = &gSnakeWeapons_8009EF3C[GM_CurrentWeaponId + 1];
|
|
pWeaponCreateFn = pWeaponEntry->mCreateActorFn;
|
|
pWeaponActor = NULL;
|
|
|
|
if (pWeaponCreateFn)
|
|
{
|
|
pWeaponActor = pWeaponCreateFn(&work->control, &work->body, 4, &work->field_914_trigger, 1);
|
|
|
|
if (!pWeaponActor)
|
|
{
|
|
work->field_908_weapon_actor = 0;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (work->field_91C_weapon_idx == WP_Nikita)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_ITEM_DISABLE);
|
|
}
|
|
|
|
if (work->field_90C_pWeaponFn == &sna_anim_grenade_80058470)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_ITEM_DISABLE);
|
|
}
|
|
|
|
work->field_91C_weapon_idx = GM_CurrentWeaponId;
|
|
|
|
if (callback)
|
|
{
|
|
GM_CallSystemCallbackProc(3, GM_CurrentWeaponId);
|
|
}
|
|
|
|
work->field_920_tbl = GM_WeaponTypes[GM_CurrentWeaponId + 1];
|
|
|
|
if (GM_CurrentWeaponId >= 0)
|
|
{
|
|
work->field_918_n_bullets = &GM_Weapons[GM_CurrentWeaponId];
|
|
}
|
|
|
|
work->field_90C_pWeaponFn = pWeaponEntry->mStateFn;
|
|
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
work->field_908_weapon_actor = pWeaponActor;
|
|
work->actpack = &weapon_actions_8009ED8C[GM_CurrentWeaponId];
|
|
|
|
return 0;
|
|
}
|
|
|
|
void sna_weapon_switching_800511BC(SnaInitWork *work, int callback)
|
|
{
|
|
int temp_s1_2;
|
|
|
|
if (GM_CurrentWeaponId != work->field_91C_weapon_idx)
|
|
{
|
|
GM_WeaponChanged = 1;
|
|
}
|
|
|
|
if (!GM_WeaponChanged)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!sna_weapon_switching_helper_800511BC(work))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!(work->field_920_tbl & 0x1000) && (GM_CurrentWeaponId == work->field_91C_weapon_idx))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (sna_weapon_switching_helper2_800511BC(work, callback) < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
temp_s1_2 = work->field_920_tbl;
|
|
GM_WeaponChanged = 0;
|
|
|
|
if (temp_s1_2 & 0x200)
|
|
{
|
|
sub_8004EB74(work);
|
|
}
|
|
else if (!GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
sna_8004EC00(work);
|
|
}
|
|
|
|
if (temp_s1_2 & 0x20)
|
|
{
|
|
sna_start_anim_8004E1F4(work, work->field_90C_pWeaponFn);
|
|
GM_ClearPlayerStatusFlag(PLAYER_CAUTION);
|
|
}
|
|
else if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_duct_move_80054424);
|
|
}
|
|
else if (GM_CheckPlayerStatusFlag(PLAYER_CAUTION))
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_MOVE))
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_wall_move_80052BA8);
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, dword_8009EEB0[work->field_A26_stance]);
|
|
}
|
|
}
|
|
else if (GM_CheckPlayerStatusFlag(PLAYER_MOVE))
|
|
{
|
|
sna_start_anim_8004E1F4(work, dword_8009EEB8[work->field_A26_stance]);
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[work->field_A26_stance]);
|
|
}
|
|
|
|
sub_8004F454(work);
|
|
}
|
|
|
|
static inline int sna_helper_800515BC(SnaInitWork *work)
|
|
{
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_ACT_ONLY) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if ( sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK6) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if ( (GM_CurrentItemId == IT_Bandana) && (work->field_90C_pWeaponFn == &sna_80057A90) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if ( (GM_CheckPlayerStatusFlag(PLAYER_PAD_OFF) ||
|
|
((GM_GameStatus & (STATE_PADRELEASE | STATE_PADDEMO)) == STATE_PADRELEASE)) &&
|
|
((GM_ItemTypes[GM_CurrentItemId + 1] & 2) != 0) )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void sna_800515BC(SnaInitWork *work, int a2)
|
|
{
|
|
int itemType;
|
|
int temp_s4;
|
|
GV_ACT *pItemActor;
|
|
TSnakeEquipFuncion *ppfnEquip;
|
|
TSnakeEquipFuncion pfnEquip;
|
|
int temp_s0_2;
|
|
int var_s2;
|
|
|
|
if ( !sna_helper_800515BC(work) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( GM_CurrentItemId == work->field_9A8_current_item )
|
|
{
|
|
return;
|
|
}
|
|
|
|
itemType = GM_ItemTypes[GM_CurrentItemId + 1];
|
|
|
|
if ( GM_CheckPlayerStatusFlag(0x300) && ((itemType & 0x8000) != 0) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
temp_s4 = work->field_9AC;
|
|
pItemActor = work->field_9A4_item_actor;
|
|
|
|
if ( pItemActor )
|
|
{
|
|
GV_DestroyActorQuick(pItemActor);
|
|
}
|
|
|
|
ppfnEquip = &gSnakeEquips_8009EF8C[GM_CurrentItemId];
|
|
pItemActor = NULL;
|
|
|
|
if ( ((itemType & 0x8000) != 0) && (*ppfnEquip != 0) )
|
|
{
|
|
pfnEquip = *ppfnEquip;
|
|
|
|
if ( (GM_CurrentItemId == 2) || (GM_CurrentItemId == 3) || (GM_CurrentItemId == 4) )
|
|
{
|
|
pItemActor = pfnEquip(&work->control, &work->body, 0);
|
|
}
|
|
else
|
|
{
|
|
pItemActor = pfnEquip(&work->control, &work->body, 6);
|
|
}
|
|
|
|
if ( !pItemActor )
|
|
{
|
|
work->field_9A4_item_actor = NULL;
|
|
return;
|
|
}
|
|
}
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_CB_BOX);
|
|
|
|
work->field_9A8_current_item = GM_CurrentItemId;
|
|
|
|
if ( a2 != 0 )
|
|
{
|
|
GM_CallSystemCallbackProc(4, GM_CurrentItemId);
|
|
}
|
|
|
|
work->field_9AC = itemType;
|
|
work->field_9A4_item_actor = pItemActor;
|
|
|
|
if ( (itemType & 1) != 0 )
|
|
{
|
|
if ( GM_CurrentItemId == IT_Scope )
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_scope_80055334);
|
|
}
|
|
else if ( GM_CurrentItemId == IT_Camera )
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_jpegcam_800553CC);
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_box_idle_800553EC);
|
|
GM_SetPlayerStatusFlag(0x401000);
|
|
}
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_CAUTION | PLAYER_MOVE);
|
|
}
|
|
else
|
|
{
|
|
if ( ((work->field_920_tbl & 0x200) == 0) && ((temp_s4 & 1) != 0) )
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) )
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_duct_move_80054424);
|
|
}
|
|
else if ( GM_CheckPlayerStatusFlag(PLAYER_CAUTION) )
|
|
{
|
|
sna_start_anim_8004E1F4(work, dword_8009EEB0[work->field_A26_stance]);
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[work->field_A26_stance]);
|
|
}
|
|
}
|
|
|
|
if ( work->field_8E8_pTarget && (work->field_9B8_fn_anim != &sna_anim_throw_800589C8) )
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_choke_hold_80059154);
|
|
}
|
|
}
|
|
|
|
if ((itemType & 2) != 0)
|
|
{
|
|
sub_8004EB74(work);
|
|
GM_SetPlayerStatusFlag(PLAYER_WEAPON_DISABLE);
|
|
} else if ( !(work->field_920_tbl & 0x200) &&
|
|
!GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
sna_8004EC00(work);
|
|
}
|
|
|
|
temp_s0_2 = GM_CheckPlayerStatusFlag(PLAYER_MOVE);
|
|
|
|
var_s2 = 0;
|
|
if ( (work->control.skip_flag & CTRL_BOTH_CHECK) && ((itemType & 1) == 0) )
|
|
{
|
|
var_s2 = 1;
|
|
}
|
|
|
|
sub_8004F454(work);
|
|
|
|
if ( temp_s0_2 != 0 )
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
}
|
|
|
|
if ( var_s2 != 0 )
|
|
{
|
|
work->control.skip_flag |= CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
if ( GM_CheckPlayerStatusFlag(0x300) )
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_WEAPON_DISABLE);
|
|
|
|
if ( (work->field_9B8_fn_anim == &sna_anim_knockdown_80054710) || GM_CheckPlayerStatusFlag(PLAYER_DOWNED) )
|
|
{
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK3);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_anim_idle_8005275C(SnaInitWork *work, int time)
|
|
{
|
|
int action_flag; // $a1
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_80052E58;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052120;
|
|
|
|
if (GM_AlertMode >= 3)
|
|
{
|
|
action_flag = work->actpack->still->setup;
|
|
}
|
|
else
|
|
{
|
|
action_flag = work->actpack->still->stand;
|
|
}
|
|
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
}
|
|
}
|
|
|
|
void sna_anim_crouch_800527DC(SnaInitWork *work, int time)
|
|
{
|
|
int sound;
|
|
|
|
if (time == 0)
|
|
{
|
|
if (work->field_A26_stance != SNA_STANCE_SQUAT)
|
|
{
|
|
sound = SE_CHANGE_STANCE;
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) != 0)
|
|
{
|
|
sound = 183;
|
|
}
|
|
GM_SeSet(&work->control.mov, sound);
|
|
}
|
|
|
|
work->field_9C8_anim_update_fn_3p = sna_anim_crouch_helper_80053014;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052120;
|
|
SetAction_8004E22C(work, work->actpack->still->squat, 4);
|
|
work->field_A2C.vy = -128;
|
|
}
|
|
|
|
if ((time == 0 && work->field_A26_stance != SNA_STANCE_STANDING) ||
|
|
(time == 4 && work->field_A26_stance == SNA_STANCE_STANDING))
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_SQUAT);
|
|
work->field_A26_stance = SNA_STANCE_SQUAT;
|
|
}
|
|
}
|
|
|
|
void sna_anim_prone_idle_800528BC(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_CROUCH;
|
|
work->field_A28 = 450;
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_800531F4;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052120;
|
|
GM_SetPlayerStatusFlag(PLAYER_GROUND);
|
|
SetAction_8004E22C(work, work->actpack->still->crouch, 4);
|
|
}
|
|
}
|
|
|
|
void sna_anim_run_8005292C(SnaInitWork *work, int time)
|
|
{
|
|
int action_flag; // $a1
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_80053360;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052120;
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
if (GM_AlertMode >= 3)
|
|
{
|
|
action_flag = work->actpack->move->aim;
|
|
}
|
|
else
|
|
{
|
|
action_flag = work->actpack->move->stand;
|
|
}
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
}
|
|
}
|
|
|
|
void sna_anim_prone_move_800529C0(SnaInitWork *work, int time)
|
|
{
|
|
int action_flag; // $a1
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_A28 = 450;
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_800535B8;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052120;
|
|
if (work->field_A54.prone_bool_thing)
|
|
{
|
|
action_flag = work->actpack->move->crouch_backwards;
|
|
}
|
|
else
|
|
{
|
|
action_flag = work->actpack->move->crouch;
|
|
}
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
work->field_A54.prone_bool_thing = 0;
|
|
}
|
|
sna_80050440(work);
|
|
}
|
|
|
|
void sna_anim_wall_idle_and_c4_80052A5C(SnaInitWork *work, int time)
|
|
{
|
|
int sVar3;
|
|
int sound;
|
|
|
|
if (time == 0)
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_CAUTION) == 0)
|
|
{
|
|
sound = SE_WALLPRESS;
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) != 0)
|
|
{
|
|
sound = 183;
|
|
}
|
|
GM_SeSet(&work->control.mov, sound);
|
|
work->control.turn.vy = dword_800ABBD0 - 2048;
|
|
GM_SetPlayerStatusFlag(PLAYER_CAUTION);
|
|
}
|
|
|
|
sVar3 = work->field_91C_weapon_idx != WP_C4 ? 300 : 472;
|
|
|
|
work->field_9C8_anim_update_fn_3p = sna_anim_wall_idle_and_c4_helper_800537D4;
|
|
work->field_A28 = sVar3;
|
|
work->field_A26_stance = 0;
|
|
work->field_9CC_anim_update_fn_1p = sub_8005230C;
|
|
SetAction_8004E22C(work, work->actpack->still->against_wall, 4);
|
|
}
|
|
|
|
GM_CheckBehindCamera(work->control.map->hzd, &work->control);
|
|
|
|
if (work->field_A3A < 8 && pVec_800ABBCC != NULL)
|
|
{
|
|
(work->control).step.vx += pVec_800ABBCC->vx / 8;
|
|
(work->control).step.vz += pVec_800ABBCC->vz / 8;
|
|
work->field_A3A++;
|
|
}
|
|
}
|
|
|
|
void sna_anim_wall_move_80052BA8(SnaInitWork *work, int time)
|
|
{
|
|
int action;
|
|
|
|
if (time == 0)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE | PLAYER_CAUTION);
|
|
work->field_9C8_anim_update_fn_3p = sna_anim_wall_move_helper_800538CC;
|
|
work->field_9CC_anim_update_fn_1p = sub_8005230C;
|
|
|
|
if (work->field_A54.wall_thing == 2)
|
|
{
|
|
action = work->actpack->move->against_wall_r;
|
|
}
|
|
else
|
|
{
|
|
action = work->actpack->move->against_wall_l;
|
|
}
|
|
|
|
work->field_A28 = 300;
|
|
work->field_A54.wall_thing = 0;
|
|
SetAction_8004E22C(work, action, 4);
|
|
work->control.turn.vy = dword_800ABBD0 - 2048;
|
|
}
|
|
|
|
if (work->field_A3A < 8 && pVec_800ABBCC != NULL)
|
|
{
|
|
work->control.step.vx += pVec_800ABBCC->vx / 8;
|
|
work->control.step.vz += pVec_800ABBCC->vz / 8;
|
|
work->field_A3A++;
|
|
}
|
|
}
|
|
|
|
void sna_anim_wall_crouch_80052CCC(SnaInitWork *work, int time)
|
|
{
|
|
int sound;
|
|
int sound2;
|
|
|
|
if (time == 0)
|
|
{
|
|
if (work->field_A26_stance != SNA_STANCE_SQUAT)
|
|
{
|
|
sound = SE_CHANGE_STANCE;
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) != 0)
|
|
{
|
|
sound = 183;
|
|
}
|
|
GM_SeSet(&work->control.mov, sound);
|
|
}
|
|
|
|
work->field_A26_stance = SNA_STANCE_SQUAT;
|
|
work->field_9C8_anim_update_fn_3p = sna_anim_wall_crouch_helper_80053A54;
|
|
work->field_9CC_anim_update_fn_1p = sub_8005230C;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_CAUTION) == 0)
|
|
{
|
|
sound2 = SE_WALLPRESS;
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) != 0)
|
|
{
|
|
sound2 = 0xb7;
|
|
}
|
|
GM_SeSet(&work->control.mov, sound2);
|
|
work->control.turn.vy = dword_800ABBD0 - 2048;
|
|
}
|
|
|
|
GM_SetPlayerStatusFlag(PLAYER_SQUAT | PLAYER_CAUTION);
|
|
SetAction_8004E22C(work, work->actpack->still->squat_against_wall, 4);
|
|
|
|
work->field_A28 = work->field_91C_weapon_idx != WP_C4 ? 300 : 472;
|
|
}
|
|
|
|
GM_CheckBehindCamera(((work->control).map)->hzd, &work->control);
|
|
|
|
if (work->field_A3A < 8 && pVec_800ABBCC != NULL)
|
|
{
|
|
work->control.step.vx += pVec_800ABBCC->vx / 8;
|
|
work->control.step.vz += pVec_800ABBCC->vz / 8;
|
|
work->field_A3A++;
|
|
}
|
|
}
|
|
|
|
void sna_fn_80052E58(SnaInitWork *work, int time)
|
|
{
|
|
int action;
|
|
int diff;
|
|
|
|
if (sna_8005009C(work))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ((work->field_9B0_pad_ptr->press & PAD_CROSS) != 0)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_crouch_800527DC);
|
|
return;
|
|
}
|
|
|
|
if (GM_AlertMode >= 3)
|
|
{
|
|
action = work->actpack->still->setup;
|
|
}
|
|
else
|
|
{
|
|
action = work->actpack->still->stand;
|
|
}
|
|
|
|
SetAction_8004E22C(work, action, 4);
|
|
|
|
if (work->field_A38_local_data > 0)
|
|
{
|
|
work->field_A38_local_data--;
|
|
}
|
|
|
|
if (work->field_A38_local_data == 0 && gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
if (dword_800ABBC4 == 1 || (dword_800ABBC4 != 0 && work->field_79C == 2))
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_wall_idle_and_c4_80052A5C);
|
|
}
|
|
else
|
|
{
|
|
diff = GV_DiffDirAbs(work->control.turn.vy, gSnaMoveDir_800ABBA4);
|
|
if (diff > 256)
|
|
{
|
|
work->field_A38_local_data = diff / 1024 + 1;
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_run_begin_80053B88);
|
|
}
|
|
|
|
work->control.turn.vy = gSnaMoveDir_800ABBA4;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_anim_crouch_helper_80053014(SnaInitWork *work, int time)
|
|
{
|
|
int diff;
|
|
int sound;
|
|
|
|
if ((work->field_9B0_pad_ptr->press & PAD_CROSS) != 0)
|
|
{
|
|
if (sna_8004E808(work, 0, 0, 0, 1100) == 0)
|
|
{
|
|
work->control.turn.vy = work->control.rot.vy;
|
|
|
|
sound = SE_CHANGE_STANCE;
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) != 0)
|
|
{
|
|
sound = 183;
|
|
}
|
|
|
|
GM_SeSet(&work->control.mov, sound);
|
|
GM_ClearPlayerStatusFlag(PLAYER_SQUAT);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (work->field_A38_local_data > 0)
|
|
{
|
|
work->field_A38_local_data--;
|
|
}
|
|
|
|
if (work->field_A38_local_data == 0 && gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
if (dword_800ABBC4 == 1 || (dword_800ABBC4 != 0 && work->field_79C == 2))
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_wall_crouch_80052CCC);
|
|
}
|
|
else
|
|
{
|
|
diff = GV_DiffDirAbs(work->control.turn.vy, gSnaMoveDir_800ABBA4);
|
|
if (diff > 256)
|
|
{
|
|
work->field_A38_local_data = diff / 1024 + 1;
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_prone_begin_80053BE8);
|
|
}
|
|
|
|
work->control.turn.vy = gSnaMoveDir_800ABBA4;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_fn_800531F4(SnaInitWork *work, int time)
|
|
{
|
|
if (work->field_A38_local_data > 0)
|
|
{
|
|
work->field_A38_local_data -= 1;
|
|
}
|
|
|
|
if (!sna_prone_check_standup_80050398(work) && work->field_A38_local_data == 0 && gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
if (dword_800ABBC4 == 1 || (dword_800ABBC4 != 0 && work->field_79C == 2))
|
|
{
|
|
if (sna_8004E808(work, 0, 0, 0, 1500) == 0)
|
|
{
|
|
work->control.turn.vy = work->control.rot.vy;
|
|
GM_ClearPlayerStatusFlag(PLAYER_GROUND);
|
|
GM_SetPlayerStatusFlag(PLAYER_SQUAT | PLAYER_CAUTION);
|
|
sna_start_anim_8004E1F4(work, sna_anim_wall_crouch_80052CCC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (sub_8004E458(work->control.turn.vy, gSnaMoveDir_800ABBA4) == 3)
|
|
{
|
|
work->field_A54.prone_bool_thing = 1;
|
|
}
|
|
else
|
|
{
|
|
work->field_A54.prone_bool_thing = 0;
|
|
}
|
|
|
|
sna_start_anim_8004E1F4(work, sna_anim_prone_move_800529C0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_80053360(SnaInitWork *work, int time)
|
|
{
|
|
int angle;
|
|
|
|
if (sna_8005009C(work))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (work->field_9B0_pad_ptr->press & PAD_CROSS)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_crouch_800527DC);
|
|
return;
|
|
}
|
|
|
|
if (gSnaMoveDir_800ABBA4 < 0)
|
|
{
|
|
if (++work->field_A3A >= 5)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_idle_8005275C);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
work->field_A3A = 0;
|
|
}
|
|
|
|
|
|
if ((dword_800ABBC4 == 1) || ((dword_800ABBC4 != 0) && (work->field_79C == 2)))
|
|
{
|
|
if (++work->field_A38_local_data >= 3)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_wall_idle_and_c4_80052A5C);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
work->field_A38_local_data = 0;
|
|
}
|
|
|
|
if (work->field_A38_local_data == 0)
|
|
{
|
|
if (gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
angle = sub_8004E4C0(work, gSnaMoveDir_800ABBA4);
|
|
}
|
|
else
|
|
{
|
|
angle = work->control.turn.vy;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
angle = gSnaMoveDir_800ABBA4;
|
|
|
|
if (angle < 0)
|
|
{
|
|
angle = work->control.turn.vy;
|
|
}
|
|
}
|
|
|
|
if (GV_DiffDirAbs(work->control.turn.vy, angle) > 1048)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_idle_8005275C);
|
|
work->control.turn.vy = angle;
|
|
return;
|
|
}
|
|
|
|
work->control.turn.vy = angle;
|
|
sub_8004EA50(work, angle);
|
|
|
|
if (GM_AlertMode >= 3)
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->move->aim, 4);
|
|
}
|
|
else
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->move->stand, 4);
|
|
}
|
|
}
|
|
|
|
void sna_fn_800535B8(SnaInitWork *work, int time)
|
|
{
|
|
int var_s0;
|
|
int temp_s2;
|
|
int temp_s3;
|
|
unsigned char var_a1;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_enter_duct_80053E9C);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
return;
|
|
}
|
|
|
|
if (!sna_prone_check_standup_80050398(work))
|
|
{
|
|
if (gSnaMoveDir_800ABBA4 < 0)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
SetAction_8004E22C(work, work->actpack->still->crouch, 4);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_prone_idle_800528BC);
|
|
return;
|
|
}
|
|
|
|
|
|
if ((dword_800ABBC4 == 1) || ((dword_800ABBC4 != 0) && (work->field_79C == 2)))
|
|
{
|
|
if (!sna_8004E808(work, 0, 0, 0, 1500))
|
|
{
|
|
work->control.turn.vy = work->control.rot.vy;
|
|
GM_ClearPlayerStatusFlag(PLAYER_GROUND | PLAYER_MOVE);
|
|
GM_SetPlayerStatusFlag(PLAYER_CAUTION | PLAYER_SQUAT);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_wall_crouch_80052CCC);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
temp_s3 = work->actpack->move->crouch;
|
|
temp_s2 = work->actpack->move->crouch_backwards;
|
|
|
|
if (GetAction(work) == temp_s2)
|
|
{
|
|
var_s0 = gSnaMoveDir_800ABBA4 + 2048;
|
|
}
|
|
else
|
|
{
|
|
var_s0 = gSnaMoveDir_800ABBA4;
|
|
}
|
|
|
|
if (sub_8004E458(work->control.turn.vy, var_s0) == 3)
|
|
{
|
|
var_s0 += 2048;
|
|
var_a1 = temp_s3;
|
|
|
|
if (GetAction(work) == var_a1)
|
|
{
|
|
var_a1 = temp_s2;
|
|
}
|
|
|
|
SetAction_8004E22C(work, (var_a1), 4);
|
|
}
|
|
|
|
work->control.turn.vy = sub_8004E4C0(work, var_s0);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_anim_wall_idle_and_c4_helper_800537D4(SnaInitWork *work, int time)
|
|
{
|
|
if (work->field_A38_local_data != 0)
|
|
{
|
|
work->field_A38_local_data--;
|
|
}
|
|
|
|
if (sub_800507D8(work))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ((work->field_9B0_pad_ptr->press & PAD_CROSS) && !sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK9))
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_wall_crouch_80052CCC);
|
|
return;
|
|
}
|
|
|
|
if ((dword_800ABBC4 == 2) || (dword_800ABBC4 == 4))
|
|
{
|
|
work->field_A54.wall_thing = dword_800ABBC4;
|
|
sna_start_anim_8004E1F4(work, &sna_anim_wall_move_80052BA8);
|
|
}
|
|
|
|
if ((dword_800ABBD0 - 2048) != work->control.rot.vy)
|
|
{
|
|
work->field_A3A = 0;
|
|
work->control.turn.vy = dword_800ABBD0 - 2048;
|
|
}
|
|
|
|
sna_check_knock_800501F8(work, time);
|
|
sna_8005027C(work, time);
|
|
}
|
|
|
|
void sna_anim_wall_move_helper_800538CC(SnaInitWork *work, int time)
|
|
{
|
|
int var_s1;
|
|
|
|
if (work->field_A38_local_data != 0)
|
|
{
|
|
work->field_A38_local_data--;
|
|
}
|
|
|
|
if (sub_800507D8(work))
|
|
{
|
|
return;
|
|
}
|
|
|
|
GM_CheckBehindCamera(work->control.map->hzd, &work->control);
|
|
|
|
if ((work->field_9B0_pad_ptr->press & PAD_CROSS) && !sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK9))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_wall_crouch_80052CCC);
|
|
return;
|
|
}
|
|
|
|
if (dword_800ABBC4 == 1)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_wall_idle_and_c4_80052A5C);
|
|
return;
|
|
}
|
|
|
|
if (((dword_800ABBD0 - 2048) != work->control.rot.vy) || (pVec_800ABBC8 != pVec_800ABBCC))
|
|
{
|
|
work->field_A3A = 0;
|
|
work->control.turn.vy = dword_800ABBD0 - 2048;
|
|
}
|
|
|
|
sna_check_knock_800501F8(work, time);
|
|
sna_8005027C(work, time);
|
|
|
|
if (dword_800ABBC4 == 2)
|
|
{
|
|
var_s1 = work->actpack->move->against_wall_r;
|
|
}
|
|
else
|
|
{
|
|
var_s1 = work->actpack->move->against_wall_l;
|
|
}
|
|
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
SetAction_8004E22C(work, var_s1, 4);
|
|
}
|
|
|
|
void sna_anim_wall_crouch_helper_80053A54(SnaInitWork *work, int time)
|
|
{
|
|
int var_s0;
|
|
|
|
if (work->field_A38_local_data != 0)
|
|
{
|
|
work->field_A38_local_data--;
|
|
}
|
|
|
|
if (sub_800507D8(work))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ((work->field_9B0_pad_ptr->press & PAD_CROSS) && !sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK9))
|
|
{
|
|
if (!sna_8004E808(work, 0, 0, 0, 1100))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_SQUAT);
|
|
var_s0 = SE_CHANGE_STANCE;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER))
|
|
{
|
|
var_s0 = 183;
|
|
}
|
|
|
|
GM_SeSet(&work->control.mov, var_s0);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_wall_idle_and_c4_80052A5C);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!(GM_GameStatus & STATE_BEHIND_CAMERA) && ((dword_800ABBD0 - 2048) != work->control.rot.vy))
|
|
{
|
|
work->field_A3A = 0;
|
|
work->control.turn.vy = dword_800ABBD0 - 2048;
|
|
}
|
|
|
|
sna_check_knock_800501F8(work, time);
|
|
sna_8005027C(work, time);
|
|
}
|
|
}
|
|
|
|
void sna_fn_nothing_80053B80(SnaInitWork *work, int time)
|
|
{
|
|
}
|
|
|
|
void sna_anim_run_begin_80053B88(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_80054318;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052120;
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
SetAction_8004E22C(work, work->actpack->move->setup, 4);
|
|
}
|
|
}
|
|
|
|
void sna_anim_prone_begin_80053BE8(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
sna_set_flags1_8004E2F4(work, (SNA_FLAG1_UNK5 | SNA_FLAG1_UNK6));
|
|
SetAction_8004E22C(work, work->actpack->trans->crouch, 4);
|
|
work->field_A26_stance = SNA_STANCE_CROUCH;
|
|
work->control.skip_flag |= CTRL_BOTH_CHECK | CTRL_SKIP_TRAP;
|
|
GM_ClearPlayerStatusFlag(PLAYER_SQUAT);
|
|
GM_SetPlayerStatusFlag(PLAYER_GROUND);
|
|
}
|
|
|
|
if (time == 7)
|
|
{
|
|
work->control.skip_flag &= ~CTRL_SKIP_TRAP;
|
|
}
|
|
|
|
switch (work->field_A38_local_data)
|
|
{
|
|
case 0:
|
|
if (work->field_798_p_height < 250)
|
|
{
|
|
work->control.skip_flag &= ~CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->still->crouch, 4);
|
|
work->field_A38_local_data = 1;
|
|
}
|
|
break;
|
|
case 1:
|
|
sna_80050440(work);
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) != 0)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_enter_duct_80053E9C);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
SetAction_8004E22C(work, work->actpack->move->crouch, 4);
|
|
}
|
|
else
|
|
{
|
|
sna_clear_flags1_8004E308(work, 0x30);
|
|
sna_start_anim_8004E1F4(work, sna_anim_prone_idle_800528BC);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_anim_prone_standup_80053D74(SnaInitWork *work, int time)
|
|
{
|
|
int sound;
|
|
|
|
if (time == 0)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_GROUND);
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
SetAction_8004E22C(work, work->actpack->trans->stand, 4);
|
|
|
|
sound = SE_CHANGE_STANCE;
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) != 0)
|
|
{
|
|
sound = 183;
|
|
}
|
|
GM_SeSet(&work->control.mov, sound);
|
|
sna_set_flags1_8004E2F4(work, (SNA_FLAG1_UNK5 | SNA_FLAG1_UNK6));
|
|
}
|
|
|
|
if (work->control.height >= 250)
|
|
{
|
|
work->control.skip_flag |= CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
if (work->control.height > 500)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
|
|
if (time == 2)
|
|
{
|
|
work->control.turn.vx = 0;
|
|
}
|
|
|
|
if (time == 7)
|
|
{
|
|
work->control.skip_flag |= CTRL_SKIP_TRAP;
|
|
}
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
work->control.skip_flag &= ~(CTRL_BOTH_CHECK | CTRL_SKIP_TRAP);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
sna_clear_flags1_8004E308(work, (SNA_FLAG1_UNK5 | SNA_FLAG1_UNK6));
|
|
}
|
|
}
|
|
|
|
void sna_anim_enter_duct_80053E9C(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_800543A8;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
GM_SetPlayerStatusFlag(PLAYER_PAD_OFF | PLAYER_MENU_DISABLE);
|
|
sna_set_flags1_8004E2F4(work, (SNA_FLAG1_UNK5 | SNA_FLAG1_UNK6));
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) == 0 &&
|
|
GetAction(work) == work->actpack->move->crouch_backwards)
|
|
{
|
|
work->field_A38_local_data = 48;
|
|
}
|
|
else
|
|
{
|
|
work->field_A38_local_data = 24;
|
|
}
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
}
|
|
|
|
if (time == work->field_A38_local_data)
|
|
{
|
|
sna_clear_invuln_8004F2EC(work);
|
|
sna_80050440(work);
|
|
sna_clear_flags1_8004E308(work, (SNA_FLAG1_UNK3 | SNA_FLAG1_UNK5 | SNA_FLAG1_UNK6));
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
GM_ClearPlayerStatusFlag(PLAYER_PAD_OFF | PLAYER_MENU_DISABLE);
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) != 0)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_duct_move_80054424);
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_prone_idle_800528BC);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_80053FAC(SnaInitWork *work, int time)
|
|
{
|
|
short vec_y; // $v1
|
|
unsigned short pad_status; // $s1
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
SetAction_8004E22C(work, work->actpack->attack->setup, 2);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK3);
|
|
GM_ClearPlayerStatusFlag(PLAYER_ATTACK);
|
|
vec_y = work->field_A54.prone_bool_thing;
|
|
work->field_A54.prone_bool_thing = 0;
|
|
work->field_90C_pWeaponFn = sna_gun_800540D0;
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
work->control.turn.vy = vec_y;
|
|
sna_8004E260(work, 0, 4, 0);
|
|
}
|
|
|
|
pad_status = work->field_9B0_pad_ptr->status;
|
|
if (work->body.is_end || (pad_status & PAD_SQUARE) == 0)
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
work->field_910 = 0;
|
|
if ((pad_status & PAD_SQUARE) != 0)
|
|
{
|
|
GM_SeSet(&work->control.mov, SE_READY_WEAPON);
|
|
GM_SetPlayerStatusFlag(PLAYER_ATTACK);
|
|
sna_start_anim_8004E1F4(work, sna_anim_shoot_weapon_80056B88);
|
|
work->field_90C_pWeaponFn = sub_80057BF0;
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_gun_800540D0(SnaInitWork *work, int time)
|
|
{
|
|
int iVar1;
|
|
int a4;
|
|
|
|
if (time == 0)
|
|
{
|
|
iVar1 = GM_CheckPlayerStatusFlag(PLAYER_MOVE);
|
|
a4 = 0xffff;
|
|
if (iVar1 != 0)
|
|
{
|
|
a4 = 0x3fe;
|
|
}
|
|
sna_8004E260(work, SET, 4, a4);
|
|
work->field_A38_local_data = 0;
|
|
}
|
|
|
|
if ((work->field_9B0_pad_ptr->release & PAD_SQUARE) != 0)
|
|
{
|
|
work->field_A38_local_data = 1;
|
|
}
|
|
|
|
if ((work->field_9B0_pad_ptr->status & PAD_SQUARE) != 0)
|
|
{
|
|
work->field_926++;
|
|
}
|
|
else
|
|
{
|
|
work->field_926 = 0;
|
|
}
|
|
|
|
if (time == 8)
|
|
{
|
|
work->field_90C_pWeaponFn = sub_80057BF0;
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
}
|
|
}
|
|
|
|
void sna_bomb_800541A8(SnaInitWork *work)
|
|
{
|
|
void *pFn; // $a1
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
if (sna_8004FDE8(work, &stru_8009EFE4[0]))
|
|
{
|
|
pFn = sna_800571B8;
|
|
}
|
|
else
|
|
{
|
|
pFn = sna_80057118;
|
|
}
|
|
sna_start_anim_8004E1F4(work, pFn);
|
|
}
|
|
|
|
// or sna_no_weapon_80054210 ?
|
|
void sna_anim_chokethrow_begin1_80054210(SnaInitWork *work, int time)
|
|
{
|
|
void *pFn;
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
if (gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
pFn = sna_anim_throw_800589C8;
|
|
}
|
|
else
|
|
{
|
|
pFn = sna_anim_chokethrow_begin2_80058C80;
|
|
}
|
|
sna_start_anim_8004E1F4(work, pFn);
|
|
}
|
|
|
|
void snake_vr_sna_init_80053198(SnaInitWork *work, int time)
|
|
{
|
|
short new_y; // $v0
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
SetAction_8004E22C(work, 134, 4);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK26);
|
|
}
|
|
|
|
if (work->body.is_end)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_DOWNED);
|
|
sna_start_anim_8004E1F4(work, sna_anim_prone_idle_800528BC);
|
|
SetAction_8004E22C(work, work->actpack->still->crouch, 0);
|
|
new_y = work->control.turn.vy + 2048;
|
|
work->control.turn.vy = new_y;
|
|
work->control.rot.vy = new_y;
|
|
sna_clear_flags1_8004E308(work, (SNA_FLAG1_UNK3 | SNA_FLAG1_UNK26));
|
|
sna_clear_invuln_8004F2EC(work);
|
|
}
|
|
}
|
|
|
|
void sna_80054318(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 2 && gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_run_8005292C);
|
|
return;
|
|
}
|
|
|
|
if (work->body.is_end)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void sna_fn_800543A8(SnaInitWork *work, int time)
|
|
{
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) && time >= 16)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_PAD_OFF | PLAYER_MENU_DISABLE);
|
|
if (sna_prone_check_standup_80050398(work))
|
|
{
|
|
sna_clear_invuln_8004F2EC(work);
|
|
sna_clear_flags1_8004E308(
|
|
work, (SNA_FLAG1_UNK2 | SNA_FLAG1_UNK3 | SNA_FLAG1_UNK5 | SNA_FLAG1_UNK6 | SNA_FLAG1_UNK10));
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_anim_duct_move_80054424(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sub_8005688C;
|
|
work->field_9CC_anim_update_fn_1p = sub_80052468;
|
|
SetAction_8004E22C(work, work->actpack->still->crouch, 4);
|
|
}
|
|
work->field_A60.vy = work->control.levels[0] + 150;
|
|
}
|
|
|
|
void sna_anim_duct_idle_80054488(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
work->field_9C8_anim_update_fn_3p = sub_80056928;
|
|
work->field_9CC_anim_update_fn_1p = sub_80052468;
|
|
}
|
|
work->field_A60.vy = work->control.levels[0] + 250;
|
|
sna_80050440(work);
|
|
}
|
|
|
|
void sna_anim_shot_flinch_800544E0(SnaInitWork *work, int time)
|
|
{
|
|
int action_flag;
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052540;
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
|
|
if (work->field_89C_pTarget->life < 1)
|
|
{
|
|
GM_SeSet2(0, 0x3f, SE_PLAYEROUT);
|
|
sna_8004F8E4(work, work->field_A26_stance == SNA_STANCE_CROUCH ? 125 : 128);
|
|
}
|
|
|
|
if (work->field_A26_stance == SNA_STANCE_CROUCH)
|
|
{
|
|
action_flag = work->actpack->damage->field_8;
|
|
}
|
|
else if ((GV_Time & 1) != 0)
|
|
{
|
|
action_flag = work->actpack->damage->field_0;
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
else
|
|
{
|
|
action_flag = work->actpack->damage->field_1;
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
}
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
sna_set_invuln_8004F2A0(work, 32);
|
|
GM_ClearPlayerStatusFlag(PLAYER_DAMAGED | PLAYER_WEAPON_DISABLE);
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[work->field_A26_stance]);
|
|
}
|
|
|
|
if (work->field_A26_stance == SNA_STANCE_CROUCH)
|
|
{
|
|
sna_80050568(work);
|
|
}
|
|
}
|
|
|
|
void sna_act_helper2_helper7_80054648(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_800525F8;
|
|
|
|
SetAction_8004E22C(work, work->actpack->special2->field_4, 4);
|
|
|
|
if (work->field_89C_pTarget->life <= 0)
|
|
{
|
|
GM_SeSet2(0, 63, SE_PLAYEROUT);
|
|
sna_8004F8E4(work, 128);
|
|
}
|
|
}
|
|
|
|
if (work->body.is_end)
|
|
{
|
|
sna_set_invuln_8004F2A0(work, 32);
|
|
GM_ClearPlayerStatusFlag(PLAYER_DAMAGED);
|
|
sna_start_anim_8004E1F4(work, sna_anim_box_idle_800553EC);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK6);
|
|
}
|
|
}
|
|
|
|
// knocked down by grenade etc
|
|
void sna_anim_knockdown_80054710(SnaInitWork *work, int time)
|
|
{
|
|
int bVar1;
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052540;
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
|
|
bVar1 = work->actpack->damage->field_2;
|
|
work->field_A54.prone_bool_thing = 1;
|
|
|
|
SetAction_8004E22C(work, bVar1, 4);
|
|
|
|
if (work->field_89C_pTarget->life < 1 && GM_GameOverTimer == 0)
|
|
{
|
|
GM_SeSet2(0, 0x3f, SE_PLAYEROUT);
|
|
GM_GameOverTimer = -1;
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK20);
|
|
}
|
|
|
|
work->control.skip_flag |= CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
if (work->control.height < 500)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_CROUCH;
|
|
GM_SetPlayerStatusFlag(PLAYER_GROUND);
|
|
}
|
|
|
|
if (work->field_798_p_height < 250)
|
|
{
|
|
work->control.skip_flag &= ~CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
sna_set_invuln_8004F2A0(work, 32);
|
|
sna_start_anim_8004E1F4(work, sna_anim_knockdown_idle_80054930);
|
|
}
|
|
else
|
|
{
|
|
if (time < 12 && work->field_A54.prone_bool_thing == 1)
|
|
{
|
|
work->control.turn.vy += 170;
|
|
}
|
|
|
|
if (time > 16)
|
|
{
|
|
GV_NearExp8V(&work->field_A2C.vx, &DG_ZeroVector.vx, 3);
|
|
}
|
|
|
|
if ((work->field_A54.prone_bool_thing == 1 && time == 12) ||
|
|
(work->field_A54.prone_bool_thing == 2 && time == 0x14))
|
|
{
|
|
GM_SeSetMode(&work->control.mov, SE_HIT_FLOOR, GM_SEMODE_BOMB);
|
|
}
|
|
|
|
work->control.step.vx = work->field_A2C.vx;
|
|
work->control.step.vz = work->field_A2C.vz;
|
|
sna_80050568(work);
|
|
}
|
|
}
|
|
|
|
void sna_anim_knockdown_idle_80054930(SnaInitWork *work, int time)
|
|
{
|
|
int local_field_A54; // $v1
|
|
int action_flag; // $a1
|
|
short v5; // $a1
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_knockdown_check_getup_80056A1C;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052540;
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK5);
|
|
GM_SetPlayerStatusFlag(PLAYER_DOWNED | PLAYER_GROUND);
|
|
GM_ClearPlayerStatusFlag(PLAYER_DAMAGED);
|
|
local_field_A54 = work->field_A54.prone_bool_thing;
|
|
work->field_A26_stance = SNA_STANCE_CROUCH;
|
|
if (local_field_A54 == 1)
|
|
{
|
|
action_flag = work->actpack->damage->field_4;
|
|
}
|
|
else
|
|
{
|
|
action_flag = work->actpack->damage->field_5;
|
|
}
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
if (work->field_89C_pTarget->life <= 0)
|
|
{
|
|
v5 = 127;
|
|
if (work->field_A54.prone_bool_thing == 1)
|
|
{
|
|
v5 = 126;
|
|
}
|
|
sna_8004F8E4(work, v5);
|
|
}
|
|
sna_80050568(work);
|
|
}
|
|
}
|
|
|
|
void sna_anim_knockdown_getup_80054A10(SnaInitWork *work, int time)
|
|
{
|
|
int action_flag; // $a1
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052540;
|
|
if (work->field_A54.prone_bool_thing == 1)
|
|
{
|
|
action_flag = work->actpack->damage->field_6;
|
|
}
|
|
else
|
|
{
|
|
action_flag = work->actpack->damage->field_7;
|
|
}
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
work->field_A54.prone_bool_thing = 0;
|
|
}
|
|
|
|
if (work->control.height >= 250)
|
|
{
|
|
work->control.skip_flag |= CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
if (work->control.height >= 501)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
|
|
if (time == 2)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_GROUND);
|
|
work->control.turn.vx = 0;
|
|
}
|
|
|
|
if (work->body.is_end)
|
|
{
|
|
sna_clear_flags1_8004E308(work, (SNA_FLAG1_UNK3 | SNA_FLAG1_UNK5));
|
|
sna_set_invuln_8004F2A0(work, 24);
|
|
GM_ClearPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_DOWNED);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK1);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
work->control.skip_flag &= ~CTRL_BOTH_CHECK;
|
|
}
|
|
}
|
|
|
|
void sna_anim_knockdown_shot_80054B50(SnaInitWork *work)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_knockdown_check_getup_80056A1C;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052540;
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_DAMAGED);
|
|
|
|
if (work->field_89C_pTarget->life <= 0 && !GM_GameOverTimer)
|
|
{
|
|
GM_SeSet2(0, 63, SE_PLAYEROUT);
|
|
sna_8004F8E4(work, work->field_A54.prone_bool_thing == 1 ? 126 : 127);
|
|
}
|
|
else
|
|
{
|
|
sna_set_invuln_8004F2A0(work, 32);
|
|
}
|
|
|
|
sna_start_anim_8004E1F4(work, sna_anim_knockdown_idle_80054930);
|
|
}
|
|
|
|
// shot by tank while proned
|
|
void sna_anim_knockdown_shot_tank_80054C08(SnaInitWork *work, int time)
|
|
{
|
|
char bVar1;
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_80052540;
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
|
|
if (work->field_A54.prone_bool_thing == 1)
|
|
{
|
|
bVar1 = work->actpack->damage->field_A;
|
|
}
|
|
else
|
|
{
|
|
bVar1 = work->actpack->damage->field_B;
|
|
}
|
|
|
|
SetAction_8004E22C(work, bVar1, 4);
|
|
|
|
if (work->field_89C_pTarget->life < 1 && GM_GameOverTimer == 0)
|
|
{
|
|
GM_SeSet2(0, 0x3f, SE_PLAYEROUT);
|
|
GM_GameOverTimer = -1;
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK20);
|
|
}
|
|
}
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
sna_set_invuln_8004F2A0(work, 32);
|
|
sna_start_anim_8004E1F4(work, sna_anim_knockdown_idle_80054930);
|
|
}
|
|
else
|
|
{
|
|
if (time == 12)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_GROUND);
|
|
}
|
|
|
|
if (time > 16)
|
|
{
|
|
GV_NearExp8V(&work->field_A2C.vx, &DG_ZeroVector.vx, 3);
|
|
}
|
|
|
|
work->control.step.vx = work->field_A2C.vx;
|
|
work->control.step.vz = work->field_A2C.vz;
|
|
sna_80050568(work);
|
|
}
|
|
}
|
|
|
|
void sna_knock_80054D68(SnaInitWork *work, int time)
|
|
{
|
|
SVECTOR vec;
|
|
|
|
int var_a1;
|
|
int var_t0;
|
|
int temp_v0;
|
|
int noise;
|
|
int code;
|
|
HZD_FLR *seg;
|
|
|
|
if (time == 0)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_CHECK_WALL);
|
|
|
|
if (dword_800ABBC4 == 4)
|
|
{
|
|
var_a1 = work->actpack->still->tap_wall_l;
|
|
}
|
|
else
|
|
{
|
|
var_a1 = work->actpack->still->tap_wall_r;
|
|
}
|
|
|
|
GM_ConfigObjectOverride(&work->body, var_a1, 0, 4, 1022);
|
|
|
|
if (((work->field_91C_weapon_idx >= 0) && (work->field_91C_weapon_idx < 2)) || (work->field_91C_weapon_idx == 3))
|
|
{
|
|
var_t0 = 0x578;
|
|
|
|
if (work->field_A26_stance != 0)
|
|
{
|
|
var_t0 = 0x302;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var_t0 = 0x325;
|
|
|
|
if (work->field_A26_stance != 0)
|
|
{
|
|
var_t0 = 0x15E;
|
|
}
|
|
}
|
|
|
|
vec.vz = -150;
|
|
vec.vy = 0;
|
|
vec.vx = (dword_800ABBC4 == 4) ? 300 : -300;
|
|
|
|
if (sna_8004F628(work, &vec, -250, HZD_CHECK_DYNSEG | HZD_CHECK_SEG, SEGMENT_ATR | HZD_SEG_NO_BEHIND, var_t0))
|
|
{
|
|
temp_v0 = HZD_LineNearFlag();
|
|
code = (temp_v0 >> 8) & 7;
|
|
|
|
if (code < 4)
|
|
{
|
|
seg = HZD_LineNearSurface();
|
|
printf("seg %d %d %d %d : ", seg->b1.x, seg->b1.z, seg->b1.y, seg->b1.h);
|
|
printf("%d %d %d %d\n", seg->b2.x, seg->b2.z, seg->b2.y, seg->b2.h);
|
|
printf("code %d\n", code);
|
|
|
|
temp_v0 = GM_GetNoiseSound(temp_v0, 0);
|
|
noise = temp_v0;
|
|
NewAfterSe(noise, 6);
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((work->body.time2 != 0) || (work->body.action2 == 0))
|
|
{
|
|
sna_8004E260(work, 0, 4, 0);
|
|
GM_ClearPlayerStatusFlag(PLAYER_CHECK_WALL);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK9);
|
|
work->field_9C0 = NULL;
|
|
}
|
|
}
|
|
|
|
void snake_vr_sna_init_800565C8(SnaInitWork *work, int time);
|
|
|
|
void sna_act_helper2_helper_80054EFC(SnaInitWork *work, int pTime)
|
|
{
|
|
int time2;
|
|
int status;
|
|
unsigned char actionFlag;
|
|
SnaInitWork *actor;
|
|
int time;
|
|
|
|
actor = work;
|
|
time = pTime;
|
|
|
|
if (time == 0)
|
|
{
|
|
actor->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
actor->field_9CC_anim_update_fn_1p = snake_vr_sna_init_800565C8;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_GROUND))
|
|
{
|
|
actionFlag = actor->actpack->special1->field_1;
|
|
}
|
|
else
|
|
{
|
|
actionFlag = actor->actpack->special1->field_0;
|
|
}
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_SQUAT))
|
|
{
|
|
sna_8004E260(actor, actionFlag, 4, 0x3FE);
|
|
actor->field_A38_local_data = 1;
|
|
}
|
|
else
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
actor->field_A38_local_data = 2;
|
|
}
|
|
|
|
SetAction_8004E22C(actor, actionFlag, 4);
|
|
}
|
|
|
|
sna_set_flags1_8004E2F4(actor, SNA_FLAG1_UNK26);
|
|
}
|
|
|
|
if (time == 8)
|
|
{
|
|
if (actor->field_A26_stance == 2)
|
|
{
|
|
NewPadVibration(dword_8009EF08, 1);
|
|
NewPadVibration(dword_8009EF10, 2);
|
|
}
|
|
else
|
|
{
|
|
NewPadVibration(dword_8009EEF8, 1);
|
|
NewPadVibration(dword_8009EF00, 2);
|
|
}
|
|
}
|
|
|
|
if ((time == 6 && actor->field_A26_stance == 2) ||
|
|
(time == 0 && actor->field_A26_stance != 2))
|
|
{
|
|
GM_SeSetMode(&actor->control.mov, SE_SNEEZE, GM_SEMODE_BOMB);
|
|
GM_SetNoise(0x64, 0x10, &actor->control.mov);
|
|
}
|
|
|
|
status = 0;
|
|
if (time >= 25)
|
|
{
|
|
status = actor->field_9B0_pad_ptr->status & (PAD_UP | PAD_DOWN | PAD_LEFT | PAD_RIGHT);
|
|
}
|
|
|
|
switch (actor->field_A38_local_data)
|
|
{
|
|
case 0:
|
|
if (actor->body.is_end != 0 || status != 0)
|
|
{
|
|
sna_clear_flags1_8004E308(actor, SNA_FLAG1_UNK26);
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_CAUTION) != 0)
|
|
{
|
|
sna_start_anim_8004E1F4(actor, sna_anim_wall_idle_and_c4_80052A5C);
|
|
return;
|
|
}
|
|
sna_start_anim_8004E1F4(actor, dword_8009EEA4[actor->field_A26_stance]);
|
|
return;
|
|
}
|
|
return;
|
|
case 1:
|
|
if (actor->body.time2 != 0 || status != 0)
|
|
{
|
|
sna_clear_flags1_8004E308(actor, SNA_FLAG1_UNK26);
|
|
sna_8004E260(actor, 0, 4, 0);
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_CAUTION) != 0)
|
|
{
|
|
sna_start_anim_8004E1F4(actor, sna_anim_wall_crouch_80052CCC);
|
|
return;
|
|
}
|
|
sna_start_anim_8004E1F4(actor, sna_anim_crouch_800527DC);
|
|
return;
|
|
}
|
|
break;
|
|
case 2:
|
|
actor->field_A60.vy = actor->control.levels[0] + 150;
|
|
if (time >= 19)
|
|
{
|
|
time2 = 40 - time;
|
|
if (time2 == 0 || status != 0)
|
|
{
|
|
sna_clear_flags1_8004E308(actor, SNA_FLAG1_UNK26);
|
|
sna_start_anim_8004E1F4(actor, sna_anim_duct_move_80054424);
|
|
return;
|
|
}
|
|
actor->field_A60.vy += GV_RandS(16) * time2;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sna_anim_scope_80055334(SnaInitWork *param_1, int time)
|
|
{
|
|
int action_flag;
|
|
int sVar2;
|
|
|
|
if (time == 0)
|
|
{
|
|
param_1->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
param_1->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
|
|
if (param_1->field_A26_stance == SNA_STANCE_STANDING)
|
|
{
|
|
action_flag = 0x87;
|
|
}
|
|
else
|
|
{
|
|
action_flag = sna_8004EAA8(param_1, param_1->field_A26_stance);
|
|
}
|
|
|
|
SetAction_8004E22C(param_1, action_flag, 4);
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE);
|
|
}
|
|
|
|
sVar2 = param_1->field_A2A;
|
|
if (sVar2 < dword_800ABBDC)
|
|
{
|
|
sVar2 = dword_800ABBDC;
|
|
}
|
|
else if (dword_800ABBD4 < sVar2)
|
|
{
|
|
sVar2 = dword_800ABBD4;
|
|
}
|
|
|
|
param_1->control.turn.vx = sVar2;
|
|
}
|
|
|
|
void sna_anim_jpegcam_800553CC(SnaInitWork *work, int time)
|
|
{
|
|
sna_anim_scope_80055334(work, time);
|
|
}
|
|
|
|
void sna_anim_box_idle_800553EC(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_80056A54;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_800525F8;
|
|
GM_ClearPlayerStatusFlag(PLAYER_GROUND | PLAYER_SQUAT);
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
SetAction_8004E22C(work, work->actpack->special2->field_2, 4);
|
|
}
|
|
}
|
|
|
|
void sna_anim_box_move_8005544C(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_80056AD8;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_800525F8;
|
|
SetAction_8004E22C(work, work->actpack->special2->field_3, 4);
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
GM_ConfigControlInterp(&work->control, 4);
|
|
}
|
|
}
|
|
|
|
void sna_anim_box_stop_800554B4(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_800525F8;
|
|
SetAction_8004E22C(work, work->actpack->special2->field_4, 4);
|
|
}
|
|
|
|
if (work->body.is_end)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_box_idle_800553EC);
|
|
}
|
|
}
|
|
|
|
void sna_anim_dying_80055524(SnaInitWork *work, int time)
|
|
{
|
|
UnkSnakeStruct2 *unk2 = &work->field_9E4;
|
|
|
|
if (time == 0)
|
|
{
|
|
int f9e6;
|
|
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
|
|
sub_8004F338(work);
|
|
GM_SetPlayerStatusFlag(PLAYER_MENU_DISABLE | PLAYER_PAD_OFF);
|
|
|
|
if ((unk2->field_9EC_flags3 & 0x400) == 0) // TODO: make flags enum for flags3
|
|
{
|
|
if ((unk2->field_9EC_flags3 & 0x4000) != 0)
|
|
{
|
|
work->control.field_38 = -2;
|
|
work->control.step_size = -2;
|
|
work->field_A28 = -2;
|
|
}
|
|
else
|
|
{
|
|
work->control.field_38 = -1;
|
|
work->control.step_size = -1;
|
|
work->field_A28 = -1;
|
|
}
|
|
}
|
|
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
GetAction(work) = -1;
|
|
SetAction_8004E22C(work, unk2->field_9E4, 4);
|
|
|
|
f9e6 = unk2->field_9E6;
|
|
if (f9e6 >= 0)
|
|
{
|
|
work->control.turn.vy = f9e6;
|
|
work->control.rot.vy = f9e6;
|
|
}
|
|
|
|
work->field_A38_local_data = -1;
|
|
work->field_A3A = -1;
|
|
|
|
if ((unk2->field_9EC_flags3 & 0x1000) == 0)
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_CB_BOX) == 0)
|
|
{
|
|
if ((work->field_9AC & 2) != 0)
|
|
{
|
|
if ((GM_GameOverTimer == 0 && unk2->field_9F2 == 0) ||
|
|
sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK29) != 0)
|
|
{
|
|
work->field_A38_local_data = work->field_9A8_current_item;
|
|
sub_8004F204(work);
|
|
}
|
|
else
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_NOT_SIGHT);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
work->field_A38_local_data = work->field_9A8_current_item;
|
|
sub_8004F204(work);
|
|
}
|
|
|
|
if ((work->field_920_tbl & 0x200) != 0)
|
|
{
|
|
if (GM_GameOverTimer != 0 || unk2->field_9F2 != 0)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_NOT_SIGHT);
|
|
}
|
|
else
|
|
{
|
|
work->field_A3A = work->field_91C_weapon_idx;
|
|
sub_8004F14C(work);
|
|
}
|
|
}
|
|
else if (work->field_91C_weapon_idx != -1 && GM_CurrentWeaponId == WP_None)
|
|
{
|
|
sub_8004F14C(work);
|
|
}
|
|
}
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_SQUAT);
|
|
}
|
|
|
|
if ((unk2->field_9EC_flags3 & 0x200) != 0 && work->control.height < 500)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_GROUND);
|
|
}
|
|
else
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_GROUND);
|
|
work->control.turn.vx = 0;
|
|
}
|
|
|
|
if ((unk2->field_9EC_flags3 & 2) == 0)
|
|
{
|
|
work->field_A2C = DG_ZeroVector;
|
|
}
|
|
|
|
if ((unk2->field_9EC_flags3 & 0x4000) == 0)
|
|
{
|
|
if ((unk2->field_9EC_flags3 & 2) == 0)
|
|
{
|
|
int level;
|
|
int new_height;
|
|
short y_pos;
|
|
|
|
new_height = (unsigned short)work->body.height - (-unk2->field_9EE + work->control.levels[0]);
|
|
level = work->control.levels[0];
|
|
work->control.height = new_height;
|
|
y_pos = new_height + level;
|
|
|
|
work->control.mov.vy = y_pos;
|
|
work->body.objs->world.t[1] = y_pos;
|
|
|
|
DG_GetLightMatrix2(&work->control.mov, &work->field_848_lighting_mtx);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int levels[2];
|
|
sub_8004E588(work->control.map->hzd, &work->control.mov, levels);
|
|
work->control.levels[0] = levels[0];
|
|
work->control.levels[1] = levels[1];
|
|
}
|
|
|
|
if (work->body.is_end)
|
|
{
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK22);
|
|
|
|
if ((unk2->field_9EC_flags3 & 0x20) == 0)
|
|
{
|
|
work->control.skip_flag &= ~CTRL_SKIP_TRAP;
|
|
}
|
|
|
|
if ((unk2->field_9EC_flags3 & 0x100) != 0)
|
|
{
|
|
work->m_ctrl.interp = 15;
|
|
work->m_ctrl.info1.field_14 = 0;
|
|
work->field_9B8_fn_anim = sna_fn_nothing_80053B80;
|
|
work->field_9BC_anim_frame = 0;
|
|
work->field_A3A = 0;
|
|
work->field_A38_local_data = 0;
|
|
}
|
|
else
|
|
{
|
|
int stance;
|
|
int fa38;
|
|
int fa3a;
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_GROUND | PLAYER_MENU_DISABLE |
|
|
PLAYER_PAD_OFF);
|
|
sna_clear_invuln_8004F2EC(work);
|
|
|
|
stance = unk2->field_9EA;
|
|
fa38 = work->field_A38_local_data;
|
|
fa3a = work->field_A3A;
|
|
|
|
if (stance < SNA_STANCE_STANDING)
|
|
{
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
stance = work->field_A26_stance;
|
|
}
|
|
else
|
|
{
|
|
stance = SNA_STANCE_UNK;
|
|
}
|
|
}
|
|
|
|
if ((unk2->field_9EC_flags3 & 0x1000) != 0)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_box_idle_800553EC);
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
else
|
|
{
|
|
if (stance < SNA_STANCE_UNK)
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_INTRUDE);
|
|
sub_8004ED08(work);
|
|
}
|
|
|
|
work->field_A26_stance = stance;
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[stance]);
|
|
}
|
|
else
|
|
{
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_CROUCH;
|
|
GM_SetPlayerStatusFlag(PLAYER_INTRUDE | PLAYER_GROUND);
|
|
sna_8004EC8C(work);
|
|
}
|
|
|
|
sna_start_anim_8004E1F4(work, sna_anim_duct_move_80054424);
|
|
}
|
|
|
|
if ((unk2->field_9EC_flags3 & 8) == 0)
|
|
{
|
|
if (fa38 >= 0)
|
|
{
|
|
GM_CurrentItemId = fa38;
|
|
|
|
if ((unsigned int)(fa38 - 2) < 3)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
}
|
|
if (fa3a >= 0)
|
|
{
|
|
GM_CurrentWeaponId = fa3a;
|
|
GM_WeaponChanged = 1;
|
|
|
|
if (fa3a == WP_Rifle)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_CROUCH;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// things like "a surveillance camera??" where player control is halted
|
|
void sna_anim_mini_cutscene_800559D8(SnaInitWork *work, int time)
|
|
{
|
|
SVECTOR vec;
|
|
|
|
UnkSnakeStruct2 *pStr = &work->field_9E4;
|
|
int weapon;
|
|
int item;
|
|
int stance;
|
|
unsigned char action;
|
|
|
|
short temp_v0;
|
|
short temp_v1_2;
|
|
short temp_v0_2;
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = &sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = &sna_fn_nothing_80053B80;
|
|
|
|
sub_8004F338(work);
|
|
|
|
GM_SetPlayerStatusFlag(PLAYER_PAD_OFF | PLAYER_MENU_DISABLE);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
GM_ClearPlayerStatusFlag(PLAYER_GROUND | PLAYER_SQUAT);
|
|
|
|
work->field_A00.field_0_ivec.vz = -1;
|
|
work->field_A00.field_0_ivec.vx = GM_PlayerAddress;
|
|
work->field_A00.field_0_ivec.pad = GM_PlayerAddress;
|
|
|
|
sna_act_unk_helper2_helper2_800605DC(&work->field_A00, work->control.map->hzd, &work->field_9E4.field_9F4);
|
|
temp_v0 = HZD_GetAddress(work->control.map->hzd, &work->field_9E4.field_9F4, work->field_A00.field_0_ivec.vy);
|
|
|
|
temp_v1_2 = (temp_v0 >> 8) & 0xff;
|
|
temp_v0_2 = temp_v0 & 0xff;
|
|
|
|
if ((temp_v1_2 == 0xff) || (temp_v0_2 == 0xff) || (temp_v1_2 != temp_v0_2))
|
|
{
|
|
pStr->field_9EC_flags3 |= 0x200;
|
|
}
|
|
|
|
if (pStr->field_9EC_flags3 & 0x200)
|
|
{
|
|
GV_SubVec3(&pStr->field_9F4, &work->control.mov, &vec);
|
|
work->control.turn.vy = GV_VecDir2(&vec);
|
|
work->control.field_38 = -1;
|
|
work->control.step_size = -1;
|
|
work->field_A28 = -1;
|
|
}
|
|
|
|
work->field_A38_local_data = -1;
|
|
|
|
if (!(pStr->field_9EC_flags3 & 0x100) && ((GM_CheckPlayerStatusFlag(PLAYER_CB_BOX)) || (work->field_9AC & 2)))
|
|
{
|
|
work->field_A38_local_data = work->field_9A8_current_item;
|
|
sub_8004F204(work);
|
|
}
|
|
|
|
work->field_A3A = -1;
|
|
|
|
if (work->field_920_tbl & 0x200)
|
|
{
|
|
work->field_A3A = work->field_91C_weapon_idx;
|
|
sub_8004F14C(work);
|
|
}
|
|
|
|
if (pStr->field_9EC_flags3 & 0x100)
|
|
{
|
|
stance = SNA_STANCE_STANDING;
|
|
action = work->actpack->special2->field_3;
|
|
}
|
|
else if (pStr->field_9EC_flags3 & 1)
|
|
{
|
|
stance = SNA_STANCE_CROUCH;
|
|
action = work->actpack->move->crouch;
|
|
GM_SetPlayerStatusFlag(PLAYER_GROUND);
|
|
}
|
|
else
|
|
{
|
|
stance = SNA_STANCE_STANDING;
|
|
action = work->actpack->move->stand;
|
|
}
|
|
|
|
work->field_A26_stance = stance;
|
|
|
|
SetAction_8004E22C(work, action, 4);
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
}
|
|
|
|
if (!(pStr->field_9EC_flags3 & 0x200))
|
|
{
|
|
work->field_A00.field_0_ivec.vx = GM_PlayerAddress;
|
|
sna_unk_helper2_helper_8006070C(&work->field_A00, &work->control);
|
|
}
|
|
|
|
GV_NearExp4PV(&work->control.rot.vx, &work->control.turn.vx, 3);
|
|
GV_NearExp4PV(&work->control.rot.vx, &work->control.turn.vx, 3);
|
|
|
|
if (sna_act_unk_helper2_helper3_80060684(&work->field_A00, &work->control.mov) < pStr->field_9F4.pad)
|
|
{
|
|
sna_clear_invuln_8004F2EC(work);
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK22);
|
|
GM_ClearPlayerStatusFlag(PLAYER_PAD_OFF | PLAYER_MENU_DISABLE);
|
|
|
|
if (pStr->field_9EC_flags3 & 0x200)
|
|
{
|
|
work->control.field_38 = 450;
|
|
work->control.step_size = 450;
|
|
work->field_A28 = 450;
|
|
}
|
|
|
|
if (!(pStr->field_9EC_flags3 & 2))
|
|
{
|
|
item = work->field_A38_local_data;
|
|
weapon = work->field_A3A;
|
|
|
|
if (item >= 0)
|
|
{
|
|
GM_CurrentItemId = item;
|
|
|
|
if ((item == IT_Box1) || (item == IT_Box2) || (item == IT_Box3))
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
}
|
|
|
|
if (weapon >= 0)
|
|
{
|
|
GM_CurrentWeaponId = weapon;
|
|
GM_WeaponChanged = 1;
|
|
|
|
if (weapon == WP_Rifle)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_CROUCH;
|
|
}
|
|
else if (weapon == WP_Stinger)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!(pStr->field_9EC_flags3 & 8))
|
|
{
|
|
work->control.skip_flag &= ~CTRL_SKIP_TRAP;
|
|
}
|
|
|
|
if (pStr->field_9EC_flags3 & 1)
|
|
{
|
|
sna_80050440(work);
|
|
sna_clear_flags1_8004E308(work, 4);
|
|
}
|
|
|
|
if (pStr->field_9EC_flags3 & 0x100)
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_box_stop_800554B4);
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[work->field_A26_stance]);
|
|
}
|
|
|
|
if (pStr->field_9E8 >= 0)
|
|
{
|
|
work->control.turn.vy = pStr->field_9E8;
|
|
}
|
|
}
|
|
}
|
|
|
|
// similar to above, seems freeze snake and make him look at a certain direction or track something
|
|
// triggers on first elevator ride at dock and right before mantis fight to look at meryl
|
|
// PERMUTER
|
|
static inline void sna_act_unk_helper3_helper_80055DD8(SnaInitWork *work, UnkSnakeStruct2 *pStr)
|
|
{
|
|
SnaInitWork *work2;
|
|
char new_var;
|
|
int action;
|
|
int field_9E4;
|
|
work2 = work;
|
|
action = work->body.action;
|
|
if (!(((action != work->actpack->trans->crouch) || work->body.is_end) && ((action != work->actpack->trans->stand) || work2->body.is_end)))
|
|
{
|
|
pStr->field_9E4 = 1;
|
|
} else {
|
|
work2 = work;
|
|
if (((((action == work->actpack->damage->field_6) && (work->body.is_end == 0)) || ((action == work->actpack->damage->field_7) && (work2->body.is_end == 0))) || ((action == work->actpack->damage->field_2) && work->body.is_end)) || ((action == work->actpack->damage->field_3) && work2->body.is_end))
|
|
{
|
|
if ((action == work->actpack->damage->field_2) && work->body.is_end)
|
|
{
|
|
SetAction_8004E22C(work, 71, 4);
|
|
}
|
|
if ((action == work->actpack->damage->field_3) && work->body.is_end)
|
|
{
|
|
SetAction_8004E22C(work, 72, 4);
|
|
}
|
|
field_9E4 = 2;
|
|
|
|
}
|
|
else
|
|
if ((((action == work->actpack->damage->field_4) || (action == work->actpack->damage->field_5)) || (action == work->actpack->damage->field_A)) || (action == work->actpack->damage->field_B))
|
|
{
|
|
field_9E4 = 3;
|
|
}
|
|
else
|
|
if (((action == work->actpack->damage->field_2) && (work->body.is_end == 0)) || ((action == (new_var = work->actpack->damage->field_3)) && (work->body.is_end == 0)))
|
|
{
|
|
field_9E4 = 4;
|
|
}
|
|
else
|
|
{
|
|
field_9E4 = 0;
|
|
}
|
|
pStr->field_9E4 = field_9E4;
|
|
}
|
|
}
|
|
|
|
static inline void sna_act_unk_helper3_helper2_80055DD8(SnaInitWork *work)
|
|
{
|
|
switch (work->field_9E4.field_9EA)
|
|
{
|
|
case 0:
|
|
switch (work->field_A26_stance)
|
|
{
|
|
case SNA_STANCE_STANDING:
|
|
if (++work->field_9E4.field_9EE >= 4)
|
|
{
|
|
work->field_9E4.field_9EE = 0;
|
|
work->field_9E4.field_9E4 = 6;
|
|
}
|
|
break;
|
|
|
|
case SNA_STANCE_SQUAT:
|
|
SetAction_8004E22C(work, work->actpack->still->stand, 4);
|
|
|
|
if (++work->field_9E4.field_9EE == 4)
|
|
{
|
|
work->field_9E4.field_9EE = 0;
|
|
work->field_9E4.field_9E4 = 6;
|
|
}
|
|
|
|
break;
|
|
|
|
case SNA_STANCE_CROUCH:
|
|
SetAction_8004E22C(work, work->actpack->trans->stand, 4);
|
|
|
|
if (work->body.is_end != 0)
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->still->stand, 4);
|
|
work->field_9E4.field_9E4 = 6;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
switch (work->field_A26_stance)
|
|
{
|
|
case SNA_STANCE_STANDING:
|
|
SetAction_8004E22C(work, work->actpack->still->squat, 4);
|
|
|
|
if (++work->field_9E4.field_9EE == 4)
|
|
{
|
|
work->field_9E4.field_9EE = 0;
|
|
work->field_9E4.field_9E4 = 6;
|
|
}
|
|
break;
|
|
|
|
case SNA_STANCE_SQUAT:
|
|
if (++work->field_9E4.field_9EE == 4)
|
|
{
|
|
work->field_9E4.field_9EE = 0;
|
|
work->field_9E4.field_9E4 = 6;
|
|
}
|
|
break;
|
|
|
|
case SNA_STANCE_CROUCH:
|
|
SetAction_8004E22C(work, work->actpack->trans->stand, 4);
|
|
|
|
if (work->body.is_end != 0)
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->still->squat, 4);
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
switch (work->field_A26_stance)
|
|
{
|
|
case SNA_STANCE_STANDING:
|
|
SetAction_8004E22C(work, work->actpack->still->squat, 4);
|
|
|
|
if (++work->field_9E4.field_9EE == 4)
|
|
{
|
|
work->field_9E4.field_9EE = 0;
|
|
work->field_A26_stance = SNA_STANCE_SQUAT;
|
|
}
|
|
break;
|
|
|
|
case SNA_STANCE_SQUAT:
|
|
SetAction_8004E22C(work, work->actpack->trans->crouch, 4);
|
|
|
|
if (work->body.is_end != 0)
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->still->crouch, 4);
|
|
work->field_9E4.field_9E4 = 6;
|
|
}
|
|
break;
|
|
|
|
case SNA_STANCE_CROUCH:
|
|
if (++work->field_9E4.field_9EE == 4)
|
|
{
|
|
work->field_9E4.field_9EE = 0;
|
|
work->field_9E4.field_9E4 = 6;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sna_act_unk_helper3_80055DD8(SnaInitWork *work, int time)
|
|
{
|
|
UnkSnakeStruct2 *pStr;
|
|
int height;
|
|
int stance;
|
|
int action_flag;
|
|
int item;
|
|
int weapon;
|
|
|
|
pStr = &work->field_9E4;
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = &sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = &sna_fn_nothing_80053B80;
|
|
|
|
sub_8004F338(work);
|
|
|
|
GM_SetPlayerStatusFlag(PLAYER_MENU_DISABLE | PLAYER_PAD_OFF);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
GM_ClearPlayerStatusFlag(PLAYER_SQUAT | PLAYER_GROUND);
|
|
|
|
work->field_A38_local_data = IT_None;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_CB_BOX) || (work->field_9AC & 2))
|
|
{
|
|
work->field_A38_local_data = work->field_9A8_current_item;
|
|
sub_8004F204(work);
|
|
}
|
|
|
|
work->field_A3A = WP_None;
|
|
|
|
if (work->field_920_tbl & 0x200)
|
|
{
|
|
work->field_A3A = work->field_91C_weapon_idx;
|
|
sub_8004F14C(work);
|
|
}
|
|
|
|
if (pStr->field_9EA != 2)
|
|
{
|
|
work->control.turn.vx = 0;
|
|
}
|
|
|
|
sna_act_unk_helper3_helper_80055DD8(work, pStr);
|
|
}
|
|
|
|
height = work->control.height;
|
|
stance = pStr->field_9EA;
|
|
|
|
switch (stance)
|
|
{
|
|
case 0:
|
|
if (height > 500)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
if (height < 500)
|
|
{
|
|
work->field_A26_stance = stance;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
if (height < 500)
|
|
{
|
|
work->field_A26_stance = stance;
|
|
}
|
|
break;
|
|
}
|
|
|
|
switch(pStr->field_9E4)
|
|
{
|
|
case 0:
|
|
SetAction_8004E22C(work, sna_8004EAA8(work, work->field_A26_stance), 4);
|
|
pStr->field_9E4 = 5;
|
|
break;
|
|
|
|
case 1:
|
|
if (work->body.is_end != 0)
|
|
{
|
|
SetAction_8004E22C(work, sna_8004EAA8(work, work->field_A26_stance), 4);
|
|
pStr->field_9E4 = 5;
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
if (work->body.is_end != 0)
|
|
{
|
|
SetAction_8004E22C(work, sna_8004EAA8(work, 0), 4);
|
|
work->field_A26_stance = 0;
|
|
pStr->field_9E4 = 5;
|
|
}
|
|
break;
|
|
|
|
case 3:
|
|
if (work->field_A54.prone_bool_thing == 1)
|
|
{
|
|
action_flag = work->actpack->damage->field_6;
|
|
}
|
|
else
|
|
{
|
|
action_flag = work->actpack->damage->field_7;
|
|
}
|
|
|
|
work->field_A54.prone_bool_thing = 0;
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
pStr->field_9E4 = 2;
|
|
break;
|
|
|
|
case 4:
|
|
if (work->body.is_end != 0)
|
|
{
|
|
if (work->field_A54.prone_bool_thing == 1)
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->damage->field_6, 4);
|
|
}
|
|
else
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->damage->field_7, 4);
|
|
}
|
|
|
|
pStr->field_9E4 = 2;
|
|
}
|
|
break;
|
|
|
|
case 5:
|
|
sna_act_unk_helper3_helper2_80055DD8(work);
|
|
break;
|
|
|
|
case 6:
|
|
work->field_A26_stance = pStr->field_9EA;
|
|
|
|
if (work->field_A26_stance == SNA_STANCE_SQUAT)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_SQUAT);
|
|
}
|
|
else if (work->field_A26_stance == SNA_STANCE_CROUCH)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_GROUND);
|
|
}
|
|
|
|
sna_clear_invuln_8004F2EC(work);
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_set_flags1_8004E2F4(work, 0x200000);
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE | PLAYER_PAD_OFF);
|
|
|
|
if (!(pStr->field_9EC_flags3 & 0x2))
|
|
{
|
|
item = work->field_A38_local_data;
|
|
weapon = work->field_A3A;
|
|
|
|
if (item >= 0)
|
|
{
|
|
GM_CurrentItemId = item;
|
|
|
|
if (item == IT_Box1 || item == IT_Box2 || item == IT_Box3)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
}
|
|
|
|
if (weapon >= 0)
|
|
{
|
|
GM_CurrentWeaponId = weapon;
|
|
GM_WeaponChanged = 1;
|
|
|
|
if (weapon == WP_Rifle)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_CROUCH;
|
|
}
|
|
else if (weapon == WP_Stinger)
|
|
{
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!(pStr->field_9EC_flags3 & 0x8))
|
|
{
|
|
work->control.skip_flag &= ~CTRL_SKIP_TRAP;
|
|
}
|
|
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[work->field_A26_stance]);
|
|
|
|
if (pStr->field_9E8 >= 0)
|
|
{
|
|
work->control.turn.vy = pStr->field_9E8;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sna_act_helper3_helper_80056650(SnaInitWork *work, int time)
|
|
{
|
|
int result;
|
|
int footstepsFrame; // guessed
|
|
|
|
if (time == 0)
|
|
{
|
|
int *status = &GM_GameStatus;
|
|
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
|
|
*status |= STATE_PADRELEASE;
|
|
|
|
sub_8004F338(work);
|
|
work->control.skip_flag &= ~CTRL_SKIP_TRAP;
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
GM_ClearPlayerStatusFlag(PLAYER_SQUAT | PLAYER_GROUND);
|
|
sub_8004F14C(work);
|
|
sub_8004F204(work);
|
|
work->field_A26_stance = 0;
|
|
SetAction_8004E22C(work, 3, 1);
|
|
}
|
|
|
|
if (!work->field_908_weapon_actor)
|
|
{
|
|
GV_ACT *timerBomb;
|
|
timerBomb = NewTimerBomb(&work->control, &work->body, 4,
|
|
&work->field_914_trigger, 1);
|
|
work->field_908_weapon_actor = timerBomb;
|
|
work->field_924 = 0;
|
|
SetAction_8004E22C(work, 0x3c, 4);
|
|
|
|
if (!work->field_908_weapon_actor)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
result = 1;
|
|
footstepsFrame = work->m_ctrl.info1.frame;
|
|
switch (work->field_924)
|
|
{
|
|
case 0:
|
|
if (EndMotion(work))
|
|
{
|
|
SetAction_8004E22C(work, 3, 1);
|
|
work->field_924 = 1;
|
|
}
|
|
break;
|
|
case 1:
|
|
SetAction_8004E22C(work, 0x32, 1);
|
|
work->field_924 = 2;
|
|
break;
|
|
case 2:
|
|
if (footstepsFrame == 6)
|
|
{
|
|
result = 3;
|
|
work->field_924 = 3;
|
|
}
|
|
break;
|
|
case 3:
|
|
result = 0;
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
sna_clear_invuln_8004F2EC(work);
|
|
GM_GameStatus &= ~STATE_PADRELEASE;
|
|
GV_DestroyActorQuick(work->field_908_weapon_actor);
|
|
work->field_908_weapon_actor = NULL;
|
|
work->field_924 = 0;
|
|
work->field_9E4.field_9F0 = 0;
|
|
sna_set_flags1_8004E2F4(work, 0x200000);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
}
|
|
break;
|
|
}
|
|
|
|
work->field_914_trigger = result;
|
|
}
|
|
|
|
|
|
void sub_8005684C(SnaInitWork *work)
|
|
{
|
|
int y;
|
|
|
|
if ((work->field_9B0_pad_ptr->status & (PAD_LEFT | PAD_RIGHT)) == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
y = work->control.turn.vy;
|
|
if ((work->field_9B0_pad_ptr->status & PAD_LEFT) != 0)
|
|
{
|
|
y += 32;
|
|
}
|
|
else
|
|
{
|
|
y -= 32;
|
|
}
|
|
work->control.turn.vy = y;
|
|
}
|
|
|
|
void sub_8005688C(SnaInitWork *work, int time)
|
|
{
|
|
int action_flag; // $a1
|
|
|
|
if ((work->field_9B0_pad_ptr->status & (PAD_DOWN | PAD_UP)) != 0)
|
|
{
|
|
if ((work->field_9B0_pad_ptr->status & PAD_UP) != 0)
|
|
{
|
|
action_flag = work->actpack->move->crouch;
|
|
}
|
|
else
|
|
{
|
|
action_flag = work->actpack->move->crouch_backwards;
|
|
}
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
sna_start_anim_8004E1F4(work, sna_anim_duct_idle_80054488);
|
|
}
|
|
else
|
|
{
|
|
sub_8005684C(work);
|
|
}
|
|
}
|
|
|
|
void sub_80056928(SnaInitWork *param_1, int time)
|
|
{
|
|
char bVar1;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) == 0)
|
|
{
|
|
sna_start_anim_8004E1F4(param_1, sna_anim_enter_duct_80053E9C);
|
|
sna_set_invuln_8004F2A0(param_1, 0);
|
|
}
|
|
else
|
|
{
|
|
if ((param_1->field_9B0_pad_ptr->status & (PAD_DOWN | PAD_UP)) == 0)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(param_1, sna_anim_duct_move_80054424);
|
|
SetAction_8004E22C(param_1, param_1->actpack->still->crouch, 4);
|
|
}
|
|
else
|
|
{
|
|
if ((param_1->field_9B0_pad_ptr->status & PAD_UP) != 0)
|
|
{
|
|
bVar1 = param_1->actpack->move->crouch;
|
|
}
|
|
else
|
|
{
|
|
bVar1 = param_1->actpack->move->crouch_backwards;
|
|
}
|
|
|
|
SetAction_8004E22C(param_1, bVar1, 4);
|
|
sub_8005684C(param_1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_knockdown_check_getup_80056A1C(SnaInitWork *work, int time)
|
|
{
|
|
if (work->field_9B0_pad_ptr->press)
|
|
{
|
|
sna_knockdown_getup_80050668(work);
|
|
}
|
|
}
|
|
|
|
void sna_80056A54(SnaInitWork *work, int time)
|
|
{
|
|
if (gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_box_move_8005544C);
|
|
}
|
|
}
|
|
|
|
void sna_fn_80056AD8(SnaInitWork *work, int time)
|
|
{
|
|
if (gSnaMoveDir_800ABBA4 < 0)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, sna_anim_box_stop_800554B4);
|
|
}
|
|
else
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->special2->field_3, 4);
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
work->control.turn.vy = (short)gSnaMoveDir_800ABBA4;
|
|
}
|
|
}
|
|
|
|
void sna_80051A10(SnaInitWork *work, SVECTOR *pPos, SVECTOR *pOut, SVECTOR *pVec)
|
|
{
|
|
MATRIX rot;
|
|
SVECTOR vec;
|
|
SVECTOR vec2;
|
|
SVECTOR vec3;
|
|
SVECTOR vec4;
|
|
|
|
int len;
|
|
|
|
ReadRotMatrix(&rot);
|
|
DG_SetPos2(pPos, &work->control.rot);
|
|
DG_PutVector(pVec, pVec, 1);
|
|
SetRotMatrix(&rot);
|
|
|
|
vec = *pPos;
|
|
vec2 = *pVec;
|
|
|
|
if (sna_line_check(&vec, work->control.map->hzd, HZD_CHECK_ALL, SEGMENT_ATR) < 0)
|
|
{
|
|
vec2 = *pVec;
|
|
}
|
|
|
|
GV_SubVec3(&vec2, pPos, &vec3);
|
|
len = GV_VecLen3(&vec3);
|
|
|
|
if ((len - work->field_A28) <= 0)
|
|
{
|
|
vec3 = *pPos;
|
|
}
|
|
else
|
|
{
|
|
GV_LenVec3(&vec3, &vec4, len, len - work->field_A28);
|
|
GV_AddVec3(pPos, &vec4, &vec3);
|
|
}
|
|
|
|
*pOut = vec3;
|
|
}
|
|
|
|
int sna_80051BA4(SnaInitWork *work)
|
|
{
|
|
SVECTOR vec;
|
|
SVECTOR vec2;
|
|
SVECTOR vec3;
|
|
|
|
GV_PAD *pPad = work->field_9B0_pad_ptr;
|
|
unsigned short press = pPad->press;
|
|
unsigned short release = pPad->release;
|
|
|
|
if (pPad->status & (PAD_R1 | PAD_L1))
|
|
{
|
|
if (press & PAD_R1)
|
|
{
|
|
work->field_A56 = 8;
|
|
}
|
|
|
|
if (press & PAD_L1)
|
|
{
|
|
work->field_A56 = 4;
|
|
}
|
|
|
|
if (release & PAD_R1)
|
|
{
|
|
work->field_A56 = 4;
|
|
}
|
|
|
|
if (release & PAD_L1)
|
|
{
|
|
work->field_A56 = 8;
|
|
}
|
|
|
|
vec2 = vec = DG_ZeroVector;
|
|
vec2.vx = 1280;
|
|
vec.vx = -1280;
|
|
vec3 = work->field_A60;
|
|
|
|
sna_80051A10(work, &vec3, &work->field_A3C, &vec2);
|
|
sna_80051A10(work, &vec3, &work->field_A44, &vec);
|
|
|
|
if (!sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK16))
|
|
{
|
|
work->field_A58 = 8;
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK16);
|
|
}
|
|
else if (work->field_A56 & 4)
|
|
{
|
|
work->field_A60 = work->field_A3C;
|
|
|
|
}
|
|
else if (work->field_A56 & 8)
|
|
{
|
|
work->field_A60 = work->field_A44;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
if (work->field_A58 > 0)
|
|
{
|
|
if (--work->field_A58 == 0)
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK16);
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void sna_80051DA0(SnaInitWork *work)
|
|
{
|
|
unsigned int status = work->field_9B0_pad_ptr->status;
|
|
unsigned char ldy = work->field_9B0_pad_ptr->left_dy;
|
|
short *temp_s4;
|
|
int var_s1;
|
|
int var_s2;
|
|
int var_s0;
|
|
int temp_v0;
|
|
int temp_a1;
|
|
short var_a0;
|
|
short var_a2;
|
|
|
|
// status is passed using the wrong type here
|
|
GM_CheckShukanReverse((unsigned short *)&status);
|
|
GM_CheckShukanReverseAnalog(&ldy);
|
|
|
|
temp_s4 = work->field_9D0;
|
|
var_s2 = temp_s4[4];
|
|
var_s1 = -temp_s4[3];
|
|
|
|
if (work->field_9D0[0] == 0)
|
|
{
|
|
if (work->field_A26_stance == SNA_STANCE_CROUCH)
|
|
{
|
|
var_s0 = work->field_A2A;
|
|
}
|
|
else
|
|
{
|
|
var_s0 = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var_s0 = work->control.turn.vx;
|
|
}
|
|
|
|
if (work->field_A26_stance == SNA_STANCE_CROUCH)
|
|
{
|
|
if (work->field_91C_weapon_idx == WP_Rifle)
|
|
{
|
|
temp_v0 = work->field_A2A;
|
|
var_s1 += temp_v0;
|
|
var_s2 += temp_v0;
|
|
}
|
|
else
|
|
{
|
|
var_s1 += var_s0;
|
|
var_s2 += var_s0;
|
|
}
|
|
}
|
|
|
|
if (var_s1 < dword_800ABBDC)
|
|
{
|
|
var_s1 = dword_800ABBDC;
|
|
}
|
|
|
|
if (var_s2 > dword_800ABBD4)
|
|
{
|
|
var_s2 = dword_800ABBD4;
|
|
}
|
|
|
|
temp_a1 = sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK15);
|
|
var_a2 = 1;
|
|
var_a0 = 1;
|
|
|
|
if (status & PAD_UP)
|
|
{
|
|
if (temp_a1 & 0xff)
|
|
{
|
|
var_a0 = 64 - ldy;
|
|
var_a2 = 64;
|
|
}
|
|
|
|
var_s0 -= (temp_s4[5] * (var_a0 & 0xff)) / var_a2;
|
|
}
|
|
else if (status & PAD_DOWN)
|
|
{
|
|
if (temp_a1 & 0xff)
|
|
{
|
|
var_a0 = ldy + 64;
|
|
var_a2 = 63;
|
|
}
|
|
|
|
var_s0 += (temp_s4[6] * (var_a0 & 0xff)) / var_a2;
|
|
}
|
|
|
|
|
|
if (var_s0 < var_s1)
|
|
{
|
|
var_s0 = var_s1;
|
|
}
|
|
|
|
if (var_s2 < var_s0)
|
|
{
|
|
var_s0 = var_s2;
|
|
}
|
|
|
|
work->control.turn.vx = var_s0;
|
|
}
|
|
|
|
void sna_80051FD0(SnaInitWork *work)
|
|
{
|
|
int iVar1;
|
|
u_short uVar2;
|
|
unsigned int uVar3;
|
|
short sVar4;
|
|
short sVar5;
|
|
int iVar6;
|
|
short *short_arr;
|
|
|
|
short_arr = work->field_9D0;
|
|
uVar2 = work->field_9B0_pad_ptr->status;
|
|
if ((uVar2 & (PAD_LEFT | PAD_RIGHT)) != 0)
|
|
{
|
|
iVar1 = work->control.turn.vy;
|
|
uVar3 = sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK15);
|
|
sVar4 = 1;
|
|
sVar5 = 1;
|
|
if (uVar2 & PAD_LEFT)
|
|
{
|
|
if ((uVar3 & 0xff) != 0)
|
|
{
|
|
sVar4 = 0x40;
|
|
sVar5 = 0x40 - (*((unsigned char *)((short *)work->field_9B0_pad_ptr + 7)));
|
|
}
|
|
iVar6 = ((int)short_arr[8]) * (sVar5 & 0xff);
|
|
iVar1 += iVar6 / sVar4;
|
|
}
|
|
else
|
|
{
|
|
if ((uVar3 & 0xff) != 0)
|
|
{
|
|
sVar4 = 0x3f;
|
|
sVar5 = (*((unsigned char *)((short *)work->field_9B0_pad_ptr + 7))) + 0x40;
|
|
}
|
|
iVar6 = ((int)short_arr[7]) * (sVar5 & 0xff);
|
|
iVar1 -= iVar6 / sVar4;
|
|
}
|
|
work->control.turn.vy = iVar1;
|
|
}
|
|
}
|
|
|
|
void sna_fn_80052120(SnaInitWork *work, int time)
|
|
{
|
|
unsigned short press;
|
|
int sound;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) != 0)
|
|
{
|
|
sna_8004EC00(work);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
sna_start_anim_8004E1F4(work, sna_anim_enter_duct_80053E9C);
|
|
}
|
|
else
|
|
{
|
|
press = work->field_9B0_pad_ptr->press;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
SetAction_8004E22C(work, sna_8004EAA8(work, (int)work->field_A26_stance), 4);
|
|
|
|
if ((work->field_9B0_pad_ptr->status & PAD_TRIANGLE) == 0)
|
|
{
|
|
sna_8004EC00(work);
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[work->field_A26_stance]);
|
|
}
|
|
else
|
|
{
|
|
if (sna_80051BA4(work))
|
|
{
|
|
return;
|
|
}
|
|
|
|
sna_80051DA0(work);
|
|
sna_80051FD0(work);
|
|
|
|
if ((press & PAD_CROSS) != 0)
|
|
{
|
|
switch (work->field_A26_stance)
|
|
{
|
|
case 0:
|
|
sna_start_anim_8004E1F4(work, sna_anim_crouch_800527DC);
|
|
break;
|
|
case 2:
|
|
if (sna_8004E808(work, 1, 0, -0x26e, 0x5dc) != 0)
|
|
{
|
|
return;
|
|
}
|
|
default:
|
|
if (sna_8004E808(work, 0, 0, 0, 0x5dc) != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
work->control.turn.vy = work->control.rot.vy;
|
|
GM_ClearPlayerStatusFlag(PLAYER_SQUAT | PLAYER_GROUND);
|
|
|
|
sound = SE_CHANGE_STANCE;
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) != 0)
|
|
{
|
|
sound = 183;
|
|
}
|
|
|
|
GM_SeSet(&work->control.mov, sound);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_8005230C(SnaInitWork *work, int time)
|
|
{
|
|
int action;
|
|
unsigned short status;
|
|
unsigned short press;
|
|
|
|
status = work->field_9B0_pad_ptr->status;
|
|
press = work->field_9B0_pad_ptr->press;
|
|
|
|
if ((status & PAD_TRIANGLE) == 0)
|
|
{
|
|
sna_8004EC00(work);
|
|
work->field_A38_local_data = 2;
|
|
}
|
|
else
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_MOVE) != 0)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
|
|
if (work->field_A26_stance == SNA_STANCE_STANDING)
|
|
{
|
|
action = work->actpack->still->against_wall;
|
|
}
|
|
else
|
|
{
|
|
action = work->actpack->still->squat_against_wall;
|
|
}
|
|
|
|
SetAction_8004E22C(work, action, 4);
|
|
}
|
|
if (((press & (PAD_LEFT | PAD_DOWN | PAD_RIGHT | PAD_UP)) != 0) ||
|
|
((status & (PAD_LEFT | PAD_DOWN | PAD_RIGHT | PAD_UP)) == 0))
|
|
{
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_CAUTION);
|
|
work->field_A28 = 0x1c2;
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[work->field_A26_stance]);
|
|
GM_ExitBehindCamera();
|
|
}
|
|
|
|
if (!sna_80051BA4(work) && (press & PAD_CROSS) != 0)
|
|
{
|
|
if (work->field_A26_stance == SNA_STANCE_STANDING)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_wall_crouch_80052CCC);
|
|
}
|
|
else
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_SQUAT);
|
|
sna_start_anim_8004E1F4(work, sna_anim_wall_idle_and_c4_80052A5C);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void sub_80052468(SnaInitWork *work, int time)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) == 0)
|
|
{
|
|
work->field_A56 = 0;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE |
|
|
PLAYER_NORMAL_WATCH | PLAYER_WATCH);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
sna_start_anim_8004E1F4(work, sna_anim_enter_duct_80053E9C);
|
|
}
|
|
else
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->still->crouch, 4);
|
|
|
|
if ((work->field_9B0_pad_ptr->status & PAD_TRIANGLE) == 0)
|
|
{
|
|
work->field_A56 = 0;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE |
|
|
PLAYER_NORMAL_WATCH | PLAYER_WATCH);
|
|
sna_start_anim_8004E1F4(work, sna_anim_duct_move_80054424);
|
|
}
|
|
|
|
sna_80051DA0(work);
|
|
sna_80051FD0(work);
|
|
}
|
|
}
|
|
|
|
void sna_fn_80052540(SnaInitWork *work, int time)
|
|
{
|
|
if ((work->field_9B0_pad_ptr->status & PAD_TRIANGLE) == 0)
|
|
{
|
|
sna_8004EC00(work);
|
|
}
|
|
|
|
if (work->field_9B8_fn_anim == sna_anim_knockdown_idle_80054930 &&
|
|
((work->field_9B0_pad_ptr->press & ~PAD_TRIANGLE) != 0))
|
|
{
|
|
sna_knockdown_getup_80050668(work);
|
|
}
|
|
|
|
gUnkCameraStruct_800B77B8.eye.vy += 320;
|
|
sna_8004EE28(work);
|
|
}
|
|
|
|
void sna_fn_800525F8(SnaInitWork *work, int time)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
if (work->field_9B8_fn_anim != sna_anim_box_idle_800553EC)
|
|
{
|
|
if (work->body.is_end)
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->special2->field_2, 4);
|
|
}
|
|
}
|
|
|
|
if (!(work->field_9B0_pad_ptr->status & PAD_TRIANGLE))
|
|
{
|
|
sna_8004EC00(work);
|
|
work->control.turn.vx = 0;
|
|
}
|
|
else
|
|
{
|
|
sna_80051DA0(work);
|
|
sna_80051FD0(work);
|
|
}
|
|
}
|
|
|
|
void snake_vr_sna_init_800565C8(SnaInitWork *work, int time)
|
|
{
|
|
if (!(work->field_9B0_pad_ptr->status & PAD_TRIANGLE))
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
work->field_A56 = 0;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE
|
|
| PLAYER_NORMAL_WATCH
|
|
| PLAYER_WATCH);
|
|
}
|
|
else
|
|
{
|
|
sna_8004EC00(work);
|
|
}
|
|
}
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_INTRUDE))
|
|
{
|
|
sna_8004EE28(work);
|
|
}
|
|
}
|
|
|
|
void sna_anim_shoot_weapon_80056B88(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_anim_shoot_weapon_helper_80057590;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
SetAction_8004E22C(work, work->actpack->still->setup, 4);
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
}
|
|
}
|
|
|
|
void sna_anim_rungun_begin_80056BDC(SnaInitWork *param_1, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
param_1->field_9C8_anim_update_fn_3p = sna_anim_rungun_begin_helper_800577B4;
|
|
param_1->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
SetAction_8004E22C(param_1, param_1->actpack->move->setup, 4);
|
|
}
|
|
}
|
|
|
|
void sna_anim_rungun_80056C3C(SnaInitWork *param_1, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
param_1->field_9C8_anim_update_fn_3p = sna_anim_rungun_helper_80057844;
|
|
param_1->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
SetAction_8004E22C(param_1, param_1->actpack->move->stand, 4);
|
|
}
|
|
}
|
|
|
|
void sna_anim_nikita_80056C9C(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
|
|
SetAction_8004E22C(work, work->actpack->attack->shoot, 4);
|
|
sna_8004E260(work, 0, 4, 0);
|
|
|
|
if (*work->field_918_n_bullets == 0)
|
|
{
|
|
work->field_A38_local_data = 1;
|
|
}
|
|
}
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
SetAction_8004E22C(work, SET, 4);
|
|
}
|
|
|
|
if (work->field_A38_local_data != 0 || time >= 24)
|
|
{
|
|
if (work->field_A38_local_data != 0 || time == 24)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_ITEM_DISABLE);
|
|
}
|
|
|
|
if (dword_8009F46C[0] == 0)
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline int sna_anim_psg1_helper_80056DDC(void)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
void sna_anim_psg1_80056DDC(SnaInitWork *work, int time)
|
|
{
|
|
MATRIX rotation;
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_A44.pad = 0;
|
|
work->field_A52 = 0;
|
|
|
|
work->field_9C8_anim_update_fn_3p = &sna_anim_psg1_helper_80057FD4;
|
|
work->field_9CC_anim_update_fn_1p = &sna_anim_psg1_helper_80057FD4;
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
|
|
GM_Camera.first_person = 0;
|
|
work->field_A20 = sna_anim_psg1_helper_80056DDC();
|
|
|
|
switch (work->field_A26_stance)
|
|
{
|
|
case 0:
|
|
SetAction_8004E22C(work, work->actpack->still->squat, 4);
|
|
work->field_A2C.vy = -128;
|
|
work->field_A3A = 0;
|
|
break;
|
|
|
|
case 1:
|
|
work->field_A3A = 1;
|
|
break;
|
|
|
|
case 2:
|
|
work->field_A3A = 3;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (work->field_A3A < 3)
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_MENU_DISABLE);
|
|
}
|
|
|
|
switch (work->field_A3A)
|
|
{
|
|
case 0:
|
|
if (time == 4)
|
|
{
|
|
work->field_A3A = 1;
|
|
}
|
|
|
|
break;
|
|
|
|
case 1:
|
|
GM_SetPlayerStatusFlag(PLAYER_SQUAT);
|
|
work->field_A26_stance = 1;
|
|
SetAction_8004E22C(work, work->actpack->trans->crouch, 4);
|
|
work->field_A3A = 2;
|
|
work->control.skip_flag |= (CTRL_BOTH_CHECK | CTRL_SKIP_TRAP);
|
|
break;
|
|
|
|
case 2:
|
|
if (work->field_798_p_height < 250)
|
|
{
|
|
work->control.skip_flag &= ~CTRL_BOTH_CHECK;
|
|
}
|
|
|
|
if (work->m_ctrl.info1.frame == 7)
|
|
{
|
|
work->control.skip_flag &= ~CTRL_SKIP_TRAP;
|
|
}
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
work->field_A3A = 3;
|
|
GM_SetPlayerStatusFlag(PLAYER_GROUND);
|
|
work->field_A26_stance = 2;
|
|
}
|
|
|
|
break;
|
|
|
|
case 3:
|
|
sub_8004EB74(work);
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE | PLAYER_SQUAT);
|
|
sna_clear_invuln_8004F2EC(work);
|
|
work->control.turn.vx = work->field_A2A;
|
|
SetAction_8004E22C(work, SET, 4);
|
|
work->field_A3A = 4;
|
|
break;
|
|
|
|
default:
|
|
DG_SetPos(&work->body.objs->objs[4].world);
|
|
DG_MovePos(&svector_800AB7E4);
|
|
ReadRotMatrix(&rotation);
|
|
|
|
work->field_A60.vx = rotation.t[0];
|
|
work->field_A60.vy = rotation.t[1];
|
|
work->field_A60.vz = rotation.t[2];
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INVINCIBLE) && (GM_Camera.first_person != 0))
|
|
{
|
|
gUnkCameraStruct_800B77B8.eye.vy += GV_RandU(16) * work->field_A24_invuln_frames;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
void sna_anim_stinger_800570C0(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = OP_ShootStinger;
|
|
work->field_9CC_anim_update_fn_1p = OP_ShootStinger;
|
|
SetAction_8004E22C(work, SET, 4);
|
|
work->field_A26_stance = SNA_STANCE_STANDING;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MENU_DISABLE | PLAYER_GROUND |
|
|
PLAYER_SQUAT);
|
|
}
|
|
}
|
|
|
|
void sna_80057118(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
if (bakudan_count_8009F42C >= 16)
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
GM_SeSet2(0, 0x3f, SE_BUZZER);
|
|
return;
|
|
}
|
|
|
|
work->field_9C8_anim_update_fn_3p = sub_80058644;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
SetAction_8004E22C(work, work->actpack->attack->field_5, 4);
|
|
}
|
|
|
|
sub_8004E9D0(work);
|
|
}
|
|
|
|
void sna_800571B8(SnaInitWork *work, int time)
|
|
{
|
|
SVECTOR *vec1;
|
|
TARGET *pGVar3;
|
|
SVECTOR *vec2;
|
|
|
|
vec2 = &work->field_8EC_vec;
|
|
|
|
if (time == 0)
|
|
{
|
|
if (bakudan_count_8009F42C >= 16)
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
work->field_8E8_pTarget->damaged &= ~(0x40);
|
|
work->field_8E8_pTarget = NULL;
|
|
return;
|
|
}
|
|
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
SetAction_8004E22C(work, work->actpack->attack->field_6, 4);
|
|
pGVar3 = work->field_8E8_pTarget;
|
|
DG_PutVector(&svector_800AB7EC, vec2, 1);
|
|
GV_SubVec3(&pGVar3->center, vec2, vec2);
|
|
|
|
vec2->vx /= 4;
|
|
vec2->vy /= 4;
|
|
vec2->vz /= 4;
|
|
}
|
|
|
|
vec1 = &work->control.step;
|
|
|
|
if (time < 4)
|
|
{
|
|
GV_AddVec3(vec1, vec2, vec1);
|
|
}
|
|
|
|
if (time == 6)
|
|
{
|
|
GM_SeSet(&work->control.mov, SE_C4_PUT);
|
|
NewBakudan(work->field_8E8_pTarget->body, &svector_800AB7F4, 1, 1, work->field_8E8_pTarget);
|
|
work->field_914_trigger = 5;
|
|
work->field_8E8_pTarget->damaged &= ~(0x40);
|
|
work->field_8E8_pTarget = 0;
|
|
}
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
}
|
|
}
|
|
|
|
void sna_80057378(SnaInitWork *work, int time)
|
|
{
|
|
int action;
|
|
int stance;
|
|
|
|
stance = work->field_A26_stance;
|
|
work->control.turn.vy = dword_800ABBA8;
|
|
|
|
if (time == 0)
|
|
{
|
|
if (stance == 0)
|
|
{
|
|
action = work->actpack->attack->field_6;
|
|
}
|
|
else
|
|
{
|
|
action = work->actpack->attack->field_7;
|
|
}
|
|
|
|
sna_8004E260(work, action, 4, 0xffff);
|
|
}
|
|
|
|
if ((stance == SNA_STANCE_STANDING && time == 6) || (stance == SNA_STANCE_SQUAT && time == 14))
|
|
{
|
|
work->field_914_trigger = 3;
|
|
GM_BombSeg = dword_800ABBB0;
|
|
}
|
|
|
|
if (work->body.time2 != 0 || work->body.action2 == 0)
|
|
{
|
|
sna_8004E260(work, 0, 4, 0);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK9);
|
|
work->field_9C0 = NULL;
|
|
}
|
|
}
|
|
|
|
void sna_anim_claymore_80057474(SnaInitWork *work, int time)
|
|
{
|
|
int i;
|
|
int down_count;
|
|
TARGET *targets;
|
|
|
|
if (time == 0)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
GM_Target_8002E374(&down_count, &targets);
|
|
|
|
if (counter_8009F448 == 8 || down_count == 64)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
GM_SeSet2(0, 63, SE_BUZZER);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
return;
|
|
}
|
|
|
|
work->field_9C8_anim_update_fn_3p = sna_anim_claymore_helper_80058780;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
SetAction_8004E22C(work, SET, 4);
|
|
|
|
for (i = 0; i < SNAKEJOINT_NUM; i++)
|
|
{
|
|
work->adjust[i] = DG_ZeroVector;
|
|
}
|
|
|
|
GM_ConfigMotionAdjust(&work->body, work->adjust);
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK26);
|
|
}
|
|
|
|
sub_8004E9D0(work);
|
|
}
|
|
|
|
static inline int sna_anim_shoot_weapon_helper_helper_80057590(SnaInitWork *work)
|
|
{
|
|
if ((work->actpack->attack->setup == 136) ||
|
|
(work->field_90C_pWeaponFn == &sna_80057A90))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
void sna_anim_shoot_weapon_helper_80057590(SnaInitWork *work, int time)
|
|
{
|
|
unsigned short status;
|
|
int diff;
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_ATTACK))
|
|
{
|
|
sna_8004E260(work, 0, 4, 0);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_idle_8005275C);
|
|
return;
|
|
}
|
|
|
|
if (gSnaMoveDir_800ABBA4 < 0)
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->still->setup, 4);
|
|
return;
|
|
}
|
|
|
|
status = work->field_9B0_pad_ptr->status;
|
|
|
|
if ((sub_8004E458(work->control.turn.vy, gSnaMoveDir_800ABBA4) == 3) &&
|
|
sna_anim_shoot_weapon_helper_helper_80057590(work))
|
|
{
|
|
work->field_A54.prone_bool_thing = gSnaMoveDir_800ABBA4;
|
|
sna_start_anim_8004E1F4(work, &sub_80053FAC);
|
|
}
|
|
else if ((status & PAD_CROSS) || (work->field_920_tbl & 8))
|
|
{
|
|
if (work->field_A38_local_data > 0)
|
|
{
|
|
work->field_A38_local_data--;
|
|
}
|
|
|
|
if (work->field_A38_local_data == 0)
|
|
{
|
|
diff = GV_DiffDirAbs(work->control.turn.vy, gSnaMoveDir_800ABBA4);
|
|
if (diff > 256)
|
|
{
|
|
work->field_A38_local_data = (diff / 1024) + 1;
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_rungun_begin_80056BDC);
|
|
}
|
|
|
|
work->control.turn.vy = gSnaMoveDir_800ABBA4;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sna_8004EF14(work);
|
|
}
|
|
}
|
|
|
|
void sna_anim_rungun_begin_helper_800577B4(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 2 && gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_rungun_80056C3C);
|
|
}
|
|
else
|
|
{
|
|
if (work->body.is_end)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, sna_anim_shoot_weapon_80056B88);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_anim_rungun_helper_80057844(SnaInitWork *work, int time)
|
|
{
|
|
int angle;
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_ATTACK))
|
|
{
|
|
sna_8004E260(work, 0, 4, 0);
|
|
sna_start_anim_8004E1F4(work, sna_anim_run_8005292C);
|
|
return;
|
|
}
|
|
|
|
if (gSnaMoveDir_800ABBA4 < 0 || (!(work->field_920_tbl & 8) && !(work->field_9B0_pad_ptr->status & PAD_CROSS)))
|
|
{
|
|
if (++work->field_A3A >= 5)
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, sna_anim_shoot_weapon_80056B88);
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
work->field_A3A = 0;
|
|
}
|
|
|
|
if (gSnaMoveDir_800ABBA4 < 0)
|
|
{
|
|
angle = work->control.turn.vy;
|
|
}
|
|
else
|
|
{
|
|
angle = sub_8004E4C0(work, gSnaMoveDir_800ABBA4);
|
|
}
|
|
|
|
work->control.turn.vy = angle;
|
|
sub_8004EA50(work, angle);
|
|
}
|
|
|
|
void sna_auto_aim_800579A0(SnaInitWork *work)
|
|
{
|
|
int unk;
|
|
int out_x_copy;
|
|
int snake_not_moving;
|
|
int out_x;
|
|
int out_y;
|
|
int diff;
|
|
|
|
// loops enemies and finds candidate to aim at, returns angle to auto turn/aim to
|
|
// melee also uses this in a different func
|
|
GM_GetHomingTarget2(&work->body.objs->objs[6].world,
|
|
work->control.rot.vy, // input snake horizontal facing angle
|
|
&out_y, &out_x, work->control.map->index,
|
|
work->field_890_autoaim_max_dist,
|
|
work->field_892_autoaim_min_angle); // min angle to activate auto aim
|
|
|
|
// ?
|
|
unk = work->adjust[2].vx;
|
|
diff = unk - out_x;
|
|
if (diff >= 65)
|
|
{
|
|
out_x = unk - 64;
|
|
}
|
|
else if (diff < -64)
|
|
{
|
|
out_x = unk + 64;
|
|
}
|
|
|
|
// ?
|
|
out_x_copy = out_x;
|
|
work->adjust[2].vx = out_x;
|
|
work->adjust[6].vx = out_x;
|
|
snake_not_moving = gSnaMoveDir_800ABBA4 < 0;
|
|
work->adjust[7].vx = 3 * out_x_copy / 2; // maybe aim gun/head up/down??
|
|
|
|
if (snake_not_moving && out_y >= 0) // if not moving, set snake turn angle
|
|
{
|
|
work->control.turn.vy = out_y;
|
|
}
|
|
}
|
|
|
|
void sna_80057A90(SnaInitWork *work, int time)
|
|
{
|
|
int bits;
|
|
int ammo, magSize;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_MOVE))
|
|
{
|
|
bits = 0x3fe;
|
|
}
|
|
else
|
|
{
|
|
bits = 0xffff;
|
|
}
|
|
|
|
if (time == 0)
|
|
{
|
|
GM_ConfigMotionAdjust(&work->body, NULL);
|
|
NewAnime_8005DDE0(&work->body.objs->objs[4].world);
|
|
sna_8004E260(work, work->actpack->attack->reload, 4, bits);
|
|
|
|
ammo = GM_MagazineMax;
|
|
magSize = GM_Weapons[work->field_91C_weapon_idx];
|
|
|
|
if (ammo > 0 && ammo < magSize)
|
|
{
|
|
magSize = ammo;
|
|
}
|
|
|
|
GM_MagazineMax = ammo;
|
|
GM_Magazine = magSize;
|
|
}
|
|
|
|
sna_8004F034(work, bits);
|
|
|
|
if (time == 16)
|
|
{
|
|
GM_SeSet(&work->control.mov, SE_RELOAD);
|
|
}
|
|
|
|
if (work->body.time2 != 0)
|
|
{
|
|
if (!(work->field_9B0_pad_ptr->status & PAD_SQUARE))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_ATTACK);
|
|
sna_8004E260(work, 0, 4, 0);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_idle_8005275C);
|
|
work->field_90C_pWeaponFn = sna_gun_800540D0;
|
|
}
|
|
else
|
|
{
|
|
work->field_90C_pWeaponFn = sub_80057BF0;
|
|
}
|
|
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
}
|
|
}
|
|
|
|
void sub_80057BF0(SnaInitWork *work, int time)
|
|
{
|
|
int var_s4;
|
|
int temp_s3;
|
|
int var_s2;
|
|
int status;
|
|
int release;
|
|
int trg;
|
|
|
|
var_s4 = GM_CheckPlayerStatusFlag(PLAYER_MOVE) ? 0x3FE : 0xFFFF;
|
|
temp_s3 = work->field_920_tbl;
|
|
var_s2 = 0;
|
|
|
|
if (time == 0)
|
|
{
|
|
sna_8004E260(work, SET, 4, var_s4);
|
|
GM_SeSet(&work->control.mov, SE_READY_WEAPON);
|
|
|
|
var_s2 = work->field_A38_local_data;
|
|
work->field_924 = 0;
|
|
|
|
if (temp_s3 & 2)
|
|
{
|
|
GM_ConfigMotionAdjust(&work->body, work->adjust);
|
|
}
|
|
}
|
|
|
|
sna_8004F034(work, var_s4);
|
|
|
|
if ( (GM_Magazine == 0) && (GM_MagazineMax != 0) && (GM_Weapons[work->field_91C_weapon_idx] > 0) )
|
|
{
|
|
work->field_90C_pWeaponFn = &sna_80057A90;
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
return;
|
|
}
|
|
|
|
if ( (temp_s3 & 2) != 0 )
|
|
{
|
|
sna_auto_aim_800579A0(work);
|
|
}
|
|
|
|
status = work->field_9B0_pad_ptr->status;
|
|
release = work->field_9B0_pad_ptr->release;
|
|
|
|
trg = 1;
|
|
|
|
if ( (temp_s3 & 1) ? (status & PAD_SQUARE) : (release & PAD_SQUARE) )
|
|
{
|
|
var_s2 = 1;
|
|
}
|
|
|
|
if ( (GM_GameStatus & STATE_PADRELEASE) ||
|
|
GM_CheckPlayerStatusFlag(PLAYER_PAD_OFF) ||
|
|
(DG_UnDrawFrameCount > 0) )
|
|
{
|
|
var_s2 = 0;
|
|
}
|
|
|
|
if ( var_s2 != 0 )
|
|
{
|
|
trg |= 2;
|
|
}
|
|
|
|
work->field_914_trigger = trg;
|
|
|
|
switch ( work->field_924 )
|
|
{
|
|
case 0:
|
|
if ( trg & 2 )
|
|
{
|
|
if ( *work->field_918_n_bullets == 0 )
|
|
{
|
|
DispEmpty(work);
|
|
|
|
if ( temp_s3 & 1 )
|
|
{
|
|
work->field_924 = 2;
|
|
break;
|
|
}
|
|
}
|
|
|
|
work->field_924 = 1;
|
|
sna_8004E260(work, work->actpack->attack->shoot, 2, var_s4);
|
|
|
|
if ( temp_s3 & 0x80 )
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_ATTACK | PLAYER_MOVE);
|
|
|
|
if ( dword_8009F470 != 0 )
|
|
{
|
|
GM_SeSet2(0, 63, SE_BUZZER);
|
|
work->field_914_trigger &= ~2;
|
|
sna_8004E260(work, 0, 4, 0);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_idle_8005275C);
|
|
}
|
|
else
|
|
{
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK3);
|
|
GM_SetPlayerStatusFlag(PLAYER_ITEM_DISABLE);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_nikita_80056C9C);
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
if ( work->body.time2 != 0 )
|
|
{
|
|
if ( (temp_s3 & 1) == 0 )
|
|
{
|
|
work->field_924 = 0;
|
|
sna_8004E260(work, SET, 2, var_s4);
|
|
}
|
|
else if ( *work->field_918_n_bullets == 0 )
|
|
{
|
|
DispEmpty(work);
|
|
work->field_924 = 2;
|
|
sna_8004E260(work, SET, 2, var_s4);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 2:
|
|
work->field_914_trigger = trg & ~2;
|
|
break;
|
|
}
|
|
|
|
if ( (status & 0x80) == 0 )
|
|
{
|
|
if ( (++work->field_926 > 4) || (temp_s3 & 1) )
|
|
{
|
|
work->field_90C_pWeaponFn = &sna_gun_800540D0;
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
|
|
GM_ConfigMotionAdjust(&work->body, NULL);
|
|
GM_ClearPlayerStatusFlag(PLAYER_ATTACK);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
work->field_926 = 0;
|
|
}
|
|
}
|
|
|
|
void sna_anim_psg1_helper_80057FD4(SnaInitWork* work, int time)
|
|
{
|
|
int trg;
|
|
int ammo;
|
|
int mag_size;
|
|
short dpad_status;
|
|
int val;
|
|
short *pShortArr;
|
|
int rx, ry;
|
|
|
|
if ( work->field_A3A < 3 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
trg = 1;
|
|
|
|
if ( work->field_A34 != 0 )
|
|
{
|
|
if ( (--work->field_A34 & 0xFF) != 4 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
GM_SeSet(&work->control.mov, SE_RELOAD);
|
|
|
|
ammo = GM_Weapons[WP_Rifle];
|
|
mag_size = 5;
|
|
|
|
if ( mag_size < ammo )
|
|
{
|
|
ammo = mag_size;
|
|
}
|
|
|
|
GM_MagazineMax = mag_size;
|
|
GM_Magazine = ammo;
|
|
}
|
|
|
|
if ( (GM_Magazine == 0) && (GM_Weapons[WP_Rifle] > 0) )
|
|
{
|
|
work->field_A34 = 24;
|
|
return;
|
|
}
|
|
|
|
if ( (work->field_9B0_pad_ptr->release & PAD_SQUARE) &&
|
|
!(GM_GameStatus & STATE_PADRELEASE) &&
|
|
!GM_CheckPlayerStatusFlag(PLAYER_PAD_OFF) &&
|
|
(DG_UnDrawFrameCount == 0) )
|
|
{
|
|
trg |= 2;
|
|
|
|
if ( *work->field_918_n_bullets == 0 )
|
|
{
|
|
DispEmpty(work);
|
|
}
|
|
}
|
|
|
|
work->field_914_trigger = trg;
|
|
|
|
dpad_status = work->field_9B0_pad_ptr->status & (PAD_LEFT | PAD_DOWN | PAD_RIGHT | PAD_UP);
|
|
if ( dpad_status != 0 )
|
|
{
|
|
val = 1;
|
|
|
|
if ( work->field_A52 == dpad_status )
|
|
{
|
|
if ( !sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK15) )
|
|
{
|
|
if ( work->field_A44.pad < 10000 )
|
|
{
|
|
work->field_A44.pad++;
|
|
}
|
|
|
|
if ( work->field_A44.pad > 16 )
|
|
{
|
|
val = 3;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
val = 3;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
work->field_A44.pad = 0;
|
|
work->field_A52 = dpad_status;
|
|
}
|
|
|
|
pShortArr = work->field_9D0;
|
|
pShortArr[0] = 1;
|
|
pShortArr[3] = 0x78;
|
|
pShortArr[4] = 0x78;
|
|
pShortArr[5] = val;
|
|
pShortArr[6] = val;
|
|
pShortArr[7] = val;
|
|
pShortArr[8] = val;
|
|
|
|
sna_80051DA0(work);
|
|
sna_80051FD0(work);
|
|
sna_8004EB14(work);
|
|
}
|
|
else
|
|
{
|
|
work->field_A52 = 0;
|
|
work->field_A44.pad = 0;
|
|
}
|
|
|
|
rx = work->body.objs->rots[0].vx;
|
|
ry = work->body.objs->rots[0].vy;
|
|
|
|
if ( GetAction(work) == 0x7A )
|
|
{
|
|
work->control.turn.vy += ry - work->field_924;
|
|
work->control.turn.vx += rx - work->field_926;
|
|
}
|
|
|
|
work->field_924 = ry;
|
|
work->field_926 = rx;
|
|
|
|
if ( GM_TranquilizerTimer > 0 )
|
|
{
|
|
if ( (time % 48) == 0 )
|
|
{
|
|
NewPadVibration(dword_8009EF20, 2);
|
|
work->field_A35_vibtime2 = 2;
|
|
}
|
|
else if ( (work->field_A35_vibtime2 != 0) &&
|
|
(--work->field_A35_vibtime2 == 0) )
|
|
{
|
|
GM_SeSet2(0, 63, SE_HEARTBEAT);
|
|
}
|
|
}
|
|
else if ( (time & 0x1F) == 0 )
|
|
{
|
|
NewPadVibration(dword_8009EF1C, 2);
|
|
work->field_A35_vibtime2 = 2;
|
|
}
|
|
else if ( (work->field_A35_vibtime2 > 0) &&
|
|
(--work->field_A35_vibtime2 == 0) )
|
|
{
|
|
GM_SeSet2(0, 63, SE_HEARTBEAT);
|
|
}
|
|
|
|
if ( GetAction(work) == SET )
|
|
{
|
|
if ( ++work->field_A38_local_data == RIFLE_TEBURE_TIME )
|
|
{
|
|
work->field_A38_local_data = 0;
|
|
|
|
if ( GM_TranquilizerTimer <= 0 )
|
|
{
|
|
GM_StatusEvent &= ~EV_Tranquilizer;
|
|
SetAction_8004E22C(work, TEBURE, 4);
|
|
}
|
|
}
|
|
}
|
|
else if ( EndMotion(work) ||
|
|
(GM_StatusEvent & EV_Tranquilizer) )
|
|
{
|
|
SetAction_8004E22C(work, SET, 4);
|
|
}
|
|
}
|
|
|
|
STATIC void OP_ShootStinger(SnaInitWork *work, int time)
|
|
{
|
|
short *ws; // WATCH_SET *ws
|
|
int trg;
|
|
|
|
trg = 1; // 1 = WEAPON_TAKE
|
|
|
|
if ((work->field_9B0_pad_ptr->release & PAD_SQUARE) &&
|
|
!(GM_GameStatus & STATE_PADRELEASE) &&
|
|
!GM_CheckPlayerStatusFlag(PLAYER_PAD_OFF))
|
|
{
|
|
if ( *work->field_918_n_bullets > 0 )
|
|
{
|
|
trg |= 2; // |= WEAPON_TRIG
|
|
}
|
|
else
|
|
{
|
|
GM_SeSet(&work->control.mov, SE_KARASHT);
|
|
DispEmpty(work);
|
|
}
|
|
}
|
|
|
|
work->field_914_trigger = trg;
|
|
|
|
if ( work->field_9B0_pad_ptr->status & (PAD_LEFT | PAD_DOWN | PAD_RIGHT | PAD_UP) )
|
|
{
|
|
ws = work->field_9D0;
|
|
ws[0] = 1; // ws->type = WATCH_TYPE_STILL
|
|
ws[3] = 0x200;
|
|
ws[4] = 0x200;
|
|
ws[5] = 0x20;
|
|
ws[6] = 0x20;
|
|
ws[7] = 0x20;
|
|
ws[8] = 0x20;
|
|
|
|
sna_80051DA0(work);
|
|
sna_80051FD0(work);
|
|
sna_8004EB14(work);
|
|
}
|
|
}
|
|
|
|
void sna_anim_grenade_80058470(SnaInitWork *work, int time)
|
|
{
|
|
int bits;
|
|
int uVar2;
|
|
int res;
|
|
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_MOVE) )
|
|
{
|
|
bits = 0x3fe;
|
|
}
|
|
else
|
|
{
|
|
bits = 0xffff;
|
|
}
|
|
|
|
if (time == 0)
|
|
{
|
|
sna_8004E260(work, SET, 4, bits);
|
|
work->field_924 = 0;
|
|
GM_SeSet(&(work->control).mov, SE_PINNUKI);
|
|
}
|
|
|
|
sna_8004F034(work, bits);
|
|
res = 1;
|
|
|
|
uVar2 = work->m_ctrl.info2.frame;
|
|
|
|
switch (work->field_924)
|
|
{
|
|
case 0:
|
|
if (work->body.time2 != 0)
|
|
{
|
|
sna_8004E260(work, work->actpack->still->stand, 1, bits);
|
|
work->field_924 = 1;
|
|
}
|
|
|
|
break;
|
|
case 1:
|
|
if (!(work->field_9B0_pad_ptr->status & PAD_SQUARE) && (DG_UnDrawFrameCount == 0))
|
|
{
|
|
sna_8004E260(work, work->actpack->attack->shoot, 1, bits);
|
|
work->field_924 = 2;
|
|
}
|
|
|
|
break;
|
|
case 2:
|
|
if (uVar2 == 7)
|
|
{
|
|
res = 3;
|
|
work->field_924 = 3;
|
|
}
|
|
|
|
break;
|
|
case 3:
|
|
res = 0;
|
|
|
|
if ((uVar2 > 11) && (work->field_9B0_pad_ptr->status & PAD_SQUARE))
|
|
{
|
|
work->field_910 = 0;
|
|
return;
|
|
}
|
|
|
|
|
|
if (work->body.time2 != 0)
|
|
{
|
|
sna_8004E260(work, 0, 4, 0);
|
|
GM_ClearPlayerStatusFlag(PLAYER_ATTACK | PLAYER_ITEM_DISABLE | PLAYER_WEAPON_DISABLE);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
work->field_914_trigger = res;
|
|
}
|
|
|
|
void sub_80058644(SnaInitWork *work, int time)
|
|
{
|
|
int iVar1;
|
|
|
|
work->field_914_trigger = 1;
|
|
|
|
if (time >= 10)
|
|
{
|
|
iVar1 = (int)work->field_A38_local_data;
|
|
if (iVar1 == 0)
|
|
{
|
|
sub_8004EEB0(work);
|
|
}
|
|
|
|
if ((work->field_9B0_pad_ptr->status & PAD_SQUARE) == 0 && iVar1 == 0 && DG_UnDrawFrameCount == 0)
|
|
{
|
|
iVar1 = sub_8004E5E8(work, 0x80);
|
|
if (iVar1 == 1)
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->attack->field_8, 1);
|
|
work->field_A38_local_data = 1;
|
|
work->field_914_trigger |= 2;
|
|
}
|
|
else if (iVar1 == 2)
|
|
{
|
|
GM_SeSet2(0, 0x3f, SE_BUZZER);
|
|
}
|
|
}
|
|
|
|
if ((iVar1 == 1 && EndMotion(work)) || iVar1 == 2)
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_idle_8005275C);
|
|
}
|
|
|
|
work->field_A2C.vy = -100;
|
|
}
|
|
}
|
|
|
|
void sna_anim_claymore_helper_80058780(SnaInitWork *work, int time)
|
|
{
|
|
int var_s1;
|
|
int x, y;
|
|
int w;
|
|
POLY_GT4 *pPoly;
|
|
int i, j;
|
|
|
|
work->field_914_trigger = 1; // 1 = WEAPON_TAKE
|
|
|
|
if ( time < 10 )
|
|
{
|
|
return;
|
|
}
|
|
|
|
var_s1 = work->field_A38_local_data;
|
|
|
|
if ( var_s1 == 0 )
|
|
{
|
|
sub_8004EEB0(work);
|
|
|
|
DG_GroupPrim(work->field_92C, DG_CurrentGroupID);
|
|
DG_VisiblePrim(work->field_92C);
|
|
DG_PutPrim(&work->field_92C->world);
|
|
|
|
if ( !(work->field_9B0_pad_ptr->status & PAD_SQUARE) && (DG_UnDrawFrameCount == 0) )
|
|
{
|
|
var_s1 = sub_8004E5E8(work, 0x40);
|
|
|
|
if ( var_s1 == 1 )
|
|
{
|
|
SetAction_8004E22C(work, work->actpack->attack->shoot, 1);
|
|
work->field_A38_local_data = 1;
|
|
work->field_914_trigger |= 2; // 2 = WEAPON_TRIG
|
|
}
|
|
else if ( var_s1 == 2 )
|
|
{
|
|
GM_SeSet2(0, 63, SE_BUZZER);
|
|
}
|
|
}
|
|
}
|
|
|
|
y = GV_Time & 63;
|
|
|
|
if ( y > 32 )
|
|
{
|
|
y = 64 - y;
|
|
}
|
|
|
|
x = work->field_928->off_x;
|
|
w = x + 63;
|
|
y += work->field_928->off_y;
|
|
|
|
pPoly = &work->field_92C->packs[GV_Clock]->poly_gt4;
|
|
|
|
for ( i = 0; i < 2; i++ )
|
|
{
|
|
pPoly->u0 = x;
|
|
pPoly->v0 = y;
|
|
pPoly->u1 = w;
|
|
pPoly->v1 = y;
|
|
pPoly->u2 = x;
|
|
pPoly->v2 = y;
|
|
pPoly->u3 = w;
|
|
pPoly->v3 = y;
|
|
pPoly++;
|
|
}
|
|
|
|
if ( ((var_s1 == 1) && (EndMotion(work))) || (var_s1 == 2) )
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK26 | SNA_FLAG1_UNK3);
|
|
DG_InvisiblePrim(work->field_92C);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_idle_8005275C);
|
|
GM_ConfigMotionAdjust(&work->body, NULL);
|
|
|
|
for ( j = 0; j < 16; j++ )
|
|
{
|
|
work->adjust[j] = DG_ZeroVector;
|
|
}
|
|
}
|
|
|
|
work->field_A2C.vy = -100;
|
|
}
|
|
|
|
void sna_anim_throw_800589C8(SnaInitWork *work, int time)
|
|
{
|
|
Target_Data *pVec; // $s3
|
|
int bClear; // $s4
|
|
ACTPACK *actpack; // $v1
|
|
int action_flag; // $s0
|
|
TARGET *field_8E8_pTarget; // $s0
|
|
SVECTOR* pTmp;
|
|
|
|
if ( time == 0)
|
|
{
|
|
pVec = &stru_8009EFE4[1];
|
|
bClear = 0;
|
|
actpack = work->actpack;
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
action_flag = actpack->attack->shoot;
|
|
if ( !sna_8004FDE8(work, pVec) )
|
|
{
|
|
action_flag = work->actpack->attack->field_5;
|
|
pVec = &stru_8009EFE4[2];
|
|
|
|
if ( !sna_8004FDE8(work, pVec) )
|
|
{
|
|
bClear = 1;
|
|
work->field_A38_local_data = 1;
|
|
action_flag = work->actpack->still->setup;
|
|
}
|
|
}
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
|
|
work->field_8FC = work->control.rot;
|
|
work->field_8FC.vy += 2048;
|
|
|
|
pTmp = &work->field_8EC_vec;
|
|
if ( !bClear )
|
|
{
|
|
field_8E8_pTarget = work->field_8E8_pTarget;
|
|
DG_PutVector(&pVec->field_0, pTmp, 1);
|
|
GV_SubVec3(&field_8E8_pTarget->center, pTmp, pTmp);
|
|
pTmp->vx /= 4;
|
|
pTmp->vy /= 4;
|
|
pTmp->vz /= 4;
|
|
}
|
|
else
|
|
{
|
|
|
|
*pTmp = DG_ZeroVector;
|
|
}
|
|
}
|
|
|
|
if ( time < 4 )
|
|
{
|
|
GV_AddVec3(
|
|
&work->control.step,
|
|
&work->field_8EC_vec,
|
|
&work->control.step);
|
|
}
|
|
|
|
if ( work->body.is_end || (work->field_A38_local_data == 1 && time == 4) )
|
|
{
|
|
sna_sub_8004E41C(work, 2);
|
|
sna_clear_flags1_8004E308(work, 4);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
}
|
|
|
|
}
|
|
|
|
void sna_anim_punch_80058C10(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_anim_punch_helper_800591F4;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
SetAction_8004E22C(work, work->actpack->attack->punch, 1);
|
|
work->field_A38_local_data = 0;
|
|
sna_set_flags1_8004E2F4(work, (SNA_FLAG1_UNK5 | SNA_FLAG1_UNK6));
|
|
}
|
|
}
|
|
|
|
void sna_anim_chokethrow_begin2_80058C80(SnaInitWork *work, int time)
|
|
{
|
|
int bClear; // $s0
|
|
TARGET *field_8E8_pTarget; // $v1
|
|
int action_flag; // $a1
|
|
SVECTOR *p;
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_904_frames_last_choke = 0;
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
bClear = 0;
|
|
work->field_A54.choke_count = 0;
|
|
|
|
if (!sna_8004FDE8(work, &stru_8009EFE4[3]))
|
|
{
|
|
bClear = 1;
|
|
work->field_A38_local_data = 1;
|
|
}
|
|
|
|
p = &work->field_8EC_vec;
|
|
if (!bClear)
|
|
{
|
|
|
|
field_8E8_pTarget = work->field_8E8_pTarget;
|
|
|
|
field_8E8_pTarget->faint--;
|
|
|
|
DG_SetPos2(&field_8E8_pTarget->center, &work->control.rot);
|
|
|
|
DG_PutVector(&svector_800AB7FC, p, 1);
|
|
DG_SetPos2(&work->control.mov, &work->control.rot);
|
|
GV_SubVec3(p, &work->control.mov, p);
|
|
p->vx /= 4;
|
|
p->vy /= 4;
|
|
p->vz /= 4;
|
|
action_flag = work->actpack->special2->field_0;
|
|
}
|
|
else
|
|
{
|
|
work->field_8EC_vec = DG_ZeroVector;
|
|
action_flag = work->actpack->still->setup;
|
|
}
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
}
|
|
|
|
if (time < 4)
|
|
{
|
|
++work->field_904_frames_last_choke;
|
|
GV_AddVec3(&work->control.step, &work->field_8EC_vec,
|
|
&work->control.step);
|
|
}
|
|
else
|
|
{
|
|
if (work->field_A38_local_data)
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
}
|
|
else
|
|
{
|
|
work->field_89C_pTarget->size.vx = 150;
|
|
sna_start_anim_8004E1F4(work, sna_anim_choke_80058E88);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_anim_choke_80058E88(SnaInitWork *work, int time)
|
|
{
|
|
short action_flag; // $s0
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_anim_choke_helper_8005951C;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
|
|
action_flag = work->actpack->special2->field_0;
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
work->field_8E8_pTarget->a_mode = action_flag;
|
|
}
|
|
}
|
|
|
|
void sna_anim_choke_rechoke_80058EF4(SnaInitWork *work, int time)
|
|
{
|
|
short bVar1;
|
|
|
|
if (time == 0 || (work->field_9B0_pad_ptr->press & PAD_SQUARE) != 0)
|
|
{
|
|
GetAction(work) = -1;
|
|
work->field_9C8_anim_update_fn_3p = sna_anim_choke_rechoke_helper_8005961C;
|
|
work->field_904_frames_last_choke = 0;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
bVar1 = work->actpack->attack->field_6;
|
|
SetAction_8004E22C(work, bVar1, 4);
|
|
work->field_8E8_pTarget->a_mode = bVar1;
|
|
}
|
|
}
|
|
|
|
void sna_anim_choke_kill_80058F88(SnaInitWork *work, int time)
|
|
{
|
|
TARGET *field_8E8_pTarget; // $s0
|
|
int action_flag; // $s1
|
|
|
|
if (time == 0)
|
|
{
|
|
field_8E8_pTarget = work->field_8E8_pTarget;
|
|
action_flag = work->actpack->attack->field_7;
|
|
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
|
|
SetAction_8004E22C(work, action_flag, 4);
|
|
|
|
field_8E8_pTarget->a_mode = action_flag;
|
|
field_8E8_pTarget->life_lost = 5;
|
|
field_8E8_pTarget->faint--;
|
|
work->field_A54.choke_count = 0;
|
|
}
|
|
|
|
if (work->body.is_end)
|
|
{
|
|
sna_sub_8004E41C(work, 2);
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
}
|
|
}
|
|
|
|
void sna_anim_choke_drag_80059054(SnaInitWork *work, int time)
|
|
{
|
|
int bVar2;
|
|
int iVar3;
|
|
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
bVar2 = work->actpack->special2->field_1;
|
|
GM_SetPlayerStatusFlag(PLAYER_MOVE);
|
|
SetAction_8004E22C(work, bVar2, 4);
|
|
work->field_8E8_pTarget->a_mode = bVar2;
|
|
}
|
|
|
|
iVar3 = work->field_904_frames_last_choke + 1;
|
|
work->field_904_frames_last_choke = iVar3;
|
|
|
|
if ((gSnaMoveDir_800ABBA4 < 0 || ((work->field_9B0_pad_ptr->status & PAD_SQUARE) == 0)))
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, sna_anim_choke_80058E88);
|
|
}
|
|
else
|
|
{
|
|
if (!((work->field_8E8_pTarget->life > 0) &&
|
|
((iVar3 < 0x5a && work->field_8E8_pTarget->captured != 0))))
|
|
{
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_MOVE);
|
|
sna_start_anim_8004E1F4(work, sna_anim_choke_80058E88);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
work->control.turn.vy = gSnaMoveDir_800ABBA4 + 0x800;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_anim_choke_hold_80059154(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0)
|
|
{
|
|
work->field_9C8_anim_update_fn_3p = sna_fn_nothing_80053B80;
|
|
work->field_9CC_anim_update_fn_1p = sna_fn_nothing_80053B80;
|
|
SetAction_8004E22C(work, work->actpack->special2->field_6, 4);
|
|
}
|
|
|
|
if (EndMotion(work))
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
}
|
|
}
|
|
|
|
void sub_800591BC(SnaInitWork *work)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_idle_8005275C);
|
|
sna_clear_flags1_8004E308(work, (SNA_FLAG1_UNK3 | SNA_FLAG1_UNK5 | SNA_FLAG1_UNK6));
|
|
}
|
|
|
|
void sna_anim_punch_helper_800591F4(SnaInitWork *work, int time)
|
|
{
|
|
int x, y;
|
|
int sound;
|
|
|
|
if ( time == 0 )
|
|
{
|
|
GM_GetHomingTarget2(&work->body.objs->objs[6].world,
|
|
work->control.rot.vy,
|
|
&x, &y, work->control.map->index,
|
|
2000, 1024);
|
|
|
|
if ( x >= 0 )
|
|
{
|
|
work->control.turn.vy = x;
|
|
}
|
|
}
|
|
|
|
if ( time == 4 )
|
|
{
|
|
sub_8004FCB8(work, &punch_info[0], 3);
|
|
|
|
sound = SE_PUNCH_SWING;
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) )
|
|
{
|
|
sound = 182;
|
|
}
|
|
|
|
GM_SeSet(&work->control.mov, sound);
|
|
GM_SetNoise(time, 2, &work->control.mov);
|
|
}
|
|
|
|
if ( time == 6 )
|
|
{
|
|
if ( !(work->field_A38_local_data & 0x20) )
|
|
{
|
|
sub_800591BC(work);
|
|
return;
|
|
}
|
|
|
|
work->field_A38_local_data &= ~0x20;
|
|
}
|
|
|
|
if ( time == 11 )
|
|
{
|
|
sub_8004FCB8(work, &punch_info[1], 3);
|
|
|
|
sound = SE_PUNCH_SWING;
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) )
|
|
{
|
|
sound = 182;
|
|
}
|
|
|
|
GM_SeSet(&work->control.mov, sound);
|
|
GM_SetNoise(4, 2, &work->control.mov);
|
|
}
|
|
|
|
if ( time == 13 )
|
|
{
|
|
if ( !(work->field_A38_local_data & 0x20) )
|
|
{
|
|
sub_800591BC(work);
|
|
return;
|
|
}
|
|
|
|
work->field_A38_local_data = 0;
|
|
}
|
|
|
|
if ( time == 22 )
|
|
{
|
|
sub_8004FCB8(work, &punch_info[2], 4);
|
|
|
|
sound = SE_KICK_SWING;
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_IN_THE_WATER) )
|
|
{
|
|
sound = 182;
|
|
}
|
|
|
|
GM_SeSet(&work->control.mov, sound);
|
|
GM_SetNoise(4, 2, &work->control.mov);
|
|
}
|
|
|
|
if ( EndMotion(work) )
|
|
{
|
|
sub_800591BC(work);
|
|
return;
|
|
}
|
|
|
|
work->field_A38_local_data |= work->field_9B0_pad_ptr->press;
|
|
|
|
if ( (work->field_9B0_pad_ptr->press & PAD_CROSS) != 0 )
|
|
{
|
|
sub_800591BC(work);
|
|
}
|
|
}
|
|
|
|
void sna_anim_choke_helper_8005951C(SnaInitWork *work, int time)
|
|
{
|
|
int sinceLastChoke;
|
|
short press;
|
|
short status;
|
|
|
|
sinceLastChoke = ++work->field_904_frames_last_choke;
|
|
|
|
if (((work->field_8E8_pTarget->life < 1 || sinceLastChoke >= 90) ||
|
|
work->field_8E8_pTarget->captured == 0))
|
|
{
|
|
sna_sub_8004E41C(work, 2);
|
|
sna_start_anim_8004E1F4(work, sna_anim_choke_hold_80059154);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
return;
|
|
}
|
|
|
|
press = work->field_9B0_pad_ptr->press;
|
|
status = work->field_9B0_pad_ptr->status;
|
|
|
|
if ((press & PAD_SQUARE) != 0)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_choke_rechoke_80058EF4);
|
|
}
|
|
else if ((status & PAD_SQUARE) == 0)
|
|
{
|
|
// A38 is snake stop movement frames, counts down
|
|
if (++work->field_A38_local_data >= 9)
|
|
{
|
|
sna_sub_8004E41C(work, 2);
|
|
sna_start_anim_8004E1F4(work, sna_anim_choke_hold_80059154);
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK3);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
work->field_A38_local_data = 0;
|
|
if (gSnaMoveDir_800ABBA4 >= 0)
|
|
{
|
|
sna_start_anim_8004E1F4(work, sna_anim_choke_drag_80059054);
|
|
}
|
|
}
|
|
}
|
|
|
|
void sna_anim_choke_rechoke_helper_8005961C(SnaInitWork *work, int time)
|
|
{
|
|
if (time == 0 || (work->field_9B0_pad_ptr->press & PAD_SQUARE) != 0)
|
|
{
|
|
work->field_8E8_pTarget->faint--;
|
|
|
|
if (++work->field_A54.choke_count >= 10) // feels good
|
|
{
|
|
// TODO: fix data when vibrate is figured out
|
|
NewPadVibration(dword_8009EF24, 1);
|
|
NewPadVibration(dword_8009EF2C, 2);
|
|
sna_start_anim_8004E1F4(work, sna_anim_choke_kill_80058F88);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (work->body.is_end == 0 && work->field_8E8_pTarget->captured != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
sna_start_anim_8004E1F4(work, sna_anim_choke_80058E88);
|
|
}
|
|
|
|
static inline int sna_init_main_logic_helper_helper_helper_800596FC(RECT *a, RECT *b)
|
|
{
|
|
int test1;
|
|
int test2;
|
|
|
|
test1 = a->x * b->x + a->y * b->y;
|
|
test2 = test1;
|
|
|
|
if (test1 < 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
if (test2 > a->x * a->x + a->y * a->y)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline int sna_init_main_logic_helper_helper_800596FC(SnaInitWork *work)
|
|
{
|
|
HZD_FLR *local_40[2];
|
|
RECT rect[2]; // Maybe vecs
|
|
CONTROL *pCtrl;
|
|
SVECTOR *pPosition;
|
|
HZD_FLR *floor;
|
|
int iVar9;
|
|
int iVar10;
|
|
int iVar17;
|
|
int iVar19;
|
|
int iVar11;
|
|
int i;
|
|
int result;
|
|
char *pChk;
|
|
|
|
result = -1;
|
|
pCtrl = &work->control;
|
|
pPosition = &pCtrl->mov;
|
|
|
|
if (pCtrl->touch_flag == 1)
|
|
{
|
|
if (!(pCtrl->nearflags[0] & 0x40))
|
|
{
|
|
floor = pCtrl->nears[0];
|
|
|
|
rect[1].x = pPosition->vx - floor->b1.x;
|
|
rect[1].y = pPosition->vz - floor->b1.z;
|
|
rect[0].x = floor->b2.x - floor->b1.x;
|
|
rect[0].y = floor->b2.z - floor->b1.z;
|
|
|
|
if (!sna_init_main_logic_helper_helper_helper_800596FC(&rect[0], &rect[1]))
|
|
{
|
|
result = 0;
|
|
work->field_79C = 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pChk = work->control.nearflags;
|
|
iVar9 = 0;
|
|
|
|
for (i = 0; i < 2; i++, pChk++)
|
|
{
|
|
floor = pCtrl->nears[i];
|
|
local_40[i] = floor;
|
|
|
|
if (*pChk & 0x40)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
rect[1].x = pPosition->vx - floor->b1.x;
|
|
rect[1].y = pPosition->vz - floor->b1.z;
|
|
rect[0].x = floor->b2.x - floor->b1.x;
|
|
rect[0].y = floor->b2.z - floor->b1.z;
|
|
|
|
if (!sna_init_main_logic_helper_helper_helper_800596FC(&rect[0], &rect[1]))
|
|
{
|
|
result = i;
|
|
iVar9++;
|
|
work->field_79C = 1;
|
|
}
|
|
}
|
|
|
|
if (iVar9 >= 2)
|
|
{
|
|
iVar11 = GV_VecLen3(&pCtrl->nearvecs[0]);
|
|
iVar10 = GV_VecLen3(&pCtrl->nearvecs[1]);
|
|
iVar17 = GV_VecDir2(&pCtrl->nearvecs[0]);
|
|
iVar19 = GV_VecDir2(&pCtrl->nearvecs[1]);
|
|
|
|
if (GV_DiffDirAbs(iVar17, iVar19) < 512)
|
|
{
|
|
work->field_79C = 1;
|
|
result = iVar11;
|
|
return result >= iVar10;
|
|
}
|
|
|
|
work->field_79C = 2;
|
|
result = 2;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
static inline void sna_init_main_logic_helper_800596FC(SnaInitWork *work)
|
|
{
|
|
int dir;
|
|
signed char cVar4;
|
|
int iVar9;
|
|
int iVar10;
|
|
int result;
|
|
int diff;
|
|
|
|
gSnaMoveDir_800ABBA4 = work->field_9B0_pad_ptr->dir;
|
|
pVec_800ABBC8 = pVec_800ABBCC;
|
|
dword_800ABBAC = 0;
|
|
dword_800ABBC4 = 0;
|
|
dword_800ABBB0 = 0;
|
|
pVec_800ABBCC = 0;
|
|
dword_800ABBA8 = -1;
|
|
dword_800ABBD0 = -1;
|
|
|
|
dir = gSnaMoveDir_800ABBA4;
|
|
|
|
work->field_79C = 0;
|
|
cVar4 = work->control.touch_flag;
|
|
|
|
if (cVar4 <= 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
dword_800ABBAC = &work->control.nearvecs[0];
|
|
dword_800ABBB4 = &work->control.nearflags[0];
|
|
dword_800ABBA8 = GV_VecDir2(&work->control.nearvecs[0]);
|
|
|
|
if ((*dword_800ABBB4 & 0x40) == 0)
|
|
{
|
|
pVec_800ABBCC = dword_800ABBAC;
|
|
dword_800ABBB0 = work->control.nears[0];
|
|
dword_800ABBD0 = dword_800ABBA8;
|
|
}
|
|
|
|
if (dir < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (cVar4 != 1)
|
|
{
|
|
iVar9 = GV_VecDir2(&work->control.nearvecs[1]);
|
|
iVar10 = GV_DiffDirAbs(dir, dword_800ABBA8);
|
|
|
|
if (GV_DiffDirAbs(dir, iVar9) < iVar10)
|
|
{
|
|
dword_800ABBAC = &work->control.nearvecs[1];
|
|
dword_800ABBB4 = &work->control.nearflags[1];
|
|
dword_800ABBA8 = GV_VecDir2(&work->control.nearvecs[1]);
|
|
|
|
if ((*dword_800ABBB4 & 0x40) == 0)
|
|
{
|
|
pVec_800ABBCC = dword_800ABBAC;
|
|
dword_800ABBB0 = work->control.nears[1];
|
|
dword_800ABBD0 = dword_800ABBA8;
|
|
}
|
|
}
|
|
}
|
|
|
|
result = sna_init_main_logic_helper_helper_800596FC(work);
|
|
|
|
if (result == -1)
|
|
{
|
|
pVec_800ABBCC = 0;
|
|
dword_800ABBD0 = -1;
|
|
return;
|
|
}
|
|
|
|
if (result != 2)
|
|
{
|
|
pVec_800ABBCC = &work->control.nearvecs[result];
|
|
dword_800ABBD0 = GV_VecDir2(pVec_800ABBCC);
|
|
dword_800ABBB0 = work->control.nears[result];
|
|
}
|
|
|
|
diff = GV_DiffDirS(dir, dword_800ABBD0);
|
|
|
|
if ((diff >= -896) && (diff <= 896))
|
|
{
|
|
dword_800ABBC4 = 1;
|
|
|
|
if (diff >= 0)
|
|
{
|
|
if (diff > 256)
|
|
{
|
|
dword_800ABBC4 = 4;
|
|
}
|
|
}
|
|
else if (diff < -256)
|
|
{
|
|
dword_800ABBC4 = 2;
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void sna_init_main_logic_helper2_800596FC(SnaInitWork *work)
|
|
{
|
|
int iVar9;
|
|
int iVar8;
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_GROUND))
|
|
{
|
|
work->field_A2A = 0;
|
|
}
|
|
else if (!flr_800ABBB8[0] || (flr_800ABBB8[0]->b1.h == 2))
|
|
{
|
|
work->field_A2A = 0;
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_WATCH))
|
|
{
|
|
work->control.turn.vx = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iVar8 = sub_8004E930(work, 750);
|
|
iVar9 = iVar8 - work->field_A2A;
|
|
|
|
if (iVar9 >= 0)
|
|
{
|
|
if (iVar9 < 16)
|
|
{
|
|
goto inside;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iVar9 = work->field_A2A - iVar8;
|
|
|
|
if (iVar9 < 16)
|
|
{
|
|
inside:
|
|
iVar8 = work->field_A2A;
|
|
}
|
|
}
|
|
|
|
work->field_A2A = iVar8;
|
|
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_WATCH))
|
|
{
|
|
(work->control).turn.vx = iVar8;
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void sna_init_main_logic_helper3_800596FC(SnaInitWork *work)
|
|
{
|
|
int iVar9;
|
|
int sVar5;
|
|
int iVar8;
|
|
int uVar13;
|
|
int new_var;
|
|
|
|
int msgs;
|
|
GV_MSG *pMsg;
|
|
int hash;
|
|
TARGET *pTarget;
|
|
|
|
if (!sna_check_flags1_8004E31C(work, 0x200000))
|
|
{
|
|
return;
|
|
}
|
|
|
|
uVar13 = work->field_9E4.field_9EC_flags3;
|
|
|
|
if (work->field_9E4.field_9F0 != 0)
|
|
{
|
|
work->control.field_38 = 450;
|
|
work->control.step_size = 450;
|
|
work->field_A28 = 450;
|
|
|
|
if ((uVar13 & 0x4002) == 0)
|
|
{
|
|
new_var = work->field_9E4.field_9EE;
|
|
iVar9 = work->control.levels[0];
|
|
iVar8 = (unsigned short)work->body.height - (iVar9 - new_var);
|
|
work->control.height = iVar8;
|
|
iVar8 = iVar8 + iVar9;
|
|
work->control.mov.vy = iVar8;
|
|
work->body.objs->world.t[1] = work->control.mov.vy;
|
|
DG_GetLightMatrix2(&work->control.mov, &work->field_848_lighting_mtx);
|
|
}
|
|
else if ((uVar13 & 0x100) == 0)
|
|
{
|
|
work->control.height = dword_8009EECC[work->field_A26_stance];
|
|
}
|
|
|
|
work->body.height = work->control.height;
|
|
sVar5 = work->field_9E4.field_9E8;
|
|
|
|
if (sVar5 >= 0)
|
|
{
|
|
if (GV_DiffDirAbs(sVar5, work->control.rot.vy) > 1536)
|
|
{
|
|
work->control.rot.vy = sVar5;
|
|
}
|
|
|
|
work->control.turn.vy = sVar5;
|
|
}
|
|
|
|
if ((uVar13 & 0x80) == 0)
|
|
{
|
|
GM_ConfigMotionControl(
|
|
&work->body,
|
|
&work->m_ctrl,
|
|
OAR_SNAKE,
|
|
work->m_segs1,
|
|
work->m_segs2,
|
|
&work->control,
|
|
work->rots
|
|
);
|
|
|
|
work->body.action = -1;
|
|
}
|
|
|
|
if ((uVar13 & 0x800) != 0)
|
|
{
|
|
SetAction_8004E22C(work, sna_8004EAA8(work, work->field_A26_stance), 0);
|
|
}
|
|
|
|
work->field_9E4.field_9F0 = 0;
|
|
}
|
|
|
|
msgs = work->field_7A0_msg_count;
|
|
pMsg = work->field_7A4_msgs;
|
|
|
|
while (msgs > 0)
|
|
{
|
|
hash = pMsg->message[0];
|
|
|
|
if ((hash == HASH_MOTION) || (hash == HASH_RUN_MOVE) || (hash == HASH_STANCE) || (hash == HASH_GO_MOTION))
|
|
{
|
|
pTarget = work->field_89C_pTarget;
|
|
|
|
if (pTarget->life_lost > 0)
|
|
{
|
|
pTarget->life += pTarget->life_lost;
|
|
sna_act_unk2_80051170(work->field_89C_pTarget);
|
|
}
|
|
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
goto exit;
|
|
}
|
|
|
|
msgs--;
|
|
pMsg++;
|
|
}
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_ACT_ONLY);
|
|
|
|
exit:
|
|
sna_clear_flags1_8004E308(work, 0x8200000);
|
|
}
|
|
|
|
static inline int sna_init_main_logic_helper4_helper_800596FC(SnaInitWork *work)
|
|
{
|
|
if (sna_check_flags1_8004E31C(work, 1) ||
|
|
GM_CheckPlayerStatusFlag(PLAYER_WATCH | PLAYER_INTRUDE))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int sna_init_main_logic_helper4_helper2_800596FC(SnaInitWork *work)
|
|
{
|
|
if (sna_check_flags1_8004E31C(work, 2) ||
|
|
GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) ||
|
|
(work->field_920_tbl & 0x200))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int sna_init_main_logic_helper4_helper3_800596FC(int f3e)
|
|
{
|
|
if ((f3e == 1) || (f3e == 3) || (f3e == 8))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int sna_init_main_logic_helper4_helper4_800596FC(SnaInitWork *work)
|
|
{
|
|
if (sna_check_flags1_8004E31C(work, 2) ||
|
|
GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) ||
|
|
(work->field_920_tbl & 0x200))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline void sna_init_main_logic_helper4_800596FC(SnaInitWork *work)
|
|
{
|
|
int iframes;
|
|
TARGET *pTarget;
|
|
int iVar8;
|
|
int bVar6;
|
|
int iVar9;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INVINCIBLE))
|
|
{
|
|
iframes = work->field_A24_invuln_frames;
|
|
|
|
if (iframes != 0)
|
|
{
|
|
if (--iframes > 0)
|
|
{
|
|
if (sna_init_main_logic_helper4_helper_800596FC(work))
|
|
{
|
|
if ((iframes & 3) != 0)
|
|
{
|
|
DG_VisibleObjs(work->body.objs);
|
|
}
|
|
else
|
|
{
|
|
DG_InvisibleObjs(work->body.objs);
|
|
}
|
|
}
|
|
|
|
if ((GM_Camera.first_person != 0) &&
|
|
(!sna_init_main_logic_helper4_helper2_800596FC(work) || (work->field_9AC & 0x2)) &&
|
|
!sna_check_flags1_8004E31C(work, 1))
|
|
{
|
|
gUnkCameraStruct_800B77B8.eye.vy += GV_RandS(16) * iframes;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sna_clear_invuln_8004F2EC(work);
|
|
}
|
|
|
|
work->field_A24_invuln_frames = iframes;
|
|
}
|
|
else
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_NOT_SIGHT))
|
|
{
|
|
DG_VisibleObjs(work->body.objs);
|
|
}
|
|
|
|
if (GM_Camera.first_person != 0)
|
|
{
|
|
DG_InvisibleObjs(work->body.objs);
|
|
}
|
|
else
|
|
{
|
|
DG_VisibleObjs(work->body.objs);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pTarget = work->field_89C_pTarget;
|
|
|
|
if (pTarget->damaged & 0x6)
|
|
{
|
|
iVar8 = pTarget->a_mode;
|
|
bVar6 = sna_init_main_logic_helper4_helper3_800596FC(iVar8);
|
|
|
|
if (sna_init_main_logic_helper4_helper4_800596FC(work) && (bVar6 || !(work->field_9AC & 0x2)))
|
|
{
|
|
work->control.skip_flag &= ~CTRL_SKIP_TRAP;
|
|
GM_ClearPlayerStatusFlag(PLAYER_SQUAT | PLAYER_CAUTION | PLAYER_ITEM_DISABLE);
|
|
sna_clear_flags1_8004E308(work, 0x30);
|
|
sna_clear_flags1_8004E308(work, 0x100);
|
|
work->field_9C0 = 0;
|
|
work->field_A28 = 0x1c2;
|
|
|
|
if ((work->field_920_tbl & 0x4) &&
|
|
GM_CheckPlayerStatusFlag(PLAYER_ATTACK) &&
|
|
(work->field_924 != 3))
|
|
{
|
|
work->field_914_trigger |= 0x9;
|
|
}
|
|
|
|
sub_8004F454(work);
|
|
|
|
if (work->field_90C_pWeaponFn == &sna_80057A90)
|
|
{
|
|
work->field_90C_pWeaponFn = &sna_gun_800540D0;
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
}
|
|
|
|
GM_SetPlayerStatusFlag(PLAYER_DAMAGED | PLAYER_WEAPON_DISABLE);
|
|
|
|
if (!bVar6)
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_DOWNED))
|
|
{
|
|
sna_set_flags1_8004E2F4(work, 0x4);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_knockdown_shot_80054B50);
|
|
}
|
|
else if (GM_CheckPlayerStatusFlag(PLAYER_CB_BOX))
|
|
{
|
|
sna_set_flags1_8004E2F4(work, 0x20);
|
|
sna_start_anim_8004E1F4(work, &sna_act_helper2_helper7_80054648);
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_shot_flinch_800544E0);
|
|
}
|
|
|
|
GM_SeSet2(0, 63, SE_PLAYER_DAMAGE_LIGHT);
|
|
|
|
NewPadVibration(dword_8009EED4, 1);
|
|
NewPadVibration(dword_8009EED8, 2);
|
|
}
|
|
else
|
|
{
|
|
work->field_A2C = pTarget->scale;
|
|
work->field_A2C.vx /= 2;
|
|
work->field_A2C.vy /= 4;
|
|
work->field_A2C.vz /= 2;
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_GROUND | PLAYER_DOWNED))
|
|
{
|
|
if (!GM_CheckPlayerStatusFlag(PLAYER_DOWNED))
|
|
{
|
|
work->field_A54.knockdown_thing = 1;
|
|
}
|
|
|
|
sna_start_anim_8004E1F4(work, &sna_anim_knockdown_shot_tank_80054C08);
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, &sna_anim_knockdown_80054710);
|
|
}
|
|
|
|
if (work->field_9AC & 0x1)
|
|
{
|
|
sub_8004F204(work);
|
|
}
|
|
|
|
GM_SeSet2(0, 63, SE_PLAYER_DAMAGE_HEAVY);
|
|
|
|
NewPadVibration(dword_8009EEE0, 1);
|
|
NewPadVibration(dword_8009EEE4, 2);
|
|
|
|
sna_8004EC00(work);
|
|
sna_set_flags1_8004E2F4(work, 0x4);
|
|
}
|
|
|
|
sna_act_helper2_helper4_8004F090(work, iVar8);
|
|
}
|
|
else
|
|
{
|
|
sna_set_invuln_8004F2A0(work, 0x20);
|
|
|
|
if (pTarget->life_lost > 0)
|
|
{
|
|
sna_act_helper2_helper4_8004F090(work, pTarget->a_mode);
|
|
}
|
|
|
|
switch (iVar8)
|
|
{
|
|
case 1:
|
|
case 3:
|
|
GM_SeSet2(0, 63, SE_PLAYER_DAMAGE_LIGHT);
|
|
NewPadVibration(dword_8009EED4, 1);
|
|
NewPadVibration(dword_8009EED8, 2);
|
|
break;
|
|
|
|
default:
|
|
GM_SeSet2(0, 63, SE_PLAYER_DAMAGE_HEAVY);
|
|
NewPadVibration(dword_8009EEE0, 1);
|
|
NewPadVibration(dword_8009EEE4, 2);
|
|
break;
|
|
}
|
|
|
|
|
|
if ((pTarget->life < 1) && ((GM_GameOverTimer > -2) && (GM_GameOverTimer < 1)))
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_INTRUDE | PLAYER_GROUND))
|
|
{
|
|
iVar9 = 0x7d;
|
|
}
|
|
else
|
|
{
|
|
iVar9 = 0x80;
|
|
work->control.rot.vx = 0;
|
|
work->control.turn.vx = 0;
|
|
}
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_DOWNED))
|
|
{
|
|
if (work->field_A54.choke_count == 1)
|
|
{
|
|
iVar9 = 0x7e;
|
|
}
|
|
else
|
|
{
|
|
iVar9 = 0x7f;
|
|
}
|
|
}
|
|
|
|
GM_SeSet2(0, 63, SE_PLAYEROUT);
|
|
sna_8004F8E4(work, iVar9);
|
|
}
|
|
}
|
|
|
|
sna_act_unk2_80051170(pTarget);
|
|
|
|
if (GM_Camera.first_person != 0)
|
|
{
|
|
work->control.turn.vy += GV_RandS(512);
|
|
}
|
|
}
|
|
else if (pTarget->damaged & 0x80)
|
|
{
|
|
sna_act_unk2_80051170(pTarget);
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void sna_init_main_logic_helper5_800596FC(SnaInitWork *work)
|
|
{
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_GAME_OVER))
|
|
{
|
|
if (((work->body.action == 128) && (work->m_ctrl.info1.frame == 49)) ||
|
|
((work->body.action == 127) && (work->m_ctrl.info1.frame == 72)))
|
|
{
|
|
NewPadVibration(dword_8009EEF0, 1);
|
|
NewPadVibration(dword_8009EEF4, 2);
|
|
|
|
if (work->body.action == 128)
|
|
{
|
|
GM_SeSetMode(&work->control.mov, SE_HIT_FLOOR, GM_SEMODE_BOMB);
|
|
}
|
|
}
|
|
|
|
if ((work->field_7A0_msg_count == 0) &&
|
|
!GM_CheckPlayerStatusFlag(PLAYER_ACT_ONLY) &&
|
|
(GM_StreamStatus() != 2))
|
|
{
|
|
GM_StreamPlayStop();
|
|
sna_set_flags1_8004E2F4(work, 0x40000);
|
|
GM_GameOverTimer = 1;
|
|
}
|
|
}
|
|
else if (GM_GameOverTimer > 0)
|
|
{
|
|
GM_GameStatus |= STATE_PADRELEASE;
|
|
|
|
if (GM_GameOverTimer == 2)
|
|
{
|
|
sna_set_flags1_8004E2F4(work, 0x80000);
|
|
GM_SetPlayerStatusFlag(PLAYER_GAME_OVER);
|
|
sna_set_invuln_8004F2A0(work, 0);
|
|
GM_GameOverTimer = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline int sna_init_main_logic_helper6_helper_800596FC(SnaInitWork *work, int flags)
|
|
{
|
|
if (dword_8009F46C[0] != 0 ||
|
|
sna_check_flags1_8004E31C(work, 0x4) ||
|
|
GM_CheckPlayerStatusFlag(flags) ||
|
|
work->field_9CC_anim_update_fn_1p == &sna_fn_nothing_80053B80)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int sna_init_main_logic_helper6_helper2_800596FC(SnaInitWork *work)
|
|
{
|
|
if ((work->field_920_tbl & 0x200) ||
|
|
(work->field_9AC & 0x2) ||
|
|
sna_check_flags1_8004E31C(work, 0x4) ||
|
|
sna_sub_8004E358(work, 0x100))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int sna_init_main_logic_helper6_helper3_800596FC(SnaInitWork *work)
|
|
{
|
|
if ((work->field_920_tbl & 0x200) ||
|
|
(work->field_9AC & 0x2) ||
|
|
sna_check_flags1_8004E31C(work, 0x4) ||
|
|
sna_sub_8004E358(work, 0x100))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline void sna_init_main_logic_helper6_800596FC(SnaInitWork *work)
|
|
{
|
|
if ((work->field_9B0_pad_ptr->press & PAD_TRIANGLE) &&
|
|
sna_init_main_logic_helper6_helper_800596FC(work, PLAYER_WATCH | PLAYER_ATTACK))
|
|
{
|
|
sub_8004EB74(work);
|
|
GM_SetPlayerStatusFlag(PLAYER_NORMAL_WATCH);
|
|
}
|
|
}
|
|
|
|
void sna_init_main_logic_800596FC(SnaInitWork *work)
|
|
{
|
|
int vy;
|
|
GV_PAD *pPad;
|
|
unsigned char *pAxis;
|
|
int i;
|
|
int frame;
|
|
int hzd_count;
|
|
unsigned short *pHzdVal;
|
|
|
|
work->field_798_p_height = work->control.height;
|
|
|
|
vy = work->body.height;
|
|
work->control.height = vy;
|
|
|
|
if ( vy < 500 )
|
|
{
|
|
vy = 500;
|
|
}
|
|
|
|
if ( vy > 700 )
|
|
{
|
|
vy = 700;
|
|
}
|
|
|
|
work->field_89C_pTarget->size.vy = vy;
|
|
|
|
if ( (work->field_A2C.vy < 0) && (work->control.level_flag != 0) )
|
|
{
|
|
work->field_A2C.vy = 0;
|
|
}
|
|
|
|
work->field_A2C.vy -= 32;
|
|
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_NOT_PLAYABLE) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_PAD_OFF) )
|
|
{
|
|
work->field_9B0_pad_ptr = &GV_PadData_8009F0C4;
|
|
}
|
|
|
|
work->field_914_trigger = 0;
|
|
work->control.turn.vz = 0;
|
|
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK15);
|
|
|
|
pPad = work->field_9B0_pad_ptr;
|
|
|
|
if ( pPad->analog != 0 && (pPad->status & (PAD_LEFT | PAD_DOWN | PAD_RIGHT | PAD_UP)) )
|
|
{
|
|
pAxis = &pPad->left_dx;
|
|
|
|
for ( i = 0; i < 2; i++, pAxis++ )
|
|
{
|
|
if ( (*pAxis < 64) || (*pAxis > 192) )
|
|
{
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK15);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
sna_init_main_logic_helper_800596FC(work);
|
|
sna_init_main_logic_helper2_800596FC(work);
|
|
sna_init_main_logic_helper3_800596FC(work);
|
|
sna_init_main_logic_helper4_800596FC(work);
|
|
|
|
if ( GM_StatusEvent & EV_CommonCold )
|
|
{
|
|
if ( !(GM_GameStatus & (STATE_PADRELEASE | STATE_PADDEMO | STATE_DEMO)) &&
|
|
!GM_CheckPlayerStatusFlag(PLAYER_PAD_OFF) &&
|
|
(work->field_A5C < 900) )
|
|
{
|
|
work->field_A5C++;
|
|
}
|
|
|
|
if ( sna_act_helper2_helper5_8004FF88(work) && (work->field_A5C == 900) )
|
|
{
|
|
work->field_A5C = 0;
|
|
sna_start_anim_8004E1F4(work, &sna_act_helper2_helper_80054EFC);
|
|
}
|
|
}
|
|
|
|
sna_weapon_switching_800511BC(work, 1);
|
|
sna_800515BC(work, 1);
|
|
|
|
if ( !GM_CheckPlayerStatusFlag(0x1304) &&
|
|
((work->field_9AC & 2) == 0) &&
|
|
((work->field_920_tbl & 0x4000) != 0) &&
|
|
(*work->field_918_n_bullets == 0))
|
|
{
|
|
*work->field_918_n_bullets = -1;
|
|
GM_CurrentWeaponId = WP_None;
|
|
work->field_90C_pWeaponFn = &sna_anim_chokethrow_begin1_80054210;
|
|
work->field_910 = 0;
|
|
work->field_926 = 0;
|
|
work->field_924 = 0;
|
|
GM_WeaponChanged = 1;
|
|
work->field_920_tbl = GM_WeaponTypes[0];
|
|
work->field_918_n_bullets = 0;
|
|
GM_ClearPlayerStatusFlag(PLAYER_WEAPON_DISABLE | PLAYER_ITEM_DISABLE);
|
|
}
|
|
|
|
sna_act_unk_80050A64(work);
|
|
sna_init_main_logic_helper5_800596FC(work);
|
|
sna_act_helper2_helper3_8004ED6C(work);
|
|
|
|
frame = work->field_9BC_anim_frame++;
|
|
work->field_9B8_fn_anim(work, frame);
|
|
|
|
if (GM_CheckPlayerStatusFlag(PLAYER_WATCH))
|
|
{
|
|
work->field_9CC_anim_update_fn_1p(work, frame);
|
|
}
|
|
else
|
|
{
|
|
work->field_9C8_anim_update_fn_3p(work, frame);
|
|
}
|
|
|
|
if ((work->field_920_tbl & 0x40) &&
|
|
GM_CheckPlayerStatusFlag(PLAYER_ATTACK))
|
|
{
|
|
work->field_910++;
|
|
work->field_90C_pWeaponFn(work, work->field_910 - 1);
|
|
}
|
|
|
|
if ( sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK9) )
|
|
{
|
|
work->field_9C4++;
|
|
work->field_9C0(work, work->field_9C4 - 1);
|
|
}
|
|
|
|
work->control.step_size = GV_NearExp4(work->control.step_size, work->field_A28);
|
|
work->control.step.vy = work->field_A2C.vy;
|
|
|
|
sna_init_main_logic_helper6_800596FC(work);
|
|
|
|
if ( GM_StreamStatus() == 2 )
|
|
{
|
|
if ( sub_8004EFE4(work, 1) >= 0 )
|
|
{
|
|
work->m_ctrl.info1.field_14 = 1;
|
|
}
|
|
|
|
sna_act_helper2_helper2_80033054(CHARAID_SNAKE, &work->adjust[6]);
|
|
|
|
if ( !work->body.objs->adjust && (work->m_ctrl.info1.field_14 == 1) )
|
|
{
|
|
GV_AddVec3(&work->rots[6], &work->adjust[6], &work->rots[6]);
|
|
}
|
|
}
|
|
|
|
GM_PlayerAction = work->body.action;
|
|
dword_800AB9D4 = work->m_ctrl.info1.frame;
|
|
GM_PlayerStance = work->field_A26_stance;
|
|
|
|
if ( GM_TranquilizerTimer > 0 )
|
|
{
|
|
GM_TranquilizerTimer--;
|
|
}
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_NOHIDDEN | PLAYER_HIDDEN);
|
|
|
|
hzd_count = work->control.event.n_triggers;
|
|
pHzdVal = work->control.event.triggers;
|
|
|
|
while ( hzd_count > 0 )
|
|
{
|
|
if ( *pHzdVal == 0x375E )
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_NOHIDDEN);
|
|
}
|
|
else if ( *pHzdVal == 0xF715 )
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_HIDDEN);
|
|
}
|
|
|
|
hzd_count -= 1;
|
|
pHzdVal += 1;
|
|
}
|
|
|
|
if ( work->field_9A0 != 0 )
|
|
{
|
|
addPrim(DG_Chanl(1)->ot[GV_Clock], &work->field_950[GV_Clock]);
|
|
work->field_9A0--;
|
|
}
|
|
|
|
snake_weapon_idx_800BDCBA = work->field_91C_weapon_idx;
|
|
snake_weapon_max_ammo_800BDCBC = *work->field_918_n_bullets;
|
|
snake_mag_size_800BDCB8 = GM_Magazine;
|
|
}
|
|
|
|
static inline int sna_act_helper_8005AD10(SnaInitWork *work)
|
|
{
|
|
if ( sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK19) )
|
|
{
|
|
CheckMessage0_80050878(work);
|
|
sna_act_unk_80050A64(work);
|
|
|
|
if ( sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK19) )
|
|
{
|
|
sna_act_unk2_80051170(work->field_89C_pTarget);
|
|
|
|
dword_800AB9D4 = 0;
|
|
DG_SetPos2(&work->control.mov, &work->control.rot);
|
|
DG_PutObjs(work->body.objs);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static inline void sna_act_helper2_8005AD10(SnaInitWork *work)
|
|
{
|
|
SVECTOR vec;
|
|
|
|
if ( sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK24) && !sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK28) )
|
|
{
|
|
vec = work->field_A68;
|
|
GV_NearExp8V(&vec.vx, &DG_ZeroVector.vx, 3);
|
|
|
|
if ( GV_VecLen3(&vec) > 8 )
|
|
{
|
|
work->field_A68 = vec;
|
|
}
|
|
|
|
work->control.step.vx = work->field_A68.vx;
|
|
work->control.step.vz = work->field_A68.vz;
|
|
|
|
if ( work->control.level_flag & 1 )
|
|
{
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK24);
|
|
}
|
|
}
|
|
|
|
if ( sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK26) )
|
|
{
|
|
work->control.step.vz = 0;
|
|
work->control.step.vx = 0;
|
|
}
|
|
}
|
|
|
|
void sna_act_8005AD10(SnaInitWork *work)
|
|
{
|
|
SVECTOR vec;
|
|
SVECTOR vec2;
|
|
TARGET *pTarget;
|
|
int height;
|
|
int level;
|
|
TARGET *pTarget2;
|
|
|
|
if ( sna_act_helper_8005AD10(work) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_SECOND_AVAILABLE) )
|
|
{
|
|
if ( ((GV_PadData + 1)->status | (GV_PadData + 1)->release) != 0 )
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_SECOND_CONTROLLER);
|
|
work->field_9B0_pad_ptr = &GV_PadData[1];
|
|
}
|
|
else if ( (GV_PadData->status | GV_PadData->release) != 0 )
|
|
{
|
|
GM_ClearPlayerStatusFlag(PLAYER_SECOND_CONTROLLER);
|
|
work->field_9B0_pad_ptr = &GV_PadData[0];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
work->field_9B0_pad_ptr = &GV_PadData[0];
|
|
}
|
|
|
|
pTarget = work->field_89C_pTarget;
|
|
|
|
if ( pTarget->damaged & 8 )
|
|
{
|
|
GV_AddVec3(&pTarget->offset, &work->control.step, &work->control.step);
|
|
pTarget->damaged &= ~0x8;
|
|
pTarget->offset = DG_ZeroVector;
|
|
}
|
|
|
|
height = (short)work->body.height;
|
|
|
|
GM_ActMotion(&work->body);
|
|
sna_act_helper2_8005AD10(work);
|
|
|
|
level = work->control.levels[0];
|
|
work->control.hzd_height = HzdHeights_8009EEC4[work->field_A26_stance] + level;
|
|
|
|
if ( (work->control.skip_flag & CTRL_BOTH_CHECK) && (work->field_798_p_height < 750) )
|
|
{
|
|
work->control.hzd_height = work->control.mov.vy;
|
|
}
|
|
|
|
/* しゃがみ天井突き抜け防止 */
|
|
if ( (work->field_A26_stance != SNA_STANCE_STANDING) && (height >= 500) )
|
|
{
|
|
work->control.height = 496;
|
|
}
|
|
|
|
UpdateLife_8004F6E8(work);
|
|
CheckSnakeDead_8004E384(work);
|
|
CheckMessage0_80050878(work);
|
|
|
|
GM_ActControl(&work->control);
|
|
|
|
flr_800ABBB8[1] = 0;
|
|
do {} while (0);
|
|
flr_800ABBB8[0] = NULL;
|
|
dword_800ABBC0 = 0;
|
|
|
|
if ( work->control.step_size != -2 )
|
|
{
|
|
HZD_LevelMinMaxFloors(flr_800ABBB8);
|
|
|
|
if ( flr_800ABBB8[0] )
|
|
{
|
|
dword_800ABBC0 = flr_800ABBB8[0]->p4.h;
|
|
}
|
|
}
|
|
|
|
if ( ((level - work->control.levels[0]) >= 250) && !sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK28) )
|
|
{
|
|
if ( !flr_800ABBB8[0] || (flr_800ABBB8[0]->b1.h == 2) )
|
|
{
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK24);
|
|
work->field_A68 = work->control.step;
|
|
work->field_A68.vy = 0;
|
|
}
|
|
}
|
|
|
|
if ( work->control.step_size == -2 )
|
|
{
|
|
work->control.mov.vy += work->body.height - height;
|
|
DG_SetPos2(&work->control.mov, &work->control.rot);
|
|
}
|
|
|
|
GM_ActObject(&work->body);
|
|
|
|
sna_clear_flags1_8004E308(work, SNA_FLAG1_UNK25);
|
|
DG_GetLightMatrix2(&work->control.mov, &work->field_848_lighting_mtx);
|
|
*work->field_88C = dword_800ABA1C == 0;
|
|
GM_MoveTarget(work->field_89C_pTarget, &work->control.mov);
|
|
|
|
vec2 = work->control.mov;
|
|
|
|
if ( !sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK12) )
|
|
{
|
|
vec2.vy = work->body.objs->objs[6].world.t[1];
|
|
}
|
|
|
|
if (work->field_A26_stance == SNA_STANCE_CROUCH)
|
|
{
|
|
vec2.vy += 320;
|
|
}
|
|
|
|
work->field_A60 = vec2;
|
|
|
|
gUnkCameraStruct_800B77B8.rotate2 = work->control.rot;
|
|
gUnkCameraStruct_800B77B8.rotate2.vy &= 0xFFF;
|
|
|
|
sna_init_main_logic_800596FC(work);
|
|
|
|
pTarget2 = work->field_89C_pTarget;
|
|
pTarget2->scale = work->control.step;
|
|
GM_PushTarget(pTarget2);
|
|
|
|
if (GM_Camera.first_person != 0)
|
|
{
|
|
GV_NearExp4V(&gUnkCameraStruct_800B77B8.eye.vx, &work->field_A60.vx, 3);
|
|
}
|
|
else
|
|
{
|
|
gUnkCameraStruct_800B77B8.eye = vec2;
|
|
}
|
|
|
|
GM_PlayerPosition = vec = work->control.mov;
|
|
|
|
if ( sna_check_flags1_8004E31C(work, SNA_FLAG1_UNK16) )
|
|
{
|
|
GM_PlayerPosition = work->field_A60;
|
|
GM_MoveTarget(work->field_89C_pTarget, &work->field_A60);
|
|
}
|
|
|
|
vec.vy = level = work->control.levels[0];
|
|
GM_PlayerAddress = work->field_844 = HZD_GetAddress(work->control.map->hzd, &vec, work->field_844);
|
|
|
|
if ( GM_CheckPlayerStatusFlag(PLAYER_INTRUDE) )
|
|
{
|
|
if ( gUnkCameraStruct_800B77B8.eye.vy < (level + 150) )
|
|
{
|
|
gUnkCameraStruct_800B77B8.eye.vy = level + 150;
|
|
}
|
|
else if ( gUnkCameraStruct_800B77B8.eye.vy > (level + 250) )
|
|
{
|
|
gUnkCameraStruct_800B77B8.eye.vy = level + 250;
|
|
}
|
|
}
|
|
|
|
GM_ClearPlayerStatusFlag(PLAYER_INVISIBLE);
|
|
|
|
if ( GM_CheckPlayerStatusFlag(3) )
|
|
{
|
|
GM_SetPlayerStatusFlag(PLAYER_INVISIBLE);
|
|
}
|
|
}
|
|
|
|
void sna_kill_8005B52C(SnaInitWork *work)
|
|
{
|
|
CONTROL *pCtrl;
|
|
GV_ACT *pShadow;
|
|
GV_ACT *pWeapon;
|
|
GV_ACT *pItem;
|
|
|
|
pCtrl = &work->control;
|
|
GM_FreeControl(&work->control);
|
|
GM_FreeObject(&work->body);
|
|
GM_FreeTarget(work->field_89C_pTarget);
|
|
GM_FreePrim(work->field_92C);
|
|
|
|
GM_PlayerStance = work->field_A26_stance;
|
|
|
|
pShadow = work->field_888_pShadow;
|
|
if (pShadow)
|
|
{
|
|
GV_DestroyOtherActor(pShadow);
|
|
}
|
|
|
|
pWeapon = work->field_908_weapon_actor;
|
|
if (pWeapon)
|
|
{
|
|
GV_DestroyOtherActor(pWeapon);
|
|
}
|
|
|
|
pItem = work->field_9A4_item_actor;
|
|
if (pItem)
|
|
{
|
|
GV_DestroyOtherActor(pItem);
|
|
}
|
|
|
|
if (GM_PlayerControl == pCtrl)
|
|
{
|
|
GM_PlayerControl = 0;
|
|
}
|
|
|
|
if (GM_PlayerBody == &work->body)
|
|
{
|
|
GM_PlayerBody = 0;
|
|
}
|
|
|
|
snainit_actor_800A9424 = NULL;
|
|
}
|
|
|
|
static inline int sna_LoadSnake2(SnaInitWork *work)
|
|
{
|
|
SVECTOR *temp_s1;
|
|
SVECTOR *temp_s2;
|
|
DG_PRIM *pPrim;
|
|
DG_TEX *pTex;
|
|
POLY_GT4 *pPoly;
|
|
int i, j;
|
|
|
|
temp_s1 = &work->field_930;
|
|
pPrim = DG_GetPrim(DG_PRIM_LINE_GT2, 2, 0, temp_s1, 0);
|
|
|
|
if (!pPrim)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
pTex = DG_GetTexture(PCX_LSIGHT);
|
|
work->field_928 = pTex;
|
|
|
|
if (!pTex)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
pPrim->field_2E_k500 = 500;
|
|
|
|
for (i = 0; i < 2; i++)
|
|
{
|
|
pPoly = &pPrim->packs[i]->poly_gt4;
|
|
|
|
for (j = 0; j < 2; j++)
|
|
{
|
|
LSTORE(COLOR_BLACK, &pPoly->r0);
|
|
LSTORE(COLOR_GRAY, &pPoly->r1);
|
|
LSTORE(COLOR_BLACK, &pPoly->r2);
|
|
LSTORE(COLOR_GRAY, &pPoly->r3);
|
|
setPolyGT4(pPoly);
|
|
setSemiTrans(pPoly, 1);
|
|
pPoly->tpage = pTex->tpage;
|
|
pPoly->clut = pTex->clut;
|
|
pPoly++;
|
|
}
|
|
}
|
|
|
|
// ???
|
|
temp_s2 = temp_s1 + 2;
|
|
|
|
temp_s1[2].vx = -100;
|
|
temp_s1[0].vx = -100;
|
|
temp_s1[3].vy = -300;
|
|
temp_s2[0].vy = -300;
|
|
temp_s1[1].vy = -300;
|
|
temp_s1[0].vy = -300;
|
|
temp_s2[0].vz = 300;
|
|
temp_s1[0].vz = 300;
|
|
temp_s1[1].vx = -800;
|
|
temp_s1[1].vz = 2000;
|
|
temp_s1[3].vx = 800;
|
|
temp_s1[3].vz = 2000;
|
|
|
|
DG_InvisiblePrim(pPrim);
|
|
work->field_92C = pPrim;
|
|
return 0;
|
|
}
|
|
|
|
static inline void sna_LoadSnake3(SnaInitWork *work)
|
|
{
|
|
u_short t1, t2;
|
|
short stance;
|
|
short temp_a1;
|
|
int temp_v1_3;
|
|
int var_s0_2;
|
|
int var_v_2;
|
|
|
|
stance = work->field_A26_stance = GM_PlayerStance;
|
|
if (stance == 3)
|
|
{
|
|
t1 = GM_ItemTypes[GM_CurrentItemId + 1];
|
|
t2 = GM_CurrentItemId;
|
|
|
|
if ((t1 & 2) || ((t2 - 2) < 3u))
|
|
{
|
|
GM_CurrentItemId = IT_None;
|
|
}
|
|
|
|
if (GM_WeaponTypes[GM_CurrentWeaponId + 1] & 0x200)
|
|
{
|
|
GM_CurrentWeaponId = WP_None;
|
|
}
|
|
}
|
|
|
|
work->field_844 = -1;
|
|
work->field_91C_weapon_idx = -2;
|
|
|
|
sna_weapon_switching_800511BC(work, 0);
|
|
|
|
work->field_9A8_current_item = IT_None;
|
|
|
|
sna_800515BC(work, 0);
|
|
|
|
work->actpack = &weapon_actions_8009ED8C[GM_CurrentWeaponId];
|
|
work->field_A28 = 450;
|
|
work->field_A44 = work->control.mov;
|
|
work->field_A60 = work->control.mov;
|
|
|
|
gUnkCameraStruct_800B77B8.eye = work->field_A60;
|
|
|
|
if (GCL_GetOption('o')) // oar
|
|
{
|
|
work->field_A5A = GCL_StrToInt(GCL_GetParamResult());
|
|
}
|
|
|
|
work->field_890_autoaim_max_dist = 6000;
|
|
|
|
if (GCL_GetOption('l')) // len
|
|
{
|
|
work->field_890_autoaim_max_dist = GCL_StrToInt(GCL_GetParamResult());
|
|
}
|
|
|
|
work->field_892_autoaim_min_angle = 512;
|
|
|
|
if (GCL_GetOption('r')) // rot
|
|
{
|
|
work->field_892_autoaim_min_angle = GCL_StrToInt(GCL_GetParamResult());
|
|
}
|
|
|
|
dword_800ABBDC = -1023;
|
|
dword_800ABBD4 = 1023;
|
|
|
|
if (GCL_GetOption('t')) // turn
|
|
{
|
|
dword_800ABBDC = GCL_StrToInt(GCL_GetParamResult());
|
|
dword_800ABBD4 = GCL_StrToInt(GCL_GetParamResult());
|
|
}
|
|
|
|
work->field_A70 = -1;
|
|
|
|
if (GCL_GetOption('e')) // exec
|
|
{
|
|
work->field_A70 = GCL_StrToInt(GCL_GetParamResult());
|
|
}
|
|
|
|
temp_a1 = work->field_A26_stance;
|
|
|
|
if (temp_a1 == 3)
|
|
{
|
|
work->field_A26_stance = 2;
|
|
GM_SetPlayerStatusFlag(PLAYER_GROUND | PLAYER_INTRUDE);
|
|
DG_InvisibleObjs(work->body.objs);
|
|
sna_8004EC8C(work);
|
|
sna_start_anim_8004E1F4(work, &sna_anim_duct_move_80054424);
|
|
GM_Camera.first_person = 2;
|
|
var_v_2 = sna_8004EAA8(work, 2);
|
|
}
|
|
else
|
|
{
|
|
var_s0_2 = sna_8004EAA8(work, temp_a1);
|
|
|
|
if ((work->field_9AC & 1) || (work->field_920_tbl & 0x20))
|
|
{
|
|
if ((unsigned int)(work->field_9A8_current_item - 2) < 3)
|
|
{
|
|
var_s0_2 = 4;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sna_start_anim_8004E1F4(work, dword_8009EEA4[work->field_A26_stance]);
|
|
}
|
|
|
|
var_v_2 = var_s0_2;
|
|
}
|
|
|
|
GM_ConfigObjectAction(&work->body, var_v_2, 0, 0);
|
|
GM_ActMotion(&work->body);
|
|
|
|
temp_v1_3 = (short)work->body.height;
|
|
|
|
work->field_798_p_height = temp_v1_3;
|
|
work->control.height = temp_v1_3;
|
|
|
|
work->field_9B0_pad_ptr = GV_PadData;
|
|
}
|
|
|
|
static inline void sna_LoadSnake4( POLY_FT4 *packs, int n_packs, DG_TEX *tex )
|
|
{
|
|
char u, v;
|
|
int i;
|
|
|
|
u = tex->off_x;
|
|
v = tex->off_y;
|
|
|
|
for ( i = 0; i < n_packs; i ++ )
|
|
{
|
|
setPolyFT4( packs );
|
|
setSemiTrans( packs, 1 );
|
|
setRGB0( packs, 128, 128, 128 );
|
|
setXY4( packs, 255, 164, 303, 164, 255, 176, 303, 176 );
|
|
setUV4( packs, u, v, u + 48, v, u, v + 12, u + 48, v + 12 );
|
|
packs->tpage = tex->tpage;
|
|
packs->clut = tex->clut;
|
|
packs ++ ;
|
|
}
|
|
}
|
|
|
|
static inline int sna_LoadSnake(SnaInitWork *work, int scriptData, int scriptBinds)
|
|
{
|
|
CONTROL *pCtrl;
|
|
OBJECT *body;
|
|
TARGET *pTarget;
|
|
HITTABLE *pJiraiUnk;
|
|
SVECTOR shadow;
|
|
SVECTOR vec;
|
|
SVECTOR *pVec;
|
|
int tmp, model, i;
|
|
char *param_pos, *param_dir;
|
|
|
|
pCtrl = &work->control;
|
|
if (GM_InitControl(pCtrl, scriptData, scriptBinds) < 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
param_pos = (char*)GCL_GetOption('p'); // pos
|
|
param_dir = (char*)GCL_GetOption('d'); // dir
|
|
GM_ConfigControlString(pCtrl, param_pos, param_dir);
|
|
GM_ConfigControlHazard(pCtrl, 0, 450, 450);
|
|
|
|
tmp = 1;
|
|
pCtrl->exclude_flag = tmp;
|
|
|
|
GM_ConfigControlAttribute(pCtrl, tmp);
|
|
GM_ConfigControlTrapCheck(pCtrl);
|
|
|
|
body = &work->body;
|
|
|
|
model = KMD_SNAKE;
|
|
if (GCL_GetOption('m')) // model
|
|
{
|
|
model = GCL_StrToInt(GCL_GetParamResult());
|
|
}
|
|
|
|
GM_InitObject(body, model, BODY_FLAG, OAR_SNAKE);
|
|
|
|
GM_ConfigObjectJoint(body);
|
|
GM_ConfigMotionControl(body,
|
|
&work->m_ctrl,
|
|
OAR_SNAKE,
|
|
work->m_segs1,
|
|
work->m_segs2,
|
|
pCtrl,
|
|
work->rots);
|
|
GM_ConfigObjectLight(body, &work->field_848_lighting_mtx);
|
|
|
|
GM_PlayerControl = pCtrl;
|
|
GM_PlayerPosition = work->control.mov;
|
|
GM_PlayerBody = body;
|
|
|
|
sna_8004EB14(work);
|
|
|
|
if (sna_LoadSnake2(work) < 0)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
sna_LoadSnake3(work);
|
|
|
|
pVec = &vec;
|
|
setVector(pVec, 300, 650, 300);
|
|
|
|
pTarget = work->field_89C_pTarget = GM_AllocTarget();
|
|
|
|
GM_SetTarget(pTarget, 159, PLAYER_SIDE, pVec);
|
|
GM_Target_8002DCCC(pTarget, 1, -1, GM_SnakeCurrentHealth, 0, &DG_ZeroVector);
|
|
GM_Target_8002DCB4(pTarget, 0, 0, &work->field_8F4, &work->field_8FC);
|
|
GM_MoveTarget(pTarget, &work->control.mov);
|
|
|
|
work->field_A22_snake_current_health = GM_SnakeCurrentHealth;
|
|
|
|
sna_LoadSnake4(work->field_950, 2, DG_GetTexture(PCX_EMPTY2));
|
|
|
|
shadow.vx = 0;
|
|
shadow.vy = 6;
|
|
shadow.vz = 12;
|
|
shadow.pad = 15;
|
|
|
|
work->field_888_pShadow = NewShadow2(pCtrl, body, shadow, &work->field_88C);
|
|
|
|
dword_800ABA1C = 0;
|
|
GM_BombSeg = 0;
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
tenage_ctrls_800BDD30[i] = NULL;
|
|
}
|
|
|
|
dword_800BDD28 = 0;
|
|
tenage_ctrls_count_800BDD70 = 0;
|
|
|
|
pJiraiUnk = GM_C4Datas_800BDD78;
|
|
i = 0;
|
|
|
|
while (i < C4_COUNT)
|
|
{
|
|
i++;
|
|
pJiraiUnk->type = WP_C4;
|
|
pJiraiUnk->actor = NULL;
|
|
pJiraiUnk++;
|
|
}
|
|
|
|
dword_8009F434 = 0;
|
|
bakudan_count_8009F42C = 0;
|
|
|
|
pJiraiUnk = GM_ClayDatas_800BDE78;
|
|
i = 0;
|
|
|
|
while (i < 8)
|
|
{
|
|
i++;
|
|
pJiraiUnk->type = WP_Claymore;
|
|
pJiraiUnk->actor = NULL;
|
|
pJiraiUnk++;
|
|
}
|
|
|
|
dword_8009F440 = 0;
|
|
dword_8009F444 = 0;
|
|
counter_8009F448 = 0;
|
|
dword_8009F46C[0] = 0;
|
|
dword_8009F470 = 0;
|
|
dword_8009F474 = 0;
|
|
target_800BDF00 = 0;
|
|
|
|
for (i = 0; i < 64; i++)
|
|
{
|
|
gBulNames_800BDC78[i] = 0;
|
|
}
|
|
|
|
tabako_dword_8009F2C0 = 0;
|
|
pVec_800ABBCC = NULL;
|
|
|
|
if (model == KMD_SNE_WET2) // wet suit in the docks
|
|
{
|
|
sna_set_flags1_8004E2F4(work, SNA_FLAG1_UNK29);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// Unused strings left in binary for some reason
|
|
static const char aPosDDD[] = "pos %d %d %d\n";
|
|
static const char aTurnDDD[] = "turn %d %d %d\n";
|
|
static const char aCeilFloorDD[] = "ceil floor %d %d\n";
|
|
static const char aStatus4x[] = "status %4x\n";
|
|
static const char aWeaponD[] = "weapon %d\n";
|
|
static const char aItemD[] = "item %d\n";
|
|
static const char aFlag4x[] = "flag %4x\n";
|
|
static const char aStanceD[] = "stance %d\n";
|
|
static const char aPadtoD[] = "padto %d\n";
|
|
static const char aTrapCheckD[] = "trap check %d\n";
|
|
static const char aPadX[] = "pad %x\n";
|
|
static const char aKaze[] = "kaze \n";
|
|
|
|
#define EXEC_LEVEL GV_ACTOR_LEVEL5
|
|
|
|
void *NewSnake(int name, int where, int argc, char **argv)
|
|
{
|
|
SnaInitWork *work;
|
|
|
|
work = GV_NewActor(EXEC_LEVEL, sizeof(SnaInitWork));
|
|
if (!work)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
GV_SetNamedActor(&work->actor, &sna_act_8005AD10, &sna_kill_8005B52C, "../snake_vr/sna_init.c");
|
|
|
|
if (sna_LoadSnake(work, name, where) < 0)
|
|
{
|
|
GV_DestroyActor(&work->actor);
|
|
return NULL;
|
|
}
|
|
|
|
snainit_actor_800A9424 = work;
|
|
return (void *)work;
|
|
}
|