mirror of
https://gitlab.com/ryandwyer/perfect-dark
synced 2026-06-25 09:02:06 -04:00
24135 lines
754 KiB
C
24135 lines
754 KiB
C
#include <ultra64.h>
|
|
#include "constants.h"
|
|
#include "game/chraction.h"
|
|
#include "game/chrai.h"
|
|
#include "game/debug.h"
|
|
#include "game/dlights.h"
|
|
#include "game/footstep.h"
|
|
#include "game/game_006900.h"
|
|
#include "game/pdmode.h"
|
|
#include "game/chr.h"
|
|
#include "game/body.h"
|
|
#include "game/prop.h"
|
|
#include "game/propsnd.h"
|
|
#include "game/objectives.h"
|
|
#include "game/atan2f.h"
|
|
#include "game/acosfasinf.h"
|
|
#include "game/bondgun.h"
|
|
#include "game/gunfx.h"
|
|
#include "game/game_0b0fd0.h"
|
|
#include "game/modelmgr.h"
|
|
#include "game/tex.h"
|
|
#include "game/camera.h"
|
|
#include "game/player.h"
|
|
#include "game/inv.h"
|
|
#include "game/playermgr.h"
|
|
#include "game/explosions.h"
|
|
#include "game/sparks.h"
|
|
#include "game/bg.h"
|
|
#include "game/game_1531a0.h"
|
|
#include "game/stagetable.h"
|
|
#include "game/env.h"
|
|
#include "game/lv.h"
|
|
#include "game/bot.h"
|
|
#include "game/botact.h"
|
|
#include "game/botcmd.h"
|
|
#include "game/botinv.h"
|
|
#include "game/mplayer/mplayer.h"
|
|
#include "game/pad.h"
|
|
#include "game/padhalllv.h"
|
|
#include "game/pak.h"
|
|
#include "game/propobj.h"
|
|
#include "game/wallhit.h"
|
|
#include "game/mpstats.h"
|
|
#include "bss.h"
|
|
#include "lib/joy.h"
|
|
#include "lib/main.h"
|
|
#include "lib/model.h"
|
|
#include "lib/snd.h"
|
|
#include "lib/rng.h"
|
|
#include "lib/mtx.h"
|
|
#include "lib/ailist.h"
|
|
#include "lib/anim.h"
|
|
#include "lib/collision.h"
|
|
#include "lib/vi.h"
|
|
#include "data.h"
|
|
#include "types.h"
|
|
|
|
s32 g_RecentQuipsPlayed[5];
|
|
u32 var8009cd84;
|
|
u32 var8009cd88;
|
|
u32 var8009cd8c;
|
|
u32 var8009cd90;
|
|
u32 var8009cd94;
|
|
u8 g_RecentQuipsIndex;
|
|
|
|
f32 g_EnemyAccuracyScale = 1;
|
|
f32 g_PlayerDamageRxScale = 1;
|
|
f32 g_PlayerDamageTxScale = 1;
|
|
f32 g_AttackWalkDurationScale = 1;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
s32 g_NumChrsWithPlayerTarget = 0;
|
|
s32 g_NumChrsSeenPlayer = 0;
|
|
s32 g_NumChrsSeenPlayerRecently = 0;
|
|
#endif
|
|
|
|
s32 g_NumChrsSeenPlayerRecently2 = 0;
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
const char *g_ChrActionNames[] = {
|
|
"ACT_INIT",
|
|
"ACT_STAND",
|
|
"ACT_KNEEL",
|
|
"ACT_ANIM",
|
|
"ACT_DIE",
|
|
"ACT_DEAD",
|
|
"ACT_ARGH",
|
|
"ACT_PREARGH",
|
|
"ACT_ATTACK",
|
|
"ACT_ATTACKWALK",
|
|
"ACT_ATTACKROLL",
|
|
"ACT_SIDESTEP",
|
|
"ACT_JUMPOUT",
|
|
"ACT_RUNPOS",
|
|
"ACT_PATROL",
|
|
"ACT_GOPOS",
|
|
"ACT_SURRENDER",
|
|
"ACT_LOOKATTARGET",
|
|
"ACT_SURPRISED",
|
|
"ACT_STARTALARM",
|
|
"ACT_THROWGRENADE",
|
|
"ACT_TURNDIR",
|
|
"ACT_TEST",
|
|
"ACT_BONDINTRO",
|
|
"ACT_BONDDIE",
|
|
"ACT_BONDMULTI",
|
|
"ACT_NULL",
|
|
"ACT_BOT_ATTACKSTAND",
|
|
"ACT_BOT_ATTACKKNEEL",
|
|
"ACT_BOT_ATTACKSTRAFE",
|
|
"ACT_DRUGGEDDROP",
|
|
"ACT_DRUGGEDKO",
|
|
"ACT_DRUGGEDCOMINGUP",
|
|
"ACT_ATTACKAMOUNT",
|
|
"ACT_ROBOTATTACK",
|
|
"ACT_SKJUMP",
|
|
"ACT_PUNCH",
|
|
"ACT_CUTFIRE",
|
|
};
|
|
|
|
const char *g_ChrMyActionNames[] = {
|
|
"NONE",
|
|
"NORMAL",
|
|
"COVERWAIT",
|
|
"GRENADEWAIT",
|
|
"WAITING",
|
|
"COVERGOTO",
|
|
"COVERBREAK",
|
|
"COVERSEEN",
|
|
"FLANKLEFT",
|
|
"FLANKRIGHT",
|
|
"DODGE",
|
|
"GRENADE",
|
|
"WAITSEEN",
|
|
"WITHDRAW",
|
|
"SHOOTING",
|
|
"SYNCSHOOT",
|
|
"WAITTIMEOUT",
|
|
"COVERTIMEOUT",
|
|
"TRACKING",
|
|
"RETREAT",
|
|
"SURRENDER",
|
|
"TALKING",
|
|
"LISTENING",
|
|
"GOTOALARM",
|
|
"BOTFRIENDFOLLOW",
|
|
"BOTHIDE",
|
|
"BOTPATH",
|
|
"BOTINJURED",
|
|
"BOTNORMAL",
|
|
"BOTSHOOTING",
|
|
"DRUGGED",
|
|
"PANIC",
|
|
"RUNFROMGRENADE",
|
|
"UNARMEDATTACK",
|
|
"MA_SKJUMP_START",
|
|
"MA_SKJUMP_AIR",
|
|
"MA_SKJUMP_LAND",
|
|
"MA_SKJUMP_LANDLOOP",
|
|
"MA_SKJUMP_SHOT",
|
|
"AIBOTDEADLIST",
|
|
"AIBOTINIT",
|
|
"AIBOTMAINLOOP",
|
|
"AIBOTGETITEM",
|
|
"AIBOTGOTOPOS",
|
|
"AIBOTGOTOPROP",
|
|
"AIBOTRUNAWAY",
|
|
"AIBOTDOWNLOAD",
|
|
"AIBOTATTACK",
|
|
"unused1",
|
|
"unused2",
|
|
"AIBOTFOLLOW",
|
|
"AIBOTDEFEND",
|
|
"FLANKBEST",
|
|
"FACING",
|
|
"PUNCHING",
|
|
};
|
|
|
|
const char *g_ChrActionNames2[] = {
|
|
"ACT_INIT",
|
|
"ACT_STAND",
|
|
"ACT_KNEEL",
|
|
"ACT_ANIM",
|
|
"ACT_DIE",
|
|
"ACT_DEAD",
|
|
"ACT_ARGH",
|
|
"ACT_PREARGH",
|
|
"ACT_ATTACK",
|
|
"ACT_ATTACKWALK",
|
|
"ACT_ATTACKROLL",
|
|
"ACT_SIDESTEP",
|
|
"ACT_JUMPOUT",
|
|
"ACT_RUNPOS",
|
|
"ACT_PATROL",
|
|
"ACT_GOPOS",
|
|
"ACT_SURRENDER",
|
|
"ACT_LOOKATTARGET",
|
|
"ACT_SURPRISED",
|
|
"ACT_STARTALARM",
|
|
"ACT_THROWGRENADE",
|
|
"ACT_TURNDIR",
|
|
"ACT_TEST",
|
|
"ACT_BONDINTRO",
|
|
"ACT_BONDDIE",
|
|
"ACT_BONDMULTI",
|
|
"ACT_NULL",
|
|
"ACT_BOT_ATTACKSTAND",
|
|
"ACT_BOT_ATTACKKNEEL",
|
|
"ACT_BOT_ATTACKSTRAFE",
|
|
"ACT_DRUGGEDDROP",
|
|
"ACT_DRUGGEDKO",
|
|
"ACT_DRUGGEDCOMINGUP",
|
|
"ACT_ATTACKAMOUNT",
|
|
"ACT_ROBOTATTACK",
|
|
"ACT_SKJUMP",
|
|
};
|
|
|
|
const char *g_ChrLiftActionNames[] = {
|
|
"NOTUSINGLIFT",
|
|
"WAITINGFORLIFT",
|
|
"ONLIFT",
|
|
"WAITINGONLIFT",
|
|
};
|
|
#endif
|
|
|
|
struct animtablerow g_DeathAnimsHumanLfoot[] = {
|
|
{ ANIM_DEATH_0020, 0, -1, 0.5, 0, 26, -1 },
|
|
{ 0, 0, 0, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanLshin[] = {
|
|
{ ANIM_DEATH_0020, 0, -1, 0.5, 0, 26, -1 },
|
|
{ 0, 0, 0, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanLthigh[] = {
|
|
{ ANIM_DEATH_0020, 0, -1, 0.5, 1, 26, -1 },
|
|
{ ANIM_DEATH_STOMACH_LONG, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0092, 1, -1, 0.4, 0, 42, 103 },
|
|
{ ANIM_0258, 1, -1, 0.5, 0, 43, 100 },
|
|
{ 0, 0, 0, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanRfoot[] = {
|
|
{ ANIM_DEATH_0020, 1, -1, 0.5, 0, 26, -1 },
|
|
{ 0, 0, 0, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanRshin[] = {
|
|
{ ANIM_DEATH_0020, 1, -1, 0.5, 0, 26, -1 },
|
|
{ 0, 0, 0, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanRthigh[] = {
|
|
{ ANIM_DEATH_0020, 1, -1, 0.5, 1, 26, -1 },
|
|
{ ANIM_DEATH_STOMACH_LONG, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0092, 0, -1, 0.4, 0, 42, 103 },
|
|
{ ANIM_0258, 0, -1, 0.5, 0, 43, 100 },
|
|
{ 0, 0, 0, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanPelvis[] = {
|
|
{ ANIM_DEATH_001A, 0, -1, 0.5, 0, 55, 39 },
|
|
{ ANIM_DEATH_001A, 1, -1, 0.5, 0, 55, 39 },
|
|
{ ANIM_DEATH_001C, 0, -1, 0.5, 1, 29, -1 },
|
|
{ ANIM_DEATH_001C, 1, -1, 0.5, 1, 29, -1 },
|
|
{ ANIM_DEATH_0021, 0, -1, 0.5, 0, 97, 64 },
|
|
{ ANIM_DEATH_0021, 1, -1, 0.5, 0, 97, 64 },
|
|
{ ANIM_DEATH_0023, 0, -1, 0.5, 0, 31, -1 },
|
|
{ ANIM_DEATH_0023, 1, -1, 0.5, 0, 31, -1 },
|
|
{ ANIM_DEATH_0024, 0, -1, 0.5, 0, 36, -1 },
|
|
{ ANIM_DEATH_0024, 1, -1, 0.5, 0, 36, -1 },
|
|
{ ANIM_DEATH_0025, 0, -1, 0.5, 0, 28, -1 },
|
|
{ ANIM_DEATH_0025, 1, -1, 0.5, 0, 28, -1 },
|
|
{ ANIM_0090, 0, -1, 0.6, 0, 157, 234 },
|
|
{ ANIM_0090, 1, -1, 0.6, 0, 157, 234 },
|
|
{ ANIM_0091, 0, -1, 0.6, 0, 75, 265 },
|
|
{ ANIM_0091, 1, -1, 0.6, 0, 75, 265 },
|
|
{ ANIM_0250, 0, -1, 0.5, 0, 65, 105 },
|
|
{ ANIM_0250, 1, -1, 0.5, 0, 65, 105 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanHead[] = {
|
|
{ ANIM_DEATH_001A, 0, -1, 0.5, 0, 55, 39 },
|
|
{ ANIM_DEATH_001A, 1, -1, 0.5, 0, 55, 39 },
|
|
{ ANIM_DEATH_001C, 0, -1, 0.5, 1, 29, -1 },
|
|
{ ANIM_DEATH_001C, 1, -1, 0.5, 1, 29, -1 },
|
|
{ ANIM_DEATH_0020, 0, -1, 0.5, 1, 26, -1 },
|
|
{ ANIM_DEATH_0020, 1, -1, 0.5, 1, 26, -1 },
|
|
{ ANIM_DEATH_0021, 0, -1, 0.5, 0, 97, 64 },
|
|
{ ANIM_DEATH_0021, 1, -1, 0.5, 0, 97, 64 },
|
|
{ ANIM_DEATH_0022, 0, -1, 0.5, 0, 94, 66 },
|
|
{ ANIM_DEATH_0022, 1, -1, 0.5, 0, 94, 66 },
|
|
{ ANIM_DEATH_0023, 0, -1, 0.5, 0, 31, -1 },
|
|
{ ANIM_DEATH_0023, 1, -1, 0.5, 0, 31, -1 },
|
|
{ ANIM_DEATH_0024, 0, -1, 0.5, 0, 36, -1 },
|
|
{ ANIM_DEATH_0024, 1, -1, 0.5, 0, 36, -1 },
|
|
{ ANIM_DEATH_0025, 0, -1, 0.5, 0, 28, -1 },
|
|
{ ANIM_DEATH_0025, 1, -1, 0.5, 0, 28, -1 },
|
|
{ ANIM_0038, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0038, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0251, 0, -1, 0.5, 0, 132, 201 },
|
|
{ ANIM_0251, 1, -1, 0.5, 0, 132, 201 },
|
|
{ ANIM_0252, 0, -1, 0.5, 0, 83, 150 },
|
|
{ ANIM_0252, 1, -1, 0.5, 0, 83, 150 },
|
|
{ ANIM_0256, 0, -1, 0.5, 0, 63, -1 },
|
|
{ ANIM_0256, 1, -1, 0.5, 0, 63, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanLhand[] = {
|
|
{ ANIM_DEATH_0020, 0, -1, 0.5, 0, 26, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanForearm[] = {
|
|
{ ANIM_DEATH_0020, 0, -1, 0.5, 0, 26, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanLbicep[] = {
|
|
{ ANIM_DEATH_0020, 0, -1, 0.5, 1, 26, -1 },
|
|
{ ANIM_008F, 1, -1, 0.45, 1, 52, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanRhand[] = {
|
|
{ ANIM_DEATH_0020, 1, -1, 0.5, 0, 26, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanRforearm[] = {
|
|
{ ANIM_DEATH_0020, 1, -1, 0.5, 0, 26, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanRbicep[] = {
|
|
{ ANIM_DEATH_0020, 1, -1, 0.5, 1, 26, -1 },
|
|
{ ANIM_008F, 0, -1, 0.45, 1, 52, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanTorso[] = {
|
|
{ ANIM_DEATH_001A, 0, -1, 0.5, 0, 55, 39 },
|
|
{ ANIM_DEATH_001A, 1, -1, 0.5, 0, 55, 39 },
|
|
{ ANIM_DEATH_001C, 0, -1, 0.5, 1, 29, -1 },
|
|
{ ANIM_DEATH_001C, 1, -1, 0.5, 1, 29, -1 },
|
|
{ ANIM_DEATH_0020, 0, -1, 0.5, 1, 26, -1 },
|
|
{ ANIM_DEATH_0020, 1, -1, 0.5, 1, 26, -1 },
|
|
{ ANIM_DEATH_0021, 0, -1, 0.5, 0, 97, 64 },
|
|
{ ANIM_DEATH_0021, 1, -1, 0.5, 0, 97, 64 },
|
|
{ ANIM_DEATH_0022, 0, -1, 0.5, 0, 94, 66 },
|
|
{ ANIM_DEATH_0022, 1, -1, 0.5, 0, 94, 66 },
|
|
{ ANIM_DEATH_0023, 0, -1, 0.5, 0, 31, -1 },
|
|
{ ANIM_DEATH_0023, 1, -1, 0.5, 0, 31, -1 },
|
|
{ ANIM_DEATH_0024, 0, -1, 0.5, 0, 36, -1 },
|
|
{ ANIM_DEATH_0024, 1, -1, 0.5, 0, 36, -1 },
|
|
{ ANIM_DEATH_0025, 0, -1, 0.5, 0, 28, -1 },
|
|
{ ANIM_DEATH_0025, 1, -1, 0.5, 0, 28, -1 },
|
|
{ ANIM_024E, 0, -1, 0.4, 0, 60, -1 },
|
|
{ ANIM_024E, 1, -1, 0.4, 0, 60, -1 },
|
|
{ ANIM_024F, 0, -1, 0.5, 0, 49, 80 },
|
|
{ ANIM_024F, 1, -1, 0.5, 0, 49, 80 },
|
|
{ ANIM_0253, 0, -1, 0.5, 1, 22, -1 },
|
|
{ ANIM_0253, 1, -1, 0.5, 1, 22, -1 },
|
|
{ ANIM_0254, 0, -1, 0.5, 0, 52, 75 },
|
|
{ ANIM_0254, 1, -1, 0.5, 0, 52, 75 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsHumanGun[] = {
|
|
{ ANIM_DEATH_001A, 0, -1, 0.5, 0, 55, 39 },
|
|
{ ANIM_DEATH_001A, 1, -1, 0.5, 0, 55, 39 },
|
|
{ ANIM_DEATH_001C, 0, -1, 0.5, 1, 29, -1 },
|
|
{ ANIM_DEATH_001C, 1, -1, 0.5, 1, 29, -1 },
|
|
{ ANIM_DEATH_0021, 0, -1, 0.5, 0, 97, 64 },
|
|
{ ANIM_DEATH_0021, 1, -1, 0.5, 0, 97, 64 },
|
|
{ ANIM_DEATH_0022, 0, -1, 0.5, 0, 94, 66 },
|
|
{ ANIM_DEATH_0022, 1, -1, 0.5, 0, 94, 66 },
|
|
{ ANIM_DEATH_0023, 0, -1, 0.5, 0, 31, -1 },
|
|
{ ANIM_DEATH_0023, 1, -1, 0.5, 0, 31, -1 },
|
|
{ ANIM_DEATH_0024, 0, -1, 0.5, 0, 36, -1 },
|
|
{ ANIM_DEATH_0024, 1, -1, 0.5, 0, 36, -1 },
|
|
{ ANIM_DEATH_0025, 0, -1, 0.5, 0, 28, -1 },
|
|
{ ANIM_DEATH_0025, 1, -1, 0.5, 0, 28, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_AnimTableHumanSlumped[] = {
|
|
{ ANIM_0019, 0, -1, 0.5, 0, 67, 54 },
|
|
{ ANIM_0019, 1, -1, 0.5, 0, 67, 54 },
|
|
{ ANIM_0257, 0, -1, 0.5, 0, 15, 80 },
|
|
{ ANIM_0257, 1, -1, 0.5, 0, 15, 80 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanLfoot[] = {
|
|
{ ANIM_0014, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0015, 1, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanLshin[] = {
|
|
{ ANIM_0014, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0015, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00BC, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00BD, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanLthigh[] = {
|
|
{ ANIM_0014, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0015, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_STOMACH_LONG, 1, 20, 0.4, 0, -1, -1 },
|
|
{ ANIM_00BA, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanRfoot[] = {
|
|
{ ANIM_0015, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0014, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0236, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanRshin[] = {
|
|
{ ANIM_0015, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0014, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00BE, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanRthigh[] = {
|
|
{ ANIM_0015, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0014, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_STOMACH_LONG, 0, 20, 0.4, 0, -1, -1 },
|
|
{ ANIM_00BF, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanPelvis[] = {
|
|
{ ANIM_DEATH_0022, 0, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_0022, 1, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_001A, 0, 15, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_001A, 1, 15, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_0023, 0, 10, 0.25, 0, -1, -1 },
|
|
{ ANIM_DEATH_0023, 1, 10, 0.25, 0, -1, -1 },
|
|
{ ANIM_00DA, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00F4, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanHead[] = {
|
|
{ ANIM_DEATH_0022, 0, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_0022, 1, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_001A, 0, 15, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_001A, 1, 15, 0.5, 0, -1, -1 },
|
|
{ ANIM_00F8, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00FB, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0101, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0113, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanLhand[] = {
|
|
{ ANIM_0012, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0013, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B8, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanForearm[] = {
|
|
{ ANIM_0010, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0011, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B4, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_021B, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanLbicep[] = {
|
|
{ ANIM_000E, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_000F, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_0022, 0, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B0, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B1, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_021C, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B5, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanRhand[] = {
|
|
{ ANIM_0013, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0012, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B9, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanRforearm[] = {
|
|
{ ANIM_0011, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0010, 1, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanRbicep[] = {
|
|
{ ANIM_000F, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_000E, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_0022, 1, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_0190, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B2, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B3, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B6, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_00B7, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanTorso[] = {
|
|
{ ANIM_DEATH_0022, 0, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_0022, 1, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_001A, 0, 15, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_001A, 1, 15, 0.5, 0, -1, -1 },
|
|
{ ANIM_0114, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0130, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsHumanGun[] = {
|
|
{ ANIM_DEATH_0022, 0, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_0022, 1, 20, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_001A, 0, 15, 0.5, 0, -1, -1 },
|
|
{ ANIM_DEATH_001A, 1, 15, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarLfoot[] = {
|
|
{ ANIM_0337, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033C, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033B, 1, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarLshin[] = {
|
|
{ ANIM_0337, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033C, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033B, 1, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarLthigh[] = {
|
|
{ ANIM_0337, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033C, 1, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033B, 1, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarRfoot[] = {
|
|
{ ANIM_0337, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033C, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033B, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarRshin[] = {
|
|
{ ANIM_0337, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033C, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033B, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarRthigh[] = {
|
|
{ ANIM_0337, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033C, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033B, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarPelvis[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarHead[] = {
|
|
{ ANIM_0339, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_0338, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033A, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarLhand[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033D, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarLforearm[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033D, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarLbicep[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033D, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarRhand[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033D, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarRforearm[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033D, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarRbicep[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033D, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarTorso[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033D, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarGun[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033D, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_DeathAnimsSkedarTail[] = {
|
|
{ ANIM_0336, 0, -1, 0.5, 0, -1, -1 },
|
|
{ ANIM_033D, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarLfoot[] = {
|
|
{ ANIM_038E, 0, -1, 1, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarLshin[] = {
|
|
{ ANIM_0390, 0, -1, 0.9, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarLthigh[] = {
|
|
{ ANIM_0390, 0, -1, 0.9, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarRfoot[] = {
|
|
{ ANIM_038E, 1, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarRshin[] = {
|
|
{ ANIM_0390, 1, -1, 0.9, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarRthigh[] = {
|
|
{ ANIM_0390, 1, -1, 0.9, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarPelvis[] = {
|
|
{ ANIM_038C, 0, -1, 0.9, 0, -1, -1 },
|
|
{ ANIM_038C, 1, -1, 0.9, 0, -1, -1 },
|
|
{ ANIM_0341, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarHead[] = {
|
|
{ ANIM_0341, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarLhand[] = {
|
|
{ ANIM_0343, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarLforearm[] = {
|
|
{ ANIM_038B, 0, -1, 0.9, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarLbicep[] = {
|
|
{ ANIM_038B, 0, -1, 0.9, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarRhand[] = {
|
|
{ ANIM_0343, 1, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarRforearm[] = {
|
|
{ ANIM_038B, 1, -1, 0.9, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarRbicep[] = {
|
|
{ ANIM_038B, 1, -1, 0.9, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarTorso[] = {
|
|
{ ANIM_038C, 0, -1, 0.9, 0, -1, -1 },
|
|
{ ANIM_038C, 1, -1, 0.9, 0, -1, -1 },
|
|
{ ANIM_0341, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarGun[] = {
|
|
{ ANIM_0343, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_InjuryAnimsSkedarTail[] = {
|
|
{ ANIM_0341, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtablerow g_SpecialDieAnims[] = {
|
|
{ ANIM_SPECIALDIE_FALLBACK, 0, -1, 0.5, 0, 149, 175 },
|
|
{ ANIM_SPECIALDIE_ROLL1, 0, -1, 0.5, 0, 115, 152 },
|
|
{ ANIM_SPECIALDIE_ROLL2, 0, -1, 0.5, 0, 115, 152 },
|
|
{ ANIM_SPECIALDIE_ROLL3, 0, -1, 0.5, 0, 115, 152 },
|
|
{ ANIM_SPECIALDIE_OVERRAILING, 0, -1, 0.5, 0, 83, 99 },
|
|
{ ANIM_022B, 0, -1, 0.5, 0, 0, 0 },
|
|
{ ANIM_022C, 0, -1, 0.5, 0, 0, 0 },
|
|
{ ANIM_022D, 0, -1, 0.5, 0, 0, 0 },
|
|
{ ANIM_022E, 0, -1, 0.5, 0, 0, 0 },
|
|
{ 0, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
struct animtable g_AnimTablesHuman[] = {
|
|
{ 0, NULL, NULL, 0, 0 },
|
|
{ HITPART_LFOOT, g_DeathAnimsHumanLfoot, g_InjuryAnimsHumanLfoot, 0, 0 },
|
|
{ HITPART_LSHIN, g_DeathAnimsHumanLshin, g_InjuryAnimsHumanLshin, 0, 0 },
|
|
{ HITPART_LTHIGH, g_DeathAnimsHumanLthigh, g_InjuryAnimsHumanLthigh, 0, 0 },
|
|
{ HITPART_RFOOT, g_DeathAnimsHumanRfoot, g_InjuryAnimsHumanRfoot, 0, 0 },
|
|
{ HITPART_RSHIN, g_DeathAnimsHumanRshin, g_InjuryAnimsHumanRshin, 0, 0 },
|
|
{ HITPART_RTHIGH, g_DeathAnimsHumanRthigh, g_InjuryAnimsHumanRthigh, 0, 0 },
|
|
{ HITPART_PELVIS, g_DeathAnimsHumanPelvis, g_InjuryAnimsHumanPelvis, 0, 0 },
|
|
{ HITPART_HEAD, g_DeathAnimsHumanHead, g_InjuryAnimsHumanHead, 0, 0 },
|
|
{ HITPART_LHAND, g_DeathAnimsHumanLhand, g_InjuryAnimsHumanLhand, 0, 0 },
|
|
{ HITPART_LFOREARM, g_DeathAnimsHumanForearm, g_InjuryAnimsHumanForearm, 0, 0 },
|
|
{ HITPART_LBICEP, g_DeathAnimsHumanLbicep, g_InjuryAnimsHumanLbicep, 0, 0 },
|
|
{ HITPART_RHAND, g_DeathAnimsHumanRhand, g_InjuryAnimsHumanRhand, 0, 0 },
|
|
{ HITPART_RFOREARM, g_DeathAnimsHumanRforearm, g_InjuryAnimsHumanRforearm, 0, 0 },
|
|
{ HITPART_RBICEP, g_DeathAnimsHumanRbicep, g_InjuryAnimsHumanRbicep, 0, 0 },
|
|
{ HITPART_TORSO, g_DeathAnimsHumanTorso, g_InjuryAnimsHumanTorso, 0, 0 },
|
|
{ HITPART_GUN, g_DeathAnimsHumanGun, g_InjuryAnimsHumanGun, 0, 0 },
|
|
{ HITPART_HAT, NULL, NULL, 0, 0 },
|
|
{ -1, NULL, NULL, 0, 0 },
|
|
};
|
|
|
|
struct animtable g_AnimTablesSkedar[] = {
|
|
{ 0, NULL, NULL, 0, 0 },
|
|
{ HITPART_LFOOT, g_DeathAnimsSkedarLfoot, g_InjuryAnimsSkedarLfoot, 0, 0 },
|
|
{ HITPART_LSHIN, g_DeathAnimsSkedarLshin, g_InjuryAnimsSkedarLshin, 0, 0 },
|
|
{ HITPART_LTHIGH, g_DeathAnimsSkedarLthigh, g_InjuryAnimsSkedarLthigh, 0, 0 },
|
|
{ HITPART_RFOOT, g_DeathAnimsSkedarRfoot, g_InjuryAnimsSkedarRfoot, 0, 0 },
|
|
{ HITPART_RSHIN, g_DeathAnimsSkedarRshin, g_InjuryAnimsSkedarRshin, 0, 0 },
|
|
{ HITPART_RTHIGH, g_DeathAnimsSkedarRthigh, g_InjuryAnimsSkedarRthigh, 0, 0 },
|
|
{ HITPART_PELVIS, g_DeathAnimsSkedarPelvis, g_InjuryAnimsSkedarPelvis, 0, 0 },
|
|
{ HITPART_HEAD, g_DeathAnimsSkedarHead, g_InjuryAnimsSkedarHead, 0, 0 },
|
|
{ HITPART_LHAND, g_DeathAnimsSkedarLhand, g_InjuryAnimsSkedarLhand, 0, 0 },
|
|
{ HITPART_LFOREARM, g_DeathAnimsSkedarLforearm, g_InjuryAnimsSkedarLforearm, 0, 0 },
|
|
{ HITPART_LBICEP, g_DeathAnimsSkedarLbicep, g_InjuryAnimsSkedarLbicep, 0, 0 },
|
|
{ HITPART_RHAND, g_DeathAnimsSkedarRhand, g_InjuryAnimsSkedarRhand, 0, 0 },
|
|
{ HITPART_RFOREARM, g_DeathAnimsSkedarRforearm, g_InjuryAnimsSkedarRforearm, 0, 0 },
|
|
{ HITPART_RBICEP, g_DeathAnimsSkedarRbicep, g_InjuryAnimsSkedarRbicep, 0, 0 },
|
|
{ HITPART_TORSO, g_DeathAnimsSkedarTorso, g_InjuryAnimsSkedarTorso, 0, 0 },
|
|
{ HITPART_GUN, g_DeathAnimsSkedarGun, g_InjuryAnimsSkedarGun, 0, 0 },
|
|
{ HITPART_HAT, g_DeathAnimsSkedarHead, g_InjuryAnimsSkedarHead, 0, 0 },
|
|
{ HITPART_TAIL, g_DeathAnimsSkedarTail, g_InjuryAnimsSkedarTail, 0, 0 },
|
|
{ -1, NULL, NULL, 0, 0 },
|
|
};
|
|
|
|
struct animtable g_AnimTablesDrCaroll[] = {
|
|
{ 0, NULL, NULL, 0, 0 },
|
|
{ -1, NULL, NULL, 0, 0 },
|
|
};
|
|
|
|
struct animtable g_AnimTablesEyespy[] = {
|
|
{ 0, NULL, NULL, 0, 0 },
|
|
{ -1, NULL, NULL, 0, 0 },
|
|
};
|
|
|
|
struct animtable g_AnimTablesRobot[] = {
|
|
{ 0, NULL, NULL, 0, 0 },
|
|
{ -1, NULL, NULL, 0, 0 },
|
|
};
|
|
|
|
struct animtable *g_AnimTablesByRace[] = {
|
|
g_AnimTablesHuman,
|
|
g_AnimTablesSkedar,
|
|
g_AnimTablesDrCaroll,
|
|
g_AnimTablesEyespy,
|
|
g_AnimTablesRobot,
|
|
};
|
|
|
|
/**
|
|
* A yeet anim is an animation config for a chr being launched by an explosion.
|
|
*/
|
|
struct yeetanim {
|
|
s16 animnum;
|
|
bool flip;
|
|
f32 speed;
|
|
f32 startframe;
|
|
f32 thudframe;
|
|
f32 endframe;
|
|
};
|
|
|
|
struct yeetanim g_YeetAnimsHuman[] = {
|
|
/* 0*/ { ANIM_0082, 0, 0.5, 9, 29, -1 },
|
|
/* 1*/ { ANIM_0082, 1, 0.5, 9, 29, -1 },
|
|
/* 2*/ { ANIM_008A, 0, 0.5, 11, 31, -1 },
|
|
/* 3*/ { ANIM_008A, 1, 0.5, 11, 31, -1 },
|
|
/* 4*/ { ANIM_0089, 0, 0.5, 6, 27, -1 },
|
|
/* 5*/ { ANIM_0089, 1, 0.5, 6, 27, -1 },
|
|
/* 6*/ { ANIM_008C, 0, 0.5, 29, 48, -1 },
|
|
/* 7*/ { ANIM_008C, 1, 0.5, 29, 48, -1 },
|
|
/* 8*/ { ANIM_008D, 0, 0.5, 29, 49, -1 },
|
|
/* 9*/ { ANIM_008D, 1, 0.5, 29, 49, -1 },
|
|
/*10*/ { ANIM_008E, 0, 0.5, 19, 42, -1 },
|
|
/*11*/ { ANIM_008E, 1, 0.5, 19, 42, -1 },
|
|
/*12*/ { ANIM_0086, 0, 0.5, 0, 60, -1 },
|
|
/*13*/ { ANIM_0086, 1, 0.5, 0, 60, -1 },
|
|
/*14*/ { ANIM_0087, 0, 0.5, 6, 29, -1 },
|
|
/*15*/ { ANIM_0087, 1, 0.5, 6, 29, -1 },
|
|
/*16*/ { ANIM_0084, 0, 0.5, 8, 25, -1 },
|
|
/*17*/ { ANIM_0084, 1, 0.5, 8, 25, -1 },
|
|
/*18*/ { ANIM_0085, 0, 0.5, 8, 25, -1 },
|
|
/*19*/ { ANIM_0085, 1, 0.5, 8, 25, -1 },
|
|
/*20*/ { ANIM_0088, 0, 0.5, 12, 29, -1 },
|
|
/*21*/ { ANIM_0088, 1, 0.5, 12, 29, -1 },
|
|
/*22*/ { ANIM_008B, 0, 0.5, 22, 41, -1 },
|
|
/*23*/ { ANIM_008B, 1, 0.5, 22, 41, -1 },
|
|
/*24*/ { 0, 0, 0.5, 0, 0, -1 },
|
|
};
|
|
|
|
s8 g_YeetAnimIndexesHumanAngle0[] = { 0, 1, 2, 3, 4, 5 };
|
|
s8 g_YeetAnimIndexesHumanAngle1[] = { 7, 9, 11 };
|
|
s8 g_YeetAnimIndexesHumanAngle2[] = { 6, 8, 10 };
|
|
s8 g_YeetAnimIndexesHumanAngle3[] = { 12, 15, 0 };
|
|
s8 g_YeetAnimIndexesHumanAngle4[] = { 13, 14, 0 };
|
|
s8 g_YeetAnimIndexesHumanAngle5[] = { 18, 19, 20, 21 };
|
|
s8 g_YeetAnimIndexesHumanAngle6[] = { 16, 22 };
|
|
s8 g_YeetAnimIndexesHumanAngle7[] = { 17, 23 };
|
|
|
|
struct yeetanim g_YeetAnimsSkedar[] = {
|
|
/* 0*/ { ANIM_033F, 0, 0.5, 0, -1, -1 },
|
|
/* 1*/ { ANIM_033F, 0, 0.5, 0, -1, -1 },
|
|
/* 2*/ { ANIM_033F, 0, 0.5, 0, -1, -1 },
|
|
/* 3*/ { ANIM_033F, 0, 0.5, 0, -1, -1 },
|
|
/* 4*/ { ANIM_033F, 0, 0.5, 0, -1, -1 },
|
|
/* 5*/ { ANIM_033F, 0, 0.5, 0, -1, -1 },
|
|
/* 6*/ { ANIM_033F, 0, 0.5, 0, -1, -1 },
|
|
/* 7*/ { ANIM_033F, 0, 0.5, 0, -1, -1 },
|
|
/* 8*/ { 0, 0, 0.5, 0, 0, -1 },
|
|
};
|
|
|
|
s8 g_YeetAnimIndexesSkedarAngle0[] = { 0 };
|
|
s8 g_YeetAnimIndexesSkedarAngle1[] = { 1 };
|
|
s8 g_YeetAnimIndexesSkedarAngle2[] = { 2 };
|
|
s8 g_YeetAnimIndexesSkedarAngle3[] = { 3 };
|
|
s8 g_YeetAnimIndexesSkedarAngle4[] = { 4 };
|
|
s8 g_YeetAnimIndexesSkedarAngle5[] = { 7 };
|
|
s8 g_YeetAnimIndexesSkedarAngle6[] = { 5 };
|
|
s8 g_YeetAnimIndexesSkedarAngle7[] = { 6 };
|
|
|
|
struct yeetanimindexlist {
|
|
s8 *indexes;
|
|
s32 count;
|
|
};
|
|
|
|
struct yeetanimindexlist g_YeetAnimIndexesByRaceAngle[][8] = {
|
|
{
|
|
{ g_YeetAnimIndexesHumanAngle0, 6 },
|
|
{ g_YeetAnimIndexesHumanAngle1, 3 },
|
|
{ g_YeetAnimIndexesHumanAngle3, 3 },
|
|
{ g_YeetAnimIndexesHumanAngle6, 2 },
|
|
{ g_YeetAnimIndexesHumanAngle5, 4 },
|
|
{ g_YeetAnimIndexesHumanAngle7, 2 },
|
|
{ g_YeetAnimIndexesHumanAngle4, 3 },
|
|
{ g_YeetAnimIndexesHumanAngle2, 3 },
|
|
}, {
|
|
{ g_YeetAnimIndexesSkedarAngle0, 1 },
|
|
{ g_YeetAnimIndexesSkedarAngle1, 1 },
|
|
{ g_YeetAnimIndexesSkedarAngle3, 1 },
|
|
{ g_YeetAnimIndexesSkedarAngle6, 1 },
|
|
{ g_YeetAnimIndexesSkedarAngle5, 1 },
|
|
{ g_YeetAnimIndexesSkedarAngle7, 1 },
|
|
{ g_YeetAnimIndexesSkedarAngle4, 1 },
|
|
{ g_YeetAnimIndexesSkedarAngle2, 1 },
|
|
},
|
|
};
|
|
|
|
struct attackanimconfig var800656c0[] = {
|
|
{ ANIM_0002, 28, 0, 0, 0, -1, 23, 54, -1, -1, 18, 54, 0.87252569198608, -0.52351540327072, 1.0470308065414, -0.34901028871536, 1.6000000238419, 1.7999999523163 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80065750 = { var800656c0, 0xffffffff };
|
|
|
|
struct attackanimconfig var80065758[] = {
|
|
{ ANIM_0032, 37, 0, 0, 0, -1, 30, 81, -1, -1, 25, 81, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.69802057743073, 1.6000000238419, 1.75 },
|
|
{ ANIM_0003, 27, 0, 0, 0, -1, 22, 61, -1, -1, 17, 61, 0.87252569198608, -0.26175770163536, 0.69802057743073, -0.69802057743073, 2, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80065830 = { var80065758, 0xffffffff };
|
|
|
|
struct attackanimconfig var80065838[] = {
|
|
{ ANIM_0032, 37, 0, 0, 0, -1, 30, 81, -1, -1, 25, 81, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.69802057743073, 1.6000000238419, 1.75 },
|
|
{ ANIM_0003, 27, 0, 0, 0, -1, 22, 61, -1, -1, 17, 61, 0.87252569198608, -0.26175770163536, 0.69802057743073, -0.69802057743073, 2, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80065910 = { var80065838, 0xffffffff };
|
|
|
|
struct attackanimconfig var80065918[] = {
|
|
{ ANIM_0004, 19, 0, 1.5707963705063, 0, -1, 19, 61, -1, -1, 14, 61, 0.87252569198608, -0.34901028871536, 0.43626284599304, -1.0470308065414, 2.5, 2.5 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var800659a8 = { var80065918, 0xffffffff };
|
|
|
|
struct attackanimconfig var800659b0[] = {
|
|
{ ANIM_0006, 27, 0, 0, 0, -1, 39, 74, -1, -1, 34, 74, 0.87252569198608, -0.69802057743073, 0.7852731347084, -0.69802057743073, 1.5, 1.5 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80065a40 = { var800659b0, 0xffffffff };
|
|
|
|
struct attackanimconfig var80065a48[] = {
|
|
{ ANIM_034A, 20, 0, 0, 0, -1, 25, 50, -1, -1, 10, 50, 0.34901028871536, -0.34901028871536, 0.52351540327072, -0.52351540327072, 1, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80065ad8 = { var80065a48, 0xffffffff };
|
|
|
|
struct attackanimgroup *g_StandHeavyAttackAnims[][32] = {
|
|
{
|
|
// RACE_HUMAN
|
|
&var80065750, &var80065830, &var80065830, &var80065830,
|
|
&var80065830, &var80065830, &var80065830, &var80065830,
|
|
&var80065830, &var80065830, &var800659a8, &var800659a8,
|
|
&var800659a8, &var800659a8, &var800659a8, &var800659a8,
|
|
&var80065a40, &var80065a40, &var80065a40, &var80065a40,
|
|
&var80065a40, &var80065a40, &var80065910, &var80065910,
|
|
&var80065910, &var80065910, &var80065910, &var80065910,
|
|
&var80065910, &var80065910, &var80065910, &var80065750,
|
|
}, {
|
|
// RACE_SKEDAR
|
|
&var80065ad8, &var80065ad8, &var80065ad8, &var80065ad8,
|
|
&var80065ad8, &var80065ad8, &var80065ad8, &var80065ad8,
|
|
&var80065ad8, &var80065ad8, &var80065ad8, &var80065ad8,
|
|
&var80065ad8, &var80065ad8, &var80065ad8, &var80065ad8,
|
|
&var80065ad8, &var80065ad8, &var80065ad8, &var80065ad8,
|
|
&var80065ad8, &var80065ad8, &var80065ad8, &var80065ad8,
|
|
&var80065ad8, &var80065ad8, &var80065ad8, &var80065ad8,
|
|
&var80065ad8, &var80065ad8, &var80065ad8, &var80065ad8,
|
|
},
|
|
};
|
|
|
|
struct attackanimconfig var80065be0[] = {
|
|
{ ANIM_0041, 26, 0, 0, 12, 140, 58, 92, 60, 79, 20, 120, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.69802057743073, 0, 0 },
|
|
{ ANIM_0044, 0, 0, 0, 17, 100, 25, 87, 30, 55, 20, 93, 0.87252569198608, -0.69802057743073, 0.69802057743073, -1.0470308065414, 0, 0 },
|
|
{ ANIM_0045, 0, 0, 0, 12, 64, 19, 51, 24, 46, 14, 58, 0.87252569198608, -0.69802057743073, 0.52351540327072, -0.7852731347084, 0, 0 },
|
|
{ ANIM_0046, 22, 0, 0, 4, 69, 22, 49, 22, 33, 8, 58, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.7852731347084, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80065d48 = { var80065be0, 0xffffffff };
|
|
|
|
struct attackanimconfig var80065d50[] = {
|
|
{ ANIM_0041, 26, 0, 0, 12, 140, 58, 92, 60, 79, 20, 120, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.69802057743073, 0, 0 },
|
|
{ ANIM_0046, 22, 0, 0, 4, 69, 22, 49, 22, 33, 8, 58, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.7852731347084, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80065e28 = { var80065d50, 0xffffffff };
|
|
|
|
struct attackanimconfig var80065e30[] = {
|
|
{ ANIM_0041, 26, 0, 0, 12, 140, 58, 92, 60, 79, 20, 120, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.69802057743073, 0, 0 },
|
|
{ ANIM_0046, 22, 0, 0, 4, 69, 22, 49, 22, 33, 8, 58, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.7852731347084, 0, 0 },
|
|
{ ANIM_0049, 0, 0, 1.5707963705063, 7, 130, 45, 93, 56, 73, 26, 107, 0.87252569198608, -0.69802057743073, 0.34901028871536, -0.52351540327072, 0, 0 },
|
|
{ ANIM_004A, 15, 0, 1.5707963705063, 5, 76, 20, 31, 31, 38, 15, 49, 0.87252569198608, -0.69802057743073, 0.52351540327072, -1.0470308065414, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80065f98 = { var80065e30, 0xffffffff };
|
|
|
|
struct attackanimconfig var80065fa0[] = {
|
|
{ ANIM_0041, 26, 0, 0, 12, 140, 58, 92, 60, 79, 20, 120, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.69802057743073, 0, 0 },
|
|
{ ANIM_0046, 22, 0, 0, 4, 69, 22, 49, 22, 33, 8, 58, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.7852731347084, 0, 0 },
|
|
{ ANIM_0047, 0, 0, 4.7123889923096, 7, 139, 54, 105, 61, 88, 26, 120, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.61076802015305, 0, 0 },
|
|
{ ANIM_0048, 19, 0, 4.7123889923096, 4, 79, 21, 50, 26, 42, 10, 64, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.61076802015305, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066108 = { var80065fa0, 0xffffffff };
|
|
|
|
struct attackanimconfig var80066110[] = {
|
|
{ ANIM_004A, 19, 0, 1.5707963705063, 5, 76, 20, 31, 31, 38, 15, 49, 0.87252569198608, -0.69802057743073, 0.52351540327072, -1.0470308065414, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var800661a0 = { var80066110, 0xffffffff };
|
|
|
|
struct attackanimconfig var800661a8[] = {
|
|
{ ANIM_0048, 19, 0, 4.7123889923096, 4, 79, 21, 50, 26, 42, 10, 64, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.61076802015305, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066238 = { var800661a8, 0xffffffff };
|
|
|
|
struct attackanimconfig var80066240[] = {
|
|
{ ANIM_034A, 20, 0, 0, 0, -1, 25, 50, -1, -1, 10, 50, 0.34901028871536, -0.34901028871536, 0.52351540327072, -0.52351540327072, 1, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var800662d0 = { var80066240, 0xffffffff };
|
|
|
|
struct attackanimgroup *g_StandLightAttackAnims[][32] = {
|
|
{
|
|
// RACE_HUMAN
|
|
&var80065d48, &var80065d48, &var80065e28, &var80065e28,
|
|
&var80065e28, &var80065f98, &var80065f98, &var80065f98,
|
|
&var80065f98, &var80065f98, &var800661a0, &var800661a0,
|
|
&var800661a0, &var800661a0, &var800661a0, &var800661a0,
|
|
&var80066238, &var80066238, &var80066238, &var80066238,
|
|
&var80066238, &var80066238, &var80066108, &var80066108,
|
|
&var80066108, &var80066108, &var80066108, &var80065e28,
|
|
&var80065e28, &var80065e28, &var80065d48, &var80065d48,
|
|
}, {
|
|
// RACE_SKEDAR
|
|
&var800662d0, &var800662d0, &var800662d0, &var800662d0,
|
|
&var800662d0, &var800662d0, &var800662d0, &var800662d0,
|
|
&var800662d0, &var800662d0, &var800662d0, &var800662d0,
|
|
&var800662d0, &var800662d0, &var800662d0, &var800662d0,
|
|
&var800662d0, &var800662d0, &var800662d0, &var800662d0,
|
|
&var800662d0, &var800662d0, &var800662d0, &var800662d0,
|
|
&var800662d0, &var800662d0, &var800662d0, &var800662d0,
|
|
&var800662d0, &var800662d0, &var800662d0, &var800662d0,
|
|
},
|
|
};
|
|
|
|
|
|
struct attackanimconfig var800663d8[] = {
|
|
{ ANIM_007A, 26, 0, 0, 7, 92, 28, 68, -1, -1, 11, 73, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.69802057743073, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066468 = { var800663d8, 0xffffffff };
|
|
|
|
struct attackanimconfig var80066470[] = {
|
|
{ ANIM_007B, 26, 0, 1.5707963705063, 9, 112, 38, 87, -1, -1, 19, 98, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.43626284599304, 0, 0 },
|
|
{ ANIM_007D, 25, 0, 1.5707963705063, 10, 112, 32, 86, -1, -1, 19, 97, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.43626284599304, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066548 = { var80066470, 0xffffffff };
|
|
|
|
struct attackanimconfig var80066550[] = {
|
|
{ ANIM_007C, 39, 0, 4.7123889923096, 22, 127, 44, 102, -1, -1, 28, 112, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.43626284599304, 0, 0 },
|
|
{ ANIM_007E, 39, 0, 4.7123889923096, 23, 130, 46, 100, -1, -1, 30, 110, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.43626284599304, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066628 = { var80066550, 0xffffffff };
|
|
|
|
struct attackanimconfig var80066630[] = {
|
|
{ ANIM_034A, 20, 0, 0, 0, -1, 25, 50, -1, -1, 10, 50, 0.34901028871536, -0.34901028871536, 0.52351540327072, -0.52351540327072, 1, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var800666c0 = { var80066630, 0xffffffff };
|
|
|
|
struct attackanimgroup *g_StandDualAttackAnims[][32] = {
|
|
{
|
|
// RACE_HUMAN
|
|
&var80066468, &var80066468, &var80066468, &var80066468,
|
|
&var80066468, &var80066548, &var80066548, &var80066548,
|
|
&var80066548, &var80066548, &var80066548, &var80066548,
|
|
&var80066548, &var80066548, &var80066548, &var80066548,
|
|
&var80066628, &var80066628, &var80066628, &var80066628,
|
|
&var80066628, &var80066628, &var80066628, &var80066628,
|
|
&var80066628, &var80066628, &var80066628, &var80066468,
|
|
&var80066468, &var80066468, &var80066468, &var80066468,
|
|
}, {
|
|
// RACE_SKEDAR
|
|
&var800666c0, &var800666c0, &var800666c0, &var800666c0,
|
|
&var800666c0, &var800666c0, &var800666c0, &var800666c0,
|
|
&var800666c0, &var800666c0, &var800666c0, &var800666c0,
|
|
&var800666c0, &var800666c0, &var800666c0, &var800666c0,
|
|
&var800666c0, &var800666c0, &var800666c0, &var800666c0,
|
|
&var800666c0, &var800666c0, &var800666c0, &var800666c0,
|
|
&var800666c0, &var800666c0, &var800666c0, &var800666c0,
|
|
&var800666c0, &var800666c0, &var800666c0, &var800666c0,
|
|
},
|
|
};
|
|
|
|
struct attackanimconfig var800667c8[] = {
|
|
{ ANIM_0007, 27, 0, 0, 0, -1, 35, 75, -1, -1, 31, 75, 0.87252569198608, -0.69802057743073, 0.90742671489716, -0.69802057743073, 1.5, 1.5 },
|
|
{ ANIM_KNEEL_TWO_HANDED_GUN, 24, 0, 0, 0, -1, 46, 98, -1, -1, 41, 98, 0.87252569198608, -0.52351540327072, 1.1342834234238, -0.69802057743073, 1.6000000238419, 1.6000000238419 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var800668a0 = { var800667c8, 0xffffffff };
|
|
|
|
struct attackanimconfig var800668a8[] = {
|
|
{ ANIM_0009, 26, 0, 0, 0, -1, 34, 87, -1, -1, 29, 87, 0.87252569198608, -0.52351540327072, 0.69802057743073, -0.95977824926376, 1.6000000238419, 2 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066938 = { var800668a8, 0xffffffff };
|
|
|
|
struct attackanimconfig var80066940[] = {
|
|
{ ANIM_000A, 28, 0, 0, 0, -1, 36, 88, -1, -1, 31, 88, 0.87252569198608, -0.69802057743073, 0.87252569198608, -0.43626284599304, 1.6000000238419, 1.5 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var800669d0 = { var80066940, 0xffffffff };
|
|
|
|
struct attackanimconfig var800669d8[] = {
|
|
{ ANIM_034A, 20, 0, 0, 0, -1, 25, 50, -1, -1, 10, 50, 0.34901028871536, -0.34901028871536, 0.52351540327072, -0.52351540327072, 1, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066a68 = { var800669d8, 0xffffffff };
|
|
|
|
struct attackanimgroup *g_KneelHeavyAttackAnims[][32] = {
|
|
{
|
|
&var800668a0, &var800668a0, &var800668a0, &var800668a0,
|
|
&var800668a0, &var800668a0, &var800668a0, &var800668a0,
|
|
&var800668a0, &var800668a0, &var80066938, &var80066938,
|
|
&var80066938, &var80066938, &var80066938, &var80066938,
|
|
&var800669d0, &var800669d0, &var800669d0, &var800669d0,
|
|
&var800669d0, &var800669d0, &var800668a0, &var800668a0,
|
|
&var800668a0, &var800668a0, &var800668a0, &var800668a0,
|
|
&var800668a0, &var800668a0, &var800668a0, &var800668a0,
|
|
}, {
|
|
&var80066a68, &var80066a68, &var80066a68, &var80066a68,
|
|
&var80066a68, &var80066a68, &var80066a68, &var80066a68,
|
|
&var80066a68, &var80066a68, &var80066a68, &var80066a68,
|
|
&var80066a68, &var80066a68, &var80066a68, &var80066a68,
|
|
&var80066a68, &var80066a68, &var80066a68, &var80066a68,
|
|
&var80066a68, &var80066a68, &var80066a68, &var80066a68,
|
|
&var80066a68, &var80066a68, &var80066a68, &var80066a68,
|
|
&var80066a68, &var80066a68, &var80066a68, &var80066a68,
|
|
},
|
|
};
|
|
|
|
struct attackanimconfig var80066b70[] = {
|
|
{ ANIM_KNEEL_SHOOT_RIGHT_HAND, 25, 0, 0, 12, 132, 55, 87, 67, 87, 26, 111, 0.87252569198608, -0.69802057743073, 0.61076802015305, -0.7852731347084, 0, 0 },
|
|
{ ANIM_004C, 26, 0, 0, 8, 89, 31, 63, 41, 51, 21, 80, 0.87252569198608, -0.69802057743073, 0.34901028871536, -1.1342834234238, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066c48 = { var80066b70, 0xffffffff };
|
|
|
|
struct attackanimconfig var80066c50[] = {
|
|
{ ANIM_004F, 47, 0, 1.5707963705063, 7, 128, 33, 86, 47, 74, 23, 106, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.7852731347084, 0, 0 },
|
|
{ ANIM_0050, 18, 0, 1.5707963705063, 7, 78, 28, 52, 35, 45, 15, 66, 0.87252569198608, -0.087252572178841, 0.69802057743073, -0.7852731347084, 1.5, 1 },
|
|
{ ANIM_0051, 20, 0, 1.5707963705063, 13, 92, 37, 67, 42, 55, 25, 84, 0.87252569198608, -0.52351540327072, 0.34901028871536, -0.69802057743073, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066d70 = { var80066c50, 0xffffffff };
|
|
|
|
struct attackanimconfig var80066d78[] = {
|
|
{ ANIM_004D, 28, 0, 4.7123889923096, 15, 124, 38, 97, 60, 84, 20, 106, 0.87252569198608, -0.69802057743073, 0.52351540327072, -0.87252569198608, 0, 0 },
|
|
{ ANIM_004E, 23, 0, 4.7123889923096, 0, 85, 32, 38, 38, 60, 14, 71, 0.87252569198608, -0.69802057743073, 0.61076802015305, -0.95977824926376, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066e50 = { var80066d78, 0xffffffff };
|
|
|
|
struct attackanimconfig var80066e58[] = {
|
|
{ ANIM_034A, 20, 0, 0, 0, -1, 25, 50, -1, -1, 10, 50, 0.34901028871536, -0.34901028871536, 0.52351540327072, -0.52351540327072, 1, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80066ee8 = { var80066e58, 0xffffffff };
|
|
|
|
struct attackanimgroup *g_KneelLightAttackAnims[][32] = {
|
|
{
|
|
&var80066c48, &var80066c48, &var80066c48, &var80066c48,
|
|
&var80066c48, &var80066c48, &var80066c48, &var80066c48,
|
|
&var80066c48, &var80066c48, &var80066d70, &var80066d70,
|
|
&var80066d70, &var80066d70, &var80066d70, &var80066d70,
|
|
&var80066e50, &var80066e50, &var80066e50, &var80066e50,
|
|
&var80066e50, &var80066e50, &var80066c48, &var80066c48,
|
|
&var80066c48, &var80066c48, &var80066c48, &var80066c48,
|
|
&var80066c48, &var80066c48, &var80066c48, &var80066c48,
|
|
}, {
|
|
&var80066ee8, &var80066ee8, &var80066ee8, &var80066ee8,
|
|
&var80066ee8, &var80066ee8, &var80066ee8, &var80066ee8,
|
|
&var80066ee8, &var80066ee8, &var80066ee8, &var80066ee8,
|
|
&var80066ee8, &var80066ee8, &var80066ee8, &var80066ee8,
|
|
&var80066ee8, &var80066ee8, &var80066ee8, &var80066ee8,
|
|
&var80066ee8, &var80066ee8, &var80066ee8, &var80066ee8,
|
|
&var80066ee8, &var80066ee8, &var80066ee8, &var80066ee8,
|
|
&var80066ee8, &var80066ee8, &var80066ee8, &var80066ee8,
|
|
},
|
|
};
|
|
|
|
struct attackanimconfig var80066ff0[] = {
|
|
{ ANIM_0074, 22, 0, 0, 10, 111, 34, 87, -1, -1, 17, 104, 0.87252569198608, -0.69802057743073, 0.61076802015305, -0.7852731347084, 0, 0 },
|
|
{ ANIM_0077, 25, 0, 0, 9, 92, 33, 62, -1, -1, 18, 69, 0.87252569198608, -0.69802057743073, 0.61076802015305, -0.7852731347084, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var800670c8 = { var80066ff0, 0xffffffff };
|
|
|
|
struct attackanimconfig var800670d0[] = {
|
|
{ ANIM_0075, 28, 0, 1.5707963705063, 15, 108, 34, 73, -1, -1, 17, 93, 0.87252569198608, -0.69802057743073, 0.52351540327072, -0.7852731347084, 0, 0 },
|
|
{ ANIM_0078, 19, 0, 1.5707963705063, 3, 95, 30, 64, -1, -1, 14, 71, 0.87252569198608, -0.69802057743073, 0.52351540327072, -0.7852731347084, 1.5, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var800671a8 = { var800670d0, 0xffffffff };
|
|
|
|
struct attackanimconfig var800671b0[] = {
|
|
{ ANIM_0076, 31, 0, 4.7123889923096, 14, 111, 40, 83, -1, -1, 21, 94, 0.87252569198608, -0.69802057743073, 0.52351540327072, -0.7852731347084, 0, 0 },
|
|
{ ANIM_0079, 26, 0, 4.7123889923096, 7, 89, 34, 60, -1, -1, 20, 68, 0.87252569198608, -0.69802057743073, 0.52351540327072, -0.7852731347084, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80067288 = { var800671b0, 0xffffffff };
|
|
|
|
struct attackanimconfig var80067290[] = {
|
|
{ ANIM_034A, 20, 0, 0, 0, -1, 25, 50, -1, -1, 10, 50, 0.34901028871536, -0.34901028871536, 0.52351540327072, -0.52351540327072, 1, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80067320 = { var80067290, 0xffffffff };
|
|
|
|
struct attackanimgroup *g_KneelDualAttackAnims[][32] = {
|
|
{
|
|
&var800670c8, &var800670c8, &var800670c8, &var800670c8,
|
|
&var800670c8, &var800670c8, &var800670c8, &var800670c8,
|
|
&var800670c8, &var800670c8, &var800671a8, &var800671a8,
|
|
&var800671a8, &var800671a8, &var800671a8, &var800671a8,
|
|
&var80067288, &var80067288, &var80067288, &var80067288,
|
|
&var80067288, &var80067288, &var800670c8, &var800670c8,
|
|
&var800670c8, &var800670c8, &var800670c8, &var800670c8,
|
|
&var800670c8, &var800670c8, &var800670c8, &var800670c8,
|
|
}, {
|
|
&var80067320, &var80067320, &var80067320, &var80067320,
|
|
&var80067320, &var80067320, &var80067320, &var80067320,
|
|
&var80067320, &var80067320, &var80067320, &var80067320,
|
|
&var80067320, &var80067320, &var80067320, &var80067320,
|
|
&var80067320, &var80067320, &var80067320, &var80067320,
|
|
&var80067320, &var80067320, &var80067320, &var80067320,
|
|
&var80067320, &var80067320, &var80067320, &var80067320,
|
|
&var80067320, &var80067320, &var80067320, &var80067320,
|
|
},
|
|
};
|
|
|
|
struct attackanimconfig g_RollAttackAnims[] = {
|
|
{ ANIM_000B, 76, 0, 0, 20, -1, 98, 161, -1, -1, 93, 161, 0.87252569198608, -0.52351540327072, 0.69802057743073, -0.69802057743073, 1.7000000476837, 2 },
|
|
{ ANIM_000C, 58, 0, 0, 10, -1, 77, 104, -1, -1, 72, 104, 0.87252569198608, -0.34901028871536, 0.61076802015305, -0.69802057743073, 1.5499999523163, 1.5 },
|
|
{ ANIM_000D, 61, 0, 0, 10, -1, 83, 128, -1, -1, 78, 128, 0.87252569198608, -0.52351540327072, 0.87252569198608, -0.52351540327072, 1.2000000476837, 1.2999999523163 },
|
|
{ ANIM_0027, 63, 0, 0, 10, -1, 73, 114, -1, -1, 68, 114, 0.87252569198608, -0.52351540327072, 0.61076802015305, -0.61076802015305, 1.6499999761581, 1.5 },
|
|
{ ANIM_000B, 76, 0, 0, 20, 76, 98, 161, -1, -1, 93, 161, 0.87252569198608, -0.52351540327072, 0.69802057743073, -0.69802057743073, 1.7000000476837, 2 },
|
|
{ ANIM_000C, 58, 0, 0, 10, 63, 77, 104, -1, -1, 72, 104, 0.87252569198608, -0.34901028871536, 0.61076802015305, -0.69802057743073, 1.5499999523163, 1.5 },
|
|
{ ANIM_000D, 61, 0, 0, 10, 56, 83, 128, -1, -1, 78, 128, 0.87252569198608, -0.52351540327072, 0.87252569198608, -0.52351540327072, 1.2000000476837, 1.2999999523163 },
|
|
{ ANIM_0027, 63, 0, 0, 10, 50, 73, 114, -1, -1, 68, 114, 0.87252569198608, -0.52351540327072, 0.61076802015305, -0.61076802015305, 1.6499999761581, 1.5 },
|
|
{ ANIM_0045, 0, 0, 0, 7, 64, 19, 51, 24, 46, 14, 58, 0.87252569198608, -0.69802057743073, 0.52351540327072, -0.7852731347084, 0, 0 },
|
|
{ ANIM_004A, 0, 0, 1.5707963705063, 14, 76, 26, 31, 31, 38, 15, 49, 0.87252569198608, -0.69802057743073, 0.52351540327072, -1.0470308065414, 0, 0 },
|
|
{ ANIM_004C, 26, 0, 0, 25, 89, 41, 63, 41, 51, 21, 80, 0.87252569198608, -0.69802057743073, 0.34901028871536, -1.1342834234238, 0, 0 },
|
|
{ ANIM_0050, 18, 0, 1.5707963705063, 11, 78, 33, 52, 35, 45, 15, 66, 0.87252569198608, -0.087252572178841, 0.69802057743073, -0.7852731347084, 1.5, 1 },
|
|
{ ANIM_007A, 26, 0, 0, 7, 92, 28, 68, -1, -1, 11, 73, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.69802057743073, 0, 0 },
|
|
{ ANIM_007B, 26, 0, 1.5707963705063, 9, 112, 38, 87, -1, -1, 19, 98, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.43626284599304, 0, 0 },
|
|
{ ANIM_0074, 22, 0, 0, 10, 11, 34, 87, -1, -1, 17, 104, 0.87252569198608, -0.69802057743073, 0.61076802015305, -0.7852731347084, 0, 0 },
|
|
{ ANIM_0075, 28, 0, 1.5707963705063, 15, 108, 34, 73, -1, -1, 17, 93, 0.87252569198608, -0.69802057743073, 0.52351540327072, -0.7852731347084, 0, 0 },
|
|
{ ANIM_007A, 26, 0, 0, 7, 92, 28, 68, -1, -1, 11, 73, 0.87252569198608, -0.69802057743073, 0.69802057743073, -0.69802057743073, 0, 0 },
|
|
{ ANIM_007D, 25, 0, 1.5707963705063, 10, 112, 32, 86, -1, -1, 19, 97, 0.87252569198608, -0.69802057743073, 0.43626284599304, -0.43626284599304, 0, 0 },
|
|
{ ANIM_0077, 25, 0, 0, 9, 92, 33, 62, -1, -1, 18, 69, 0.87252569198608, -0.69802057743073, 0.61076802015305, -0.7852731347084, 0, 0 },
|
|
{ ANIM_0078, 19, 0, 1.5707963705063, 3, 95, 30, 64, -1, -1, 14, 71, 0.87252569198608, -0.69802057743073, 0.52351540327072, -0.7852731347084, 1.5, 1 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimconfig g_AttackAnimHeavyWalk = { ANIM_0030, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 1.3999999761581, 1.2999999523163 };
|
|
struct attackanimconfig g_AttackAnimHeavyRun = { ANIM_0031, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 1.1000000238419, 1.2000000476837 };
|
|
struct attackanimconfig g_AttackAnimLightWalk = { ANIM_0052, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 };
|
|
struct attackanimconfig g_AttackAnimLightRun = { ANIM_0055, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 };
|
|
struct attackanimconfig g_AttackAnimDualWalk = { ANIM_006C, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 };
|
|
struct attackanimconfig g_AttackAnimDualRun = { ANIM_006E, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 };
|
|
struct attackanimconfig g_AttackAnimDualCrossedWalk = { ANIM_006D, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 };
|
|
struct attackanimconfig g_AttackAnimDualCrossedRun = { ANIM_006F, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 };
|
|
|
|
struct attackanimconfig var80067c50[] = {
|
|
{ ANIM_0057, 0, 0, 1.5707963705063, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 },
|
|
{ ANIM_0056, 0, 0, 4.7123889923096, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimconfig var80067d28[] = { ANIM_SNIPING_GETDOWN, 0, 0, 0, 0, 236, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 };
|
|
|
|
struct attackanimconfig var80067d70[] = {
|
|
{ ANIM_SNIPING_ONGROUND, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 },
|
|
{ ANIM_SNIPING_GETUP, 0, 0, 0, 0, -1, 0, 0, -1, -1, 0, 0, 0.87252569198608, -0.52351540327072, 0.52351540327072, -0.52351540327072, 0, 0 },
|
|
{ 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
|
};
|
|
|
|
struct attackanimgroup var80067e48 = { var80067d28, 0xffffffff };
|
|
|
|
struct attackanimgroup *g_LieAttackAnims = &var80067e48;
|
|
|
|
u32 g_StageFlags = 0;
|
|
|
|
struct chrdata *g_BgChrs = NULL;
|
|
s16 *g_BgChrnums = NULL;
|
|
s32 g_NumBgChrs = 0;
|
|
|
|
s16 *g_TeamList = NULL;
|
|
s16 *g_SquadronList = NULL;
|
|
|
|
struct var80067e6c var80067e6c[] = {
|
|
{ ANIM_0028, 0 },
|
|
{ ANIM_RUNNING_TWOHANDGUN, 0 },
|
|
{ ANIM_0029, 0 },
|
|
{ ANIM_006B, 0 },
|
|
{ ANIM_RUNNING_ONEHANDGUN, 0 },
|
|
{ ANIM_005A, 0 },
|
|
{ ANIM_0072, 0 },
|
|
{ ANIM_0073, 0 },
|
|
{ ANIM_005A, 0 },
|
|
{ ANIM_006C, 0 },
|
|
{ ANIM_0030, 0 },
|
|
{ ANIM_0031, 0 },
|
|
{ ANIM_0052, 0 },
|
|
{ ANIM_0055, 0 },
|
|
{ ANIM_006E, 0 },
|
|
{ ANIM_006F, 0 },
|
|
{ ANIM_0057, 0 },
|
|
{ ANIM_0056, 0 },
|
|
{ ANIM_006D, 0 },
|
|
{ ANIM_RUNNING_ONEHANDGUN, 0 },
|
|
{ ANIM_020A, 0 },
|
|
{ ANIM_020D, 0 },
|
|
{ ANIM_01F9, 0 },
|
|
{ ANIM_01F8, 0 },
|
|
{ ANIM_021D, 0 },
|
|
{ ANIM_0016, 0 },
|
|
{ ANIM_0018, 0 },
|
|
{ ANIM_001B, 0 },
|
|
{ ANIM_001D, 0 },
|
|
{ ANIM_001E, 0 },
|
|
{ ANIM_005C, 0 },
|
|
{ ANIM_005D, 0 },
|
|
{ ANIM_005E, 0 },
|
|
{ ANIM_005F, 0 },
|
|
{ -1 },
|
|
};
|
|
|
|
struct var80067e6c var80067f84[] = {
|
|
{ ANIM_0392, 0 },
|
|
{ ANIM_0393, 0 },
|
|
{ ANIM_SKEDAR_RUNNING, 0 },
|
|
{ -1 },
|
|
};
|
|
|
|
struct var80067e6c var80067fa4[] = {
|
|
{ ANIM_015F, 0 },
|
|
{ ANIM_0160, 0 },
|
|
{ -1 },
|
|
};
|
|
|
|
struct var80067e6c var80067fbc[] = {
|
|
{ ANIM_015F, 0 },
|
|
{ -1 },
|
|
};
|
|
|
|
struct var80067e6c var80067fcc[] = {
|
|
{ ANIM_0238, 0 },
|
|
{ -1 },
|
|
};
|
|
|
|
struct var80067e6c *var80067fdc[] = {
|
|
var80067e6c,
|
|
var80067f84,
|
|
var80067fa4,
|
|
var80067fbc,
|
|
var80067fcc,
|
|
};
|
|
|
|
f32 func0f02dff0(s16 animnum)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAYCOUNT(var80067fdc); i++) {
|
|
s32 j = 0;
|
|
s16 thisanimnum = var80067fdc[i][j].animnum;
|
|
|
|
while (thisanimnum >= 0) {
|
|
if (thisanimnum == animnum) {
|
|
return var80067fdc[i][j].value;
|
|
}
|
|
|
|
j++;
|
|
thisanimnum = var80067fdc[i][j].animnum;
|
|
}
|
|
}
|
|
|
|
return 1.0f;
|
|
}
|
|
|
|
bool chrGoPosIsWaiting(struct chrdata *chr)
|
|
{
|
|
static s16 list1[] = { ANIM_TWO_GUN_HOLD, ANIM_006A, -1 };
|
|
static s16 list2[] = { ANIM_00C0, -1 };
|
|
static s16 list3[] = { ANIM_013E, -1 };
|
|
static s16 list4[] = { ANIM_013E, -1 };
|
|
static s16 list5[] = { ANIM_0237, -1 };
|
|
static s16 *waitableanims[] = { list1, list2, list3, list4, list5 };
|
|
|
|
if (chr->aibot) {
|
|
if (chr->actiontype == ACT_STAND
|
|
|| (chr->actiontype == ACT_GOPOS && (chr->act_gopos.flags & GOPOSFLAG_WAITING))) {
|
|
return true;
|
|
}
|
|
} else {
|
|
s16 animnum = modelGetAnimNum(chr->model);
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAYCOUNT(waitableanims); i++) {
|
|
s16 thisanimnum;
|
|
s32 j;
|
|
|
|
for (j = 0; (thisanimnum = waitableanims[i][j]) >= 0; j++) {
|
|
if (thisanimnum == animnum) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool weaponIsOneHanded(struct prop *prop)
|
|
{
|
|
if (prop) {
|
|
struct weaponobj *weapon = prop->weapon;
|
|
return weaponHasFlag(weapon->weaponnum, WEAPONFLAG_ONEHANDED);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Returns a value between min and max based on the chr's speedrating property.
|
|
*
|
|
* chr->speedrating is between 0 and 100. The result is scaled between min and
|
|
* max accordingly.
|
|
*
|
|
* This function also applies the PD mode reaction speed, but the PD mode
|
|
* reaction speed is always zero because PD doesn't have it in the settings.
|
|
* It was used in GE but disabled in PD.
|
|
*/
|
|
f32 chrGetRangedSpeed(struct chrdata *chr, f32 min, f32 max)
|
|
{
|
|
f32 speedrating = chr->speedrating;
|
|
|
|
speedrating = pdmodeGetEnemyReactionSpeed() * (100.0f - speedrating) + speedrating;
|
|
|
|
return (max - min) * speedrating * 0.01f + min;
|
|
}
|
|
|
|
/**
|
|
* Calculates a percentage of how slow the chr is.
|
|
*
|
|
* percentage is expected to be between 0 and 100.
|
|
* chr->speedrating is between 0 and 100.
|
|
*
|
|
* This function takes the difference between the speedrating and the max (100),
|
|
* then multiplies that amount by the given percentage and returns it.
|
|
*
|
|
* For example, if the chr's speedrating is 10 (out of 100) and the given
|
|
* percentage is 50, the result will be 45.
|
|
*/
|
|
s32 chrGetPercentageOfSlowness(struct chrdata *chr, s32 percentage)
|
|
{
|
|
s32 speedrating = chr->speedrating;
|
|
s32 extra = pdmodeGetEnemyReactionSpeed() * (100 - speedrating);
|
|
|
|
speedrating = extra + speedrating;
|
|
|
|
return (100 - speedrating) * percentage / 100;
|
|
}
|
|
|
|
f32 chrGetRangedArghSpeed(struct chrdata *chr, f32 min, f32 max)
|
|
{
|
|
f32 arghrating = chr->arghrating;
|
|
|
|
arghrating = pdmodeGetEnemyReactionSpeed() * (100.0f - arghrating) + arghrating;
|
|
|
|
return (max - min) * arghrating * 0.01f + min;
|
|
}
|
|
|
|
f32 chrGetAttackEntityRelativeAngle(struct chrdata *chr, s32 attackflags, s32 entityid)
|
|
{
|
|
f32 angle;
|
|
struct coord pos;
|
|
s16 rooms[8];
|
|
|
|
if (attackflags & ATTACKFLAG_AIMFORWARD) {
|
|
return 0;
|
|
}
|
|
|
|
if (attackflags & ATTACKFLAG_AIMATDIRECTION) {
|
|
angle = entityid * (M_BADTAU / 65536);
|
|
angle -= chrGetInverseTheta(chr);
|
|
|
|
if (angle < 0) {
|
|
angle += M_BADTAU;
|
|
}
|
|
|
|
return angle;
|
|
}
|
|
|
|
chrGetAttackEntityPos(chr, attackflags, entityid, &pos, rooms);
|
|
|
|
return chrGetAngleToPos(chr, &pos);
|
|
}
|
|
|
|
f32 chrGetAttackEntityDistance(struct chrdata *chr, u32 attackflags, s32 entityid)
|
|
{
|
|
if (attackflags & ATTACKFLAG_AIMATTARGET) {
|
|
return chrGetDistanceToTarget(chr);
|
|
}
|
|
|
|
if (attackflags & ATTACKFLAG_AIMATCHR) {
|
|
return chrGetDistanceToChr(chr, entityid);
|
|
}
|
|
|
|
if (attackflags & ATTACKFLAG_AIMATPAD) {
|
|
return chrGetDistanceToPad(chr, entityid);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void func0f02e3dc(struct coord *a, struct coord *b,struct coord *c, struct coord *d, struct coord *dst)
|
|
{
|
|
f32 value = d->z * (b->x - a->x) - (b->z - a->z) * d->x;
|
|
|
|
if (value != 0) {
|
|
f32 tmp = ((b->z - a->z) * (c->x - a->x) + (a->z - c->z) * (b->x - a->x)) / value;
|
|
dst->x = d->x * tmp + c->x;
|
|
dst->y = d->y * tmp + c->y;
|
|
dst->z = d->z * tmp + c->z;
|
|
} else if (d->x == 0 && d->z == 0) {
|
|
dst->x = c->x;
|
|
dst->y = c->y;
|
|
dst->z = c->z;
|
|
} else {
|
|
dst->x = a->x;
|
|
dst->y = a->y;
|
|
dst->z = a->z;
|
|
}
|
|
}
|
|
|
|
void func0f02e4f8(struct coord *arg0, struct coord *arg1, struct coord *dst)
|
|
{
|
|
struct coord sp2c;
|
|
struct coord sp20;
|
|
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
cd00024e4c(&sp2c, &sp20, 2298, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(&sp2c, &sp20, 2298, "chraction.c");
|
|
#else
|
|
cd00024e4c(&sp2c, &sp20, 2338, "chraction.c");
|
|
#endif
|
|
|
|
func0f02e3dc(&sp2c, &sp20, arg0, arg1, dst);
|
|
}
|
|
|
|
f32 func0f02e550(struct prop *prop, f32 arg1, f32 arg2, u32 arg3, f32 ymax, f32 ymin)
|
|
{
|
|
struct coord sp5c;
|
|
struct coord sp50;
|
|
struct chrdata *chr = prop->chr;
|
|
f32 result;
|
|
struct coord sp3c;
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
|
|
sp5c.x = sinf(arg1);
|
|
sp5c.y = 0;
|
|
sp5c.z = cosf(arg1);
|
|
|
|
sp50.x = prop->pos.x + sp5c.f[0] * arg2;
|
|
sp50.y = prop->pos.y;
|
|
sp50.z = prop->pos.z + sp5c.f[2] * arg2;
|
|
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
if (cd0002d7c0(&prop->pos, prop->rooms, &sp50, arg3, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) {
|
|
result = arg2;
|
|
} else {
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
cdGetPos(&sp3c, 2377, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cdGetPos(&sp3c, 2377, "chraction.c");
|
|
#else
|
|
cdGetPos(&sp3c, 2417, "chraction.c");
|
|
#endif
|
|
|
|
xdiff = sp3c.x - prop->pos.x;
|
|
zdiff = sp3c.z - prop->pos.z;
|
|
|
|
result = sqrtf(xdiff * xdiff + zdiff * zdiff);
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
|
|
return result;
|
|
}
|
|
|
|
f32 func0f02e684(struct prop *prop, f32 arg1, f32 arg2)
|
|
{
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
|
|
chrGetBbox(prop, &radius, &ymax, &ymin);
|
|
|
|
return func0f02e550(prop, arg1, arg2, CDTYPE_ALL, ymax, ymin);
|
|
}
|
|
|
|
void chrChooseStandAnimation(struct chrdata *chr, f32 mergetime)
|
|
{
|
|
struct prop *gun1 = chrGetHeldProp(chr, HAND_LEFT);
|
|
struct prop *gun2 = chrGetHeldProp(chr, HAND_RIGHT);
|
|
s32 race = CHRRACE(chr);
|
|
s32 prevanimnum = modelGetAnimNum(chr->model);
|
|
|
|
if (chr->actiontype == ACT_GOPOS) {
|
|
chr->act_gopos.flags |= GOPOSFLAG_WAITING;
|
|
}
|
|
|
|
if (chr->aibot) {
|
|
return;
|
|
}
|
|
|
|
if (race == RACE_EYESPY) {
|
|
modelSetAnimation(chr->model, ANIM_013E, 0, 0, 0, mergetime);
|
|
} else if (race == RACE_HUMAN) {
|
|
if (prevanimnum == ANIM_SNIPING_GETDOWN
|
|
|| prevanimnum == ANIM_SNIPING_GETUP
|
|
|| prevanimnum == ANIM_SNIPING_ONGROUND) {
|
|
modelSetAnimation(chr->model, ANIM_SNIPING_GETUP, chr->model->anim->flip, -1, chrGetRangedSpeed(chr, 0.5, 0.8), 16);
|
|
} else if ((gun1 && gun2) || (!gun1 && !gun2)
|
|
|| weaponIsOneHanded(gun1)
|
|
|| weaponIsOneHanded(gun2)) {
|
|
modelSetAnimation(chr->model, ANIM_006A, random() % 2, 0, 0.25, mergetime);
|
|
modelSetAnimLooping(chr->model, 0, 16);
|
|
} else if (gun2 || gun1) {
|
|
modelSetAnimation(chr->model, ANIM_TWO_GUN_HOLD, gun1 != NULL, 0, 0.25, mergetime);
|
|
modelSetAnimLooping(chr->model, 0, 16);
|
|
modelSetAnimEndFrame(chr->model, 120);
|
|
}
|
|
} else if (race == RACE_SKEDAR) {
|
|
modelSetAnimation(chr->model, ANIM_00C0, random() % 2, 0, 0.5, mergetime);
|
|
} else if (race == RACE_DRCAROLL) {
|
|
modelSetAnimation(chr->model, ANIM_013E, 0, 0, 0.5, mergetime);
|
|
} else if (race == RACE_ROBOT) {
|
|
modelSetAnimation(chr->model, ANIM_0237, 0, 0, 0.5, mergetime);
|
|
}
|
|
}
|
|
|
|
void func0f02e9a0(struct chrdata *chr, f32 mergetime)
|
|
{
|
|
f32 limit = 127;
|
|
f32 fsleep;
|
|
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_STAND;
|
|
chr->act_stand.prestand = false;
|
|
chr->act_stand.flags = 0;
|
|
chr->act_stand.entityid = 0;
|
|
chr->act_stand.reaim = 0;
|
|
chr->act_stand.turning = TURNSTATE_OFF;
|
|
chr->act_stand.checkfacingwall = false;
|
|
chr->act_stand.wallcount = random() % 120 + 180; // 180 to 299
|
|
chr->act_stand.mergetime = mergetime;
|
|
chr->act_stand.playwalkanim = false;
|
|
|
|
fsleep = mergetime;
|
|
|
|
if (chr->model->anim->playspeed != PALUPF(1.0f)) {
|
|
fsleep *= PALUPF(1.0f) / chr->model->anim->playspeed;
|
|
}
|
|
|
|
if (fsleep > limit) {
|
|
fsleep = limit;
|
|
}
|
|
|
|
chr->sleep = fsleep;
|
|
|
|
if (modelIsAnimMerging(chr->model) && !chr->aibot) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrChooseStandAnimation(chr, mergetime);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrStand(struct chrdata *chr)
|
|
{
|
|
s32 race = CHRRACE(chr);
|
|
f32 result;
|
|
|
|
if (race != RACE_EYESPY) {
|
|
chrStopFiring(chr);
|
|
|
|
if (race == RACE_HUMAN && chr->actiontype == ACT_KNEEL) {
|
|
chrStopFiring(chr);
|
|
|
|
chr->actiontype = ACT_STAND;
|
|
chr->act_stand.prestand = true;
|
|
chr->act_stand.flags = 0;
|
|
chr->act_stand.entityid = 0;
|
|
chr->act_stand.reaim = 0;
|
|
chr->act_stand.turning = TURNSTATE_OFF;
|
|
chr->act_stand.checkfacingwall = false;
|
|
chr->act_stand.wallcount = random() % 120 + 180;
|
|
chr->sleep = 0;
|
|
chr->act_stand.playwalkanim = false;
|
|
|
|
if (chr->aibot == NULL) {
|
|
if (modelGetAnimNum(chr->model) == ANIM_KNEEL_SHOOT_RIGHT_HAND) {
|
|
result = chrGetRangedSpeed(chr, 0.5, 0.8);
|
|
modelSetAnimation(chr->model, ANIM_KNEEL_SHOOT_RIGHT_HAND,
|
|
chr->model->anim->flip, 109, result, 16);
|
|
modelSetAnimEndFrame(chr->model, 140);
|
|
} else {
|
|
result = chrGetRangedSpeed(chr, 0.5, 0.8);
|
|
modelSetAnimation(chr->model, ANIM_KNEEL_TWO_HANDED_GUN,
|
|
chr->model->anim->flip, 120, result, 16);
|
|
modelSetAnimEndFrame(chr->model, 151);
|
|
}
|
|
}
|
|
} else if (race == RACE_DRCAROLL || race == RACE_ROBOT) {
|
|
chr->actiontype = ACT_STAND;
|
|
chr->act_stand.prestand = true;
|
|
chr->act_stand.flags = 0;
|
|
chr->act_stand.entityid = 0;
|
|
chr->act_stand.reaim = 0;
|
|
chr->act_stand.turning = TURNSTATE_OFF;
|
|
chr->act_stand.checkfacingwall = false;
|
|
chr->act_stand.wallcount = random() % 120 + 180;
|
|
chr->sleep = 0;
|
|
chr->act_stand.playwalkanim = false;
|
|
|
|
func0f02e9a0(chr, 16);
|
|
} else {
|
|
func0f02e9a0(chr, 16);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool chrFaceCover(struct chrdata *chr)
|
|
{
|
|
struct cover cover;
|
|
|
|
if (!coverUnpack(chr->cover, &cover)) {
|
|
return false;
|
|
}
|
|
|
|
chrStand(chr);
|
|
chr->act_stand.reaim = 0;
|
|
chr->act_stand.flags = ATTACKFLAG_AIMATDIRECTION;
|
|
chr->act_stand.turning = TURNSTATE_TURNING;
|
|
//chr->act_stand.entityid = atan2f(-cover.look->x, -cover.look->z) * (0x4000 / BADDEG2RAD(90));
|
|
chr->act_stand.entityid = atan2f(-cover.look->x, -cover.look->z) * 10432.039f;
|
|
|
|
return true;
|
|
}
|
|
|
|
void func0f02ed28(struct chrdata *chr, f32 mergetime)
|
|
{
|
|
func0f02e9a0(chr, mergetime);
|
|
|
|
chr->act_stand.checkfacingwall = true;
|
|
}
|
|
|
|
void chrStop(struct chrdata *chr)
|
|
{
|
|
chrStand(chr);
|
|
|
|
chr->act_stand.checkfacingwall = true;
|
|
}
|
|
|
|
void chrKneelChooseAnimation(struct chrdata *chr)
|
|
{
|
|
struct prop *gun1 = chrGetHeldProp(chr, 1);
|
|
struct prop *gun2 = chrGetHeldProp(chr, 0);
|
|
|
|
if (chr->aibot == NULL) {
|
|
if ((gun1 && gun2)
|
|
|| (!gun1 && !gun2)
|
|
|| weaponIsOneHanded(gun1)
|
|
|| weaponIsOneHanded(gun2)) {
|
|
bool flip = random() % 2;
|
|
modelSetAnimation(chr->model, ANIM_KNEEL_SHOOT_RIGHT_HAND, flip, 0, chrGetRangedSpeed(chr, 0.5, 0.8), 16);
|
|
modelSetAnimEndFrame(chr->model, 28);
|
|
} else if (gun2 || gun1) {
|
|
modelSetAnimation(chr->model, ANIM_KNEEL_TWO_HANDED_GUN, gun1 != NULL, 0, chrGetRangedSpeed(chr, 0.5, 0.8), 16);
|
|
modelSetAnimEndFrame(chr->model, 27);
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrKneel(struct chrdata *chr)
|
|
{
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_KNEEL;
|
|
chr->sleep = 0;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrKneelChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrStartAlarmChooseAnimation(struct chrdata *chr)
|
|
{
|
|
struct prop *gun1 = chrGetHeldProp(chr, 1);
|
|
struct prop *gun2 = chrGetHeldProp(chr, 0);
|
|
bool flip = false;
|
|
|
|
if (gun1 && !gun2) {
|
|
flip = true;
|
|
} else if ((gun1 && gun2) || (!gun1 && !gun2)) {
|
|
flip = random() % 2;
|
|
}
|
|
|
|
modelSetAnimation(chr->model, ANIM_TALKING_003D, flip, 40, 1, 16);
|
|
modelSetAnimEndFrame(chr->model, 82);
|
|
}
|
|
|
|
void chrStartAlarm(struct chrdata *chr)
|
|
{
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_STARTALARM;
|
|
chr->sleep = 0;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrStartAlarmChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrThrowGrenadeChooseAnimation(struct chrdata *chr)
|
|
{
|
|
u32 rand = random();
|
|
|
|
if (chr->act_throwgrenade.needsequip) {
|
|
if (rand % 3 == 0) {
|
|
modelSetAnimation(chr->model, ANIM_THROWGRENADE_CROUCHING, chr->act_throwgrenade.hand != 0, 0, chrGetRangedSpeed(chr, 0.5, 1.2), 16);
|
|
} else if (rand % 3 == 1) {
|
|
modelSetAnimation(chr->model, ANIM_THROWGRENADE_NOPIN, chr->act_throwgrenade.hand != 0, 0, chrGetRangedSpeed(chr, 0.5, 1.2), 16);
|
|
} else {
|
|
modelSetAnimation(chr->model, ANIM_THROWGRENADE_STANDING, chr->act_throwgrenade.hand != 0, 0, chrGetRangedSpeed(chr, 0.5, 1.2), 16);
|
|
}
|
|
} else {
|
|
if (rand % 3 == 0) {
|
|
modelSetAnimation(chr->model, ANIM_THROWGRENADE_CROUCHING, chr->act_throwgrenade.hand != 0, 5, chrGetRangedSpeed(chr, 0.5, 1.2), 16);
|
|
} else if (rand % 3 == 1) {
|
|
modelSetAnimation(chr->model, ANIM_THROWGRENADE_NOPIN, chr->act_throwgrenade.hand != 0, 6, chrGetRangedSpeed(chr, 0.5, 1.2), 16);
|
|
} else {
|
|
modelSetAnimation(chr->model, ANIM_THROWGRENADE_STANDING, chr->act_throwgrenade.hand != 0, 84, chrGetRangedSpeed(chr, 0.5, 1.2), 16);
|
|
}
|
|
}
|
|
|
|
modelSetAnimEndFrame(chr->model, -1);
|
|
}
|
|
|
|
void chrThrowGrenade(struct chrdata *chr, s32 hand, s32 needsequip)
|
|
{
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_THROWGRENADE;
|
|
chr->act_throwgrenade.hand = hand;
|
|
chr->act_throwgrenade.needsequip = needsequip;
|
|
chr->sleep = 0;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrThrowGrenadeChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrSurprisedChooseAnimation(struct chrdata *chr)
|
|
{
|
|
if (chr->act_surprised.type == 1) {
|
|
struct prop *gun1 = chrGetHeldProp(chr, 1);
|
|
struct prop *gun0 = chrGetHeldProp(chr, 0);
|
|
s32 flip = 0;
|
|
|
|
if (gun1 != NULL && gun0 == NULL) {
|
|
flip = 1;
|
|
} else if ((gun1 != NULL && gun0 != NULL) || (gun1 == NULL && gun0 == NULL)) {
|
|
flip = random() & 1;
|
|
}
|
|
|
|
modelSetAnimation(chr->model, ANIM_003F, flip, 10, chrGetRangedSpeed(chr, 0.6f, 0.96000003f), 16);
|
|
modelSetAnimEndFrame(chr->model, 52);
|
|
} else if (chr->act_surprised.type == 2) {
|
|
modelSetAnimation(chr->model, ANIM_SURRENDER_002E, random() & 1, 0, chrGetRangedSpeed(chr, 0.35f, 0.56f), 16);
|
|
modelSetAnimEndFrame(chr->model, 7);
|
|
} else {
|
|
u32 part = random() % 3;
|
|
modelSetAnimation(chr->model, ANIM_0040, random() & 1, 17, 0.6f, 16);
|
|
|
|
if (part == 0) {
|
|
modelSetAnimEndFrame(chr->model, chrGetRangedSpeed(chr, 38, 8));
|
|
} else if (part == 1) {
|
|
modelSetAnimEndFrame(chr->model, chrGetRangedSpeed(chr, 66, 8));
|
|
} else {
|
|
modelSetAnimEndFrame(chr->model, chrGetRangedSpeed(chr, 96, 8));
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrDoSurprisedOneHand(struct chrdata *chr)
|
|
{
|
|
struct prop *prop = chrGetTargetProp(chr);
|
|
f32 angle = chrGetAngleToPos(chr, &prop->pos);
|
|
|
|
// BADDEG2RAD(10) doesn't match due to float precision :(
|
|
if (angle < 0.17450514435768f || angle > BADDEG2RAD(350)) {
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_SURPRISED;
|
|
chr->act_surprised.type = 1;
|
|
chr->sleep = 0;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrSurprisedChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
} else if (!chrIsStopped(chr)) {
|
|
chrStand(chr);
|
|
}
|
|
}
|
|
|
|
void chrDoSurprisedSurrender(struct chrdata *chr)
|
|
{
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_SURPRISED;
|
|
chr->act_surprised.type = 2;
|
|
chr->sleep = 0;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrSurprisedChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrDoSurprisedLookAround(struct chrdata *chr)
|
|
{
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_SURPRISED;
|
|
chr->act_surprised.type = 3;
|
|
chr->sleep = 0;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrSurprisedChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrSurrenderChooseAnimation(struct chrdata *chr)
|
|
{
|
|
struct prop *gun1 = chrGetHeldProp(chr, 1);
|
|
struct prop *gun0 = chrGetHeldProp(chr, 0);
|
|
|
|
if (gun0 || gun1) {
|
|
modelSetAnimation(chr->model, ANIM_SURRENDER_002F, random() & 1, 0, 0.5, 16);
|
|
modelSetAnimLooping(chr->model, 40, 16);
|
|
|
|
if (gun1) {
|
|
objSetDropped(gun1, DROPTYPE_SURRENDER);
|
|
}
|
|
|
|
if (gun0) {
|
|
objSetDropped(gun0, DROPTYPE_SURRENDER);
|
|
}
|
|
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
} else {
|
|
modelSetAnimation(chr->model, ANIM_SURRENDER_002E, random() & 1, 0, 0.5, 16);
|
|
modelSetAnimLooping(chr->model, 30, 16);
|
|
}
|
|
|
|
chrDropConcealedItems(chr);
|
|
}
|
|
|
|
void chrSurrender(struct chrdata *chr)
|
|
{
|
|
u32 action = ACT_SURRENDER;
|
|
|
|
if (chr->actiontype != action) {
|
|
chrStopFiring(chr);
|
|
chr->actiontype = action;
|
|
chr->sleep = action;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrSurrenderChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrSidestepChooseAnimation(struct chrdata *chr)
|
|
{
|
|
struct prop *gun1 = chrGetHeldProp(chr, 1);
|
|
struct prop *gun2 = chrGetHeldProp(chr, 0);
|
|
bool flip = false;
|
|
bool allowflip = false;
|
|
u32 race = CHRRACE(chr);
|
|
|
|
if (gun1 && gun2) {
|
|
flip = random() % 2;
|
|
allowflip = random() % 2;
|
|
} else {
|
|
if (weaponIsOneHanded(gun1) == false
|
|
&& weaponIsOneHanded(gun2) == false
|
|
&& (gun1 || gun2)) {
|
|
flip = (gun1 != 0);
|
|
allowflip = random() % 2;
|
|
}
|
|
}
|
|
|
|
if (race == RACE_HUMAN) {
|
|
if (allowflip == false) {
|
|
if (chr->act_sidestep.side) {
|
|
modelSetAnimation(chr->model, ANIM_0068, true, 5, chrGetRangedSpeed(chr, 0.55, 0.88000005), 16);
|
|
modelSetAnimEndFrame(chr->model, 36);
|
|
} else {
|
|
modelSetAnimation(chr->model, ANIM_0068, false, 5, chrGetRangedSpeed(chr, 0.55, 0.88000005), 16);
|
|
modelSetAnimEndFrame(chr->model, 36);
|
|
}
|
|
} else {
|
|
if ((chr->act_sidestep.side && !flip) || (chr->act_sidestep.side == 0 && flip)) {
|
|
modelSetAnimation(chr->model, ANIM_003B, flip, 5, chrGetRangedSpeed(chr, 0.7, 1.12), 16);
|
|
modelSetAnimEndFrame(chr->model, 34);
|
|
} else {
|
|
modelSetAnimation(chr->model, ANIM_003A, flip, 5, chrGetRangedSpeed(chr, 0.7, 1.12), 16);
|
|
modelSetAnimEndFrame(chr->model, 32);
|
|
}
|
|
}
|
|
} else if (race == RACE_SKEDAR) {
|
|
if (chr->act_sidestep.side) {
|
|
modelSetAnimation(chr->model, ANIM_0328, false, 5, chrGetRangedSpeed(chr, 0.55, 0.88000005), 16);
|
|
modelSetAnimEndFrame(chr->model, 27);
|
|
} else {
|
|
modelSetAnimation(chr->model, ANIM_0328, true, 5, chrGetRangedSpeed(chr, 0.55, 0.88000005), 16);
|
|
modelSetAnimEndFrame(chr->model, 27);
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrSidestep(struct chrdata *chr, bool side)
|
|
{
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_SIDESTEP;
|
|
chr->act_sidestep.side = side;
|
|
chr->sleep = 0;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrSidestepChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrJumpOutChooseAnimation(struct chrdata *chr)
|
|
{
|
|
struct prop *gun1 = chrGetHeldProp(chr, 1);
|
|
struct prop *gun2 = chrGetHeldProp(chr, 0);
|
|
bool flip = false;
|
|
|
|
if (gun1 && !gun2) {
|
|
flip = true;
|
|
} else if ((gun1 && gun2) || (!gun1 && !gun2)
|
|
|| weaponIsOneHanded(gun1) || weaponIsOneHanded(gun2)) {
|
|
flip = random() % 2;
|
|
}
|
|
|
|
if ((chr->act_jumpout.side && !flip) || (chr->act_jumpout.side == 0 && flip)) {
|
|
modelSetAnimation(chr->model, ANIM_0068, true, 5, chrGetRangedSpeed(chr, 0.55, 0.88000005), 16);
|
|
modelSetAnimEndFrame(chr->model, 36);
|
|
} else {
|
|
modelSetAnimation(chr->model, ANIM_0068, false, 5, chrGetRangedSpeed(chr, 0.55, 0.88000005), 16);
|
|
modelSetAnimEndFrame(chr->model, 36);
|
|
}
|
|
}
|
|
|
|
void chrJumpOut(struct chrdata *chr, bool side)
|
|
{
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_JUMPOUT;
|
|
chr->act_jumpout.side = side;
|
|
chr->sleep = 0;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrJumpOutChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrRunPosChooseAnimation(struct chrdata *chr)
|
|
{
|
|
f32 xdiff = chr->prop->pos.x - chr->act_runpos.pos.x;
|
|
f32 ydiff = chr->prop->pos.y - chr->act_runpos.pos.y;
|
|
f32 zdiff = chr->prop->pos.z - chr->act_runpos.pos.z;
|
|
f32 distance = sqrtf(xdiff * xdiff + zdiff * zdiff);
|
|
struct prop *gun1 = chrGetHeldProp(chr, 1);
|
|
struct prop *gun2 = chrGetHeldProp(chr, 0);
|
|
bool heavy = true;
|
|
bool flip;
|
|
s32 race = CHRRACE(chr);
|
|
|
|
if ((gun1 && gun2) || (!gun1 && !gun2)) {
|
|
heavy = false;
|
|
flip = random() % 2;
|
|
} else if (weaponIsOneHanded(gun1) || weaponIsOneHanded(gun2)) {
|
|
heavy = false;
|
|
flip = (bool)gun1 != false;
|
|
} else {
|
|
flip = (bool)gun1 != false;
|
|
}
|
|
|
|
if (race == RACE_HUMAN) {
|
|
if (heavy) {
|
|
f32 mult = 0.5;
|
|
#if PAL
|
|
chr->act_runpos.eta60 = 1.0f / (func0f02dff0(ANIM_RUNNING_TWOHANDGUN) * mult) * distance * 0.83333331346512f;
|
|
#else
|
|
chr->act_runpos.eta60 = 1.0f / (func0f02dff0(ANIM_RUNNING_TWOHANDGUN) * mult) * distance;
|
|
#endif
|
|
modelSetAnimation(chr->model, ANIM_RUNNING_TWOHANDGUN, flip, 0, mult, 16);
|
|
} else {
|
|
f32 mult = 0.5;
|
|
#if PAL
|
|
chr->act_runpos.eta60 = 1.0f / (func0f02dff0(ANIM_RUNNING_ONEHANDGUN) * mult) * distance * 0.83333331346512f;
|
|
#else
|
|
chr->act_runpos.eta60 = 1.0f / (func0f02dff0(ANIM_RUNNING_ONEHANDGUN) * mult) * distance;
|
|
#endif
|
|
modelSetAnimation(chr->model, ANIM_RUNNING_ONEHANDGUN, flip, 0, mult, 16);
|
|
}
|
|
} else if (race == RACE_SKEDAR) {
|
|
f32 mult = 0.5;
|
|
#if PAL
|
|
chr->act_runpos.eta60 = 1.0f / (func0f02dff0(ANIM_SKEDAR_RUNNING) * mult) * distance * 0.83333331346512f;
|
|
#else
|
|
chr->act_runpos.eta60 = 1.0f / (func0f02dff0(ANIM_SKEDAR_RUNNING) * mult) * distance;
|
|
#endif
|
|
modelSetAnimation(chr->model, ANIM_SKEDAR_RUNNING, flip, 0, mult, 16);
|
|
}
|
|
}
|
|
|
|
void chrRunToPos(struct chrdata *chr, struct coord *pos)
|
|
{
|
|
chrStopFiring(chr);
|
|
chr->actiontype = ACT_RUNPOS;
|
|
chr->act_runpos.pos.x = pos->x;
|
|
chr->act_runpos.pos.y = pos->y;
|
|
chr->act_runpos.pos.z = pos->z;
|
|
chr->sleep = 0;
|
|
chr->act_runpos.neardist = 30;
|
|
chr->act_runpos.turnspeed = 0;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrRunPosChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrAttackStand(struct chrdata *chr, u32 attackflags, s32 entityid)
|
|
{
|
|
struct prop *leftgun = chrGetHeldProp(chr, HAND_LEFT);
|
|
struct prop *rightgun = chrGetHeldProp(chr, HAND_RIGHT);
|
|
bool flip;
|
|
struct attackanimgroup **animgroup;
|
|
bool firing[] = {false, false};
|
|
s32 race = CHRRACE(chr);
|
|
|
|
if (leftgun && rightgun) {
|
|
struct prop *leftgun2 = chrGetHeldUsableProp(chr, HAND_LEFT);
|
|
struct prop *rightgun2 = chrGetHeldUsableProp(chr, HAND_RIGHT);
|
|
|
|
if (leftgun2 && rightgun2) {
|
|
flip = random() % 2;
|
|
|
|
if (random() % 3 == 0) {
|
|
animgroup = g_StandLightAttackAnims[race];
|
|
firing[HAND_LEFT] = flip;
|
|
firing[HAND_RIGHT] = !flip;
|
|
} else {
|
|
animgroup = g_StandDualAttackAnims[race];
|
|
firing[HAND_LEFT] = true;
|
|
firing[HAND_RIGHT] = true;
|
|
}
|
|
} else {
|
|
flip = (bool)rightgun2 == false;
|
|
animgroup = g_StandLightAttackAnims[race];
|
|
firing[HAND_LEFT] = (bool)rightgun2 == false;
|
|
firing[HAND_RIGHT] = !flip;
|
|
}
|
|
} else {
|
|
if (weaponIsOneHanded(leftgun) || weaponIsOneHanded(rightgun)) {
|
|
flip = (bool)leftgun != false;
|
|
animgroup = g_StandLightAttackAnims[race];
|
|
firing[HAND_LEFT] = (bool)leftgun != false;
|
|
firing[HAND_RIGHT] = !flip;
|
|
} else {
|
|
flip = (bool)leftgun != false;
|
|
animgroup = g_StandHeavyAttackAnims[race];
|
|
firing[HAND_LEFT] = (bool)leftgun != false;
|
|
firing[HAND_RIGHT] = !flip;
|
|
}
|
|
}
|
|
|
|
chrAttack(chr, animgroup, flip, firing, attackflags, entityid, true);
|
|
}
|
|
|
|
void chrAttackLie(struct chrdata *chr, u32 attackflags, s32 entityid)
|
|
{
|
|
u32 stack[2];
|
|
struct prop *gun = chrGetHeldProp(chr, HAND_RIGHT);
|
|
s32 firing[2] = {false, false};
|
|
|
|
if (chr);
|
|
|
|
if (attackflags & ATTACKFLAG_AIMONLY) {
|
|
firing[1] = false;
|
|
firing[0] = false;
|
|
} else {
|
|
bool tmp = gun == NULL;
|
|
firing[1] = tmp;
|
|
firing[0] = (bool)!tmp;
|
|
}
|
|
|
|
chrAttack(chr, &g_LieAttackAnims, gun == NULL, firing, attackflags, entityid, false);
|
|
}
|
|
|
|
void chrAttackKneel(struct chrdata *chr, u32 attackflags, s32 entityid)
|
|
{
|
|
struct prop *leftgun = chrGetHeldProp(chr, HAND_LEFT);
|
|
struct prop *rightgun = chrGetHeldProp(chr, HAND_RIGHT);
|
|
s32 flip;
|
|
struct attackanimgroup **animgroup;
|
|
bool firing[2] = {false, false};
|
|
s32 race = CHRRACE(chr);
|
|
struct prop *leftgun2;
|
|
struct prop *rightgun2;
|
|
|
|
if (leftgun && rightgun) {
|
|
leftgun2 = chrGetHeldUsableProp(chr, HAND_LEFT);
|
|
rightgun2 = chrGetHeldUsableProp(chr, HAND_RIGHT);
|
|
|
|
if (leftgun2 && rightgun2) {
|
|
flip = random() % 2;
|
|
|
|
if (random() % 3 == 0) {
|
|
animgroup = g_KneelLightAttackAnims[race];
|
|
firing[HAND_LEFT] = flip;
|
|
firing[HAND_RIGHT] = !flip;
|
|
} else {
|
|
animgroup = g_KneelDualAttackAnims[race];
|
|
firing[HAND_LEFT] = true;
|
|
firing[HAND_RIGHT] = true;
|
|
}
|
|
} else {
|
|
flip = (bool)rightgun2 == false;
|
|
animgroup = g_KneelLightAttackAnims[race];
|
|
firing[HAND_LEFT] = (bool)rightgun2 == false;
|
|
firing[HAND_RIGHT] = !flip;
|
|
}
|
|
} else {
|
|
if (weaponIsOneHanded(leftgun) || weaponIsOneHanded(rightgun)) {
|
|
flip = (bool)leftgun != false;
|
|
animgroup = g_KneelLightAttackAnims[race];
|
|
firing[HAND_LEFT] = (bool)leftgun != false;
|
|
firing[HAND_RIGHT] = !flip;
|
|
} else {
|
|
flip = (bool)leftgun != false;
|
|
animgroup = g_KneelHeavyAttackAnims[race];
|
|
firing[HAND_LEFT] = (bool)leftgun != false;
|
|
firing[HAND_RIGHT] = !flip;
|
|
}
|
|
}
|
|
|
|
chrAttack(chr, animgroup, flip, firing, attackflags, entityid, false);
|
|
}
|
|
|
|
void chrAttackWalkChooseAnimation(struct chrdata *chr)
|
|
{
|
|
if (chr->aibot == NULL) {
|
|
modelSetAnimation(chr->model, chr->act_attackwalk.animcfg->animnum,
|
|
chr->act_attackwalk.flip, chr->act_attackwalk.animcfg->unk10, 0.5, 16);
|
|
}
|
|
}
|
|
|
|
void chrAttackWalk(struct chrdata *chr, bool run)
|
|
{
|
|
struct attackanimconfig *animcfg;
|
|
struct prop *leftgun = chrGetHeldProp(chr, HAND_LEFT);
|
|
struct prop *rightgun = chrGetHeldProp(chr, HAND_RIGHT);
|
|
bool flip;
|
|
bool firing[] = {false, false};
|
|
bool everytick[] = {false, false};
|
|
bool singleshot[] = {false, false};
|
|
s32 i;
|
|
struct prop *prop;
|
|
struct weaponobj *weapon;
|
|
|
|
if (leftgun && rightgun) {
|
|
struct prop *leftgun2 = chrGetHeldUsableProp(chr, HAND_LEFT);
|
|
struct prop *rightgun2 = chrGetHeldUsableProp(chr, HAND_RIGHT);
|
|
s32 style = 0;
|
|
|
|
if (leftgun2 && rightgun2) {
|
|
flip = random() % 2;
|
|
style = random() % 3;
|
|
} else {
|
|
flip = (bool)rightgun2 == false;
|
|
}
|
|
|
|
if (style == 0) {
|
|
if (run) {
|
|
animcfg = &g_AttackAnimLightRun;
|
|
} else {
|
|
animcfg = &g_AttackAnimLightWalk;
|
|
}
|
|
|
|
if (flip) {
|
|
firing[HAND_LEFT] = true;
|
|
} else {
|
|
firing[HAND_RIGHT] = true;
|
|
}
|
|
} else if (style == 1) {
|
|
if (run) {
|
|
animcfg = &g_AttackAnimDualRun;
|
|
} else {
|
|
animcfg = &g_AttackAnimDualWalk;
|
|
}
|
|
|
|
firing[HAND_LEFT] = firing[HAND_RIGHT] = true;
|
|
} else {
|
|
if (run) {
|
|
animcfg = &g_AttackAnimDualCrossedRun;
|
|
} else {
|
|
animcfg = &g_AttackAnimDualCrossedWalk;
|
|
}
|
|
|
|
firing[HAND_LEFT] = firing[HAND_RIGHT] = true;
|
|
}
|
|
} else {
|
|
if (weaponIsOneHanded(leftgun) || weaponIsOneHanded(rightgun)) {
|
|
flip = (bool)leftgun != false;
|
|
|
|
if (run) {
|
|
animcfg = &g_AttackAnimLightRun;
|
|
} else {
|
|
animcfg = &g_AttackAnimLightWalk;
|
|
}
|
|
|
|
if (flip) {
|
|
firing[HAND_LEFT] = true;
|
|
} else {
|
|
firing[HAND_RIGHT] = true;
|
|
}
|
|
} else {
|
|
flip = (bool)leftgun != false;
|
|
|
|
if (run) {
|
|
animcfg = &g_AttackAnimHeavyRun;
|
|
} else {
|
|
animcfg = &g_AttackAnimHeavyWalk;
|
|
}
|
|
|
|
if (flip) {
|
|
firing[HAND_LEFT] = true;
|
|
} else {
|
|
firing[HAND_RIGHT] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
if (firing[i]) {
|
|
prop = chrGetHeldProp(chr, i);
|
|
weapon = prop->weapon;
|
|
|
|
if (weaponGetNumTicksPerShot(weapon->weaponnum, weapon->gunfunc) < 1) {
|
|
everytick[i] = true;
|
|
}
|
|
|
|
if (weapon->weaponnum == WEAPON_ROCKETLAUNCHER
|
|
|| weapon->weaponnum == WEAPON_ROCKETLAUNCHER_34
|
|
|| weapon->weaponnum == WEAPON_SLAYER
|
|
|| weapon->weaponnum == WEAPON_DEVASTATOR
|
|
|| (
|
|
!g_Vars.normmplayerisrunning
|
|
&& weapon->weaponnum == WEAPON_DY357MAGNUM
|
|
&& chr->headnum != HEAD_JONATHAN
|
|
&& chr->headnum != HEAD_CHRIST)
|
|
|| (
|
|
!g_Vars.normmplayerisrunning
|
|
&& weapon->weaponnum == WEAPON_DY357LX)
|
|
|| (
|
|
!g_Vars.normmplayerisrunning
|
|
&& weapon->weaponnum == WEAPON_SHOTGUN)) {
|
|
singleshot[i] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
chr->actiontype = ACT_ATTACKWALK;
|
|
|
|
chr->act_attackwalk.frame60count = 0;
|
|
#if PAL
|
|
// This is really TICKS(400.0f), but off by one bit :(
|
|
chr->act_attackwalk.frame60max = random() % (s32)(333.33331298828f * g_AttackWalkDurationScale) + TICKS(120);
|
|
#else
|
|
chr->act_attackwalk.frame60max = random() % (s32)(400 * g_AttackWalkDurationScale) + TICKS(120);
|
|
#endif
|
|
chr->act_attackwalk.facedtarget = false;
|
|
chr->act_attackwalk.animcfg = animcfg;
|
|
chr->act_attackwalk.nextshot60 = 0;
|
|
chr->act_attackwalk.nextgun = random() % 2;
|
|
chr->act_attackwalk.firegun[HAND_LEFT] = firing[HAND_LEFT];
|
|
chr->act_attackwalk.firegun[HAND_RIGHT] = firing[HAND_RIGHT];
|
|
chr->act_attackwalk.everytick[HAND_LEFT] = everytick[HAND_LEFT];
|
|
chr->act_attackwalk.everytick[HAND_RIGHT] = everytick[HAND_RIGHT];
|
|
chr->act_attackwalk.singleshot[HAND_LEFT] = singleshot[HAND_LEFT];
|
|
chr->act_attackwalk.singleshot[HAND_RIGHT] = singleshot[HAND_RIGHT];
|
|
chr->act_attackwalk.turnspeed = 0;
|
|
chr->act_attackwalk.flip = flip;
|
|
|
|
chr->sleep = 0;
|
|
chr->chrflags &= ~CHRCFLAG_INJUREDTARGET;
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrAttackWalkChooseAnimation(chr);
|
|
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrAttackRollChooseAnimation(struct chrdata *chr)
|
|
{
|
|
modelSetAnimation(chr->model, chr->act_attack.animcfg->animnum, chr->act_attack.flip,
|
|
chr->act_attack.animcfg->unk10, chrGetRangedSpeed(chr, 0.5, 0.8), 16);
|
|
|
|
if (chr->act_attack.onehanded == false) {
|
|
if (chr->act_attack.dorecoil) {
|
|
if (chr->act_attack.animcfg->unk24 >= 0) {
|
|
modelSetAnimEndFrame(chr->model, chr->act_attack.animcfg->unk24);
|
|
} else {
|
|
modelSetAnimEndFrame(chr->model, chr->act_attack.animcfg->unk1c);
|
|
}
|
|
} else {
|
|
if (chr->act_attack.animcfg->unk20 >= 0) {
|
|
modelSetAnimEndFrame(chr->model, chr->act_attack.animcfg->unk20);
|
|
} else if (chr->act_attack.animcfg->unk14 >= 0) {
|
|
modelSetAnimEndFrame(chr->model, chr->act_attack.animcfg->unk14);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrAttackRoll(struct chrdata *chr, bool toleft)
|
|
{
|
|
struct attackanimconfig *animcfg;
|
|
struct prop *leftgun = chrGetHeldProp(chr, HAND_LEFT);
|
|
struct prop *rightgun = chrGetHeldProp(chr, HAND_RIGHT);
|
|
bool flip;
|
|
bool onehanded = false;
|
|
struct prop *prop;
|
|
struct weaponobj *weapon;
|
|
bool dorecoil = true;
|
|
bool firing[] = {false, false};
|
|
s32 i;
|
|
bool dooneburst = false;
|
|
bool everytick[] = {false, false};
|
|
bool singleshot[] = {false, false};
|
|
|
|
if (leftgun && rightgun) {
|
|
struct prop *leftgun2 = chrGetHeldUsableProp(chr, HAND_LEFT);
|
|
struct prop *rightgun2 = chrGetHeldUsableProp(chr, HAND_RIGHT);
|
|
|
|
if (leftgun2 && rightgun2) {
|
|
flip = random() % 2;
|
|
onehanded = true;
|
|
|
|
if (random() % 3 == 0) {
|
|
firing[HAND_LEFT] = flip;
|
|
firing[HAND_RIGHT] = !flip;
|
|
} else {
|
|
firing[HAND_LEFT] = true;
|
|
firing[HAND_RIGHT] = true;
|
|
}
|
|
} else {
|
|
flip = (bool)rightgun2 == false;
|
|
onehanded = true;
|
|
firing[HAND_LEFT] = flip;
|
|
firing[HAND_RIGHT] = !flip;
|
|
}
|
|
} else {
|
|
if (weaponIsOneHanded(leftgun) || weaponIsOneHanded(rightgun)) {
|
|
flip = (bool)leftgun != false;
|
|
onehanded = true;
|
|
firing[HAND_LEFT] = flip;
|
|
firing[HAND_RIGHT] = !flip;
|
|
} else {
|
|
flip = (bool)leftgun != false;
|
|
firing[HAND_LEFT] = flip;
|
|
firing[HAND_RIGHT] = !flip;
|
|
}
|
|
}
|
|
|
|
if ((toleft && !flip) || (!toleft && flip)) {
|
|
// Roll to left
|
|
if (random() % 2) {
|
|
animcfg = &g_RollAttackAnims[0];
|
|
} else {
|
|
animcfg = &g_RollAttackAnims[2];
|
|
}
|
|
} else {
|
|
// Roll to right
|
|
if (random() % 2) {
|
|
animcfg = &g_RollAttackAnims[1];
|
|
} else {
|
|
animcfg = &g_RollAttackAnims[3];
|
|
}
|
|
}
|
|
|
|
if (onehanded) {
|
|
// Move the animation pointer to the one-handed version of the same
|
|
// animation. The one-handed versions are in the array immediately after
|
|
// the four heavy-weapon versions.
|
|
animcfg += 4;
|
|
}
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
if (firing[i]) {
|
|
prop = chrGetHeldProp(chr, i);
|
|
weapon = prop->weapon;
|
|
|
|
if (weaponGetNumTicksPerShot(weapon->weaponnum, weapon->gunfunc) < 1) {
|
|
everytick[i] = true;
|
|
|
|
if (weapon->weaponnum == WEAPON_LASER) {
|
|
dorecoil = false;
|
|
}
|
|
} else {
|
|
dorecoil = false;
|
|
dooneburst = true;
|
|
}
|
|
|
|
if (weapon->weaponnum == WEAPON_ROCKETLAUNCHER
|
|
|| weapon->weaponnum == WEAPON_ROCKETLAUNCHER_34
|
|
|| weapon->weaponnum == WEAPON_SLAYER
|
|
|| weapon->weaponnum == WEAPON_DEVASTATOR
|
|
|| (
|
|
!g_Vars.normmplayerisrunning
|
|
&& weapon->weaponnum == WEAPON_DY357MAGNUM
|
|
&& chr->headnum != HEAD_JONATHAN
|
|
&& chr->headnum != HEAD_CHRIST)
|
|
|| (
|
|
!g_Vars.normmplayerisrunning
|
|
&& weapon->weaponnum == WEAPON_DY357LX)
|
|
|| (
|
|
!g_Vars.normmplayerisrunning
|
|
&& weapon->weaponnum == WEAPON_SHOTGUN)) {
|
|
singleshot[i] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
chr->actiontype = ACT_ATTACKROLL;
|
|
|
|
chr->act_attack.animcfg = animcfg;
|
|
chr->act_attack.fired = false;
|
|
chr->act_attack.nextgun = random() % 2;
|
|
chr->act_attack.firegun[HAND_LEFT] = firing[HAND_LEFT];
|
|
chr->act_attack.firegun[HAND_RIGHT] = firing[HAND_RIGHT];
|
|
chr->act_attack.everytick[HAND_LEFT] = everytick[HAND_LEFT];
|
|
chr->act_attack.everytick[HAND_RIGHT] = everytick[HAND_RIGHT];
|
|
chr->act_attack.singleshot[HAND_LEFT] = singleshot[HAND_LEFT];
|
|
chr->act_attack.singleshot[HAND_RIGHT] = singleshot[HAND_RIGHT];
|
|
chr->act_attack.dorecoil = dorecoil;
|
|
chr->act_attack.dooneburst = dooneburst;
|
|
chr->act_attack.onehanded = onehanded;
|
|
chr->act_attack.pausecount = 0;
|
|
chr->act_attack.numshots = 0;
|
|
chr->act_attack.turning = TURNSTATE_TURNING;
|
|
|
|
if (singleshot[HAND_LEFT] || singleshot[HAND_RIGHT]) {
|
|
if (singleshot[HAND_LEFT] && singleshot[HAND_RIGHT]) {
|
|
chr->act_attack.maxshots = 2;
|
|
} else {
|
|
chr->act_attack.maxshots = 1;
|
|
}
|
|
} else {
|
|
chr->act_attack.maxshots = (random() % 4) + 2;
|
|
|
|
if (firing[HAND_RIGHT] && firing[HAND_LEFT]) {
|
|
chr->act_attack.maxshots += (random() % 4) + 2;
|
|
}
|
|
}
|
|
|
|
chr->act_attack.flags = ATTACKFLAG_AIMATTARGET;
|
|
chr->act_attack.entityid = 0;
|
|
chr->act_attack.standing = true;
|
|
chr->act_attack.reaim = 0;
|
|
chr->act_attack.lastfire60 = 0;
|
|
chr->act_attack.lastontarget60 = 0;
|
|
chr->act_attack.flip = flip;
|
|
|
|
chr->sleep = 0;
|
|
|
|
// @bug: CHRCFLAG_INJUREDTARGET is not unset here. This means if the chr
|
|
// does an attack that hits the target, then does a roll attack which
|
|
// misses, their AI list will incorrectly read the roll attack as a hit
|
|
// provided it didn't read and clear the flag between the attacks.
|
|
// It usually (always?) does though, so this isn't really an issue.
|
|
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrAttackRollChooseAnimation(chr);
|
|
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrStartAnim(struct chrdata *chr, s32 animnum, f32 startframe, f32 endframe, u8 chranimflags, s32 merge, f32 speed)
|
|
{
|
|
u32 stack;
|
|
|
|
if (chr && chr->model) {
|
|
if (chranimflags & CHRANIMFLAG_REVERSE) {
|
|
speed = -speed;
|
|
}
|
|
|
|
if (CHRRACE(chr) != RACE_DRCAROLL) {
|
|
chrStopFiring(chr);
|
|
}
|
|
|
|
chr->actiontype = ACT_ANIM;
|
|
|
|
chr->act_anim.movewheninvis = (chranimflags & CHRANIMFLAG_MOVEWHENINVIS) != 0;
|
|
chr->act_anim.pauseatend = (chranimflags & CHRANIMFLAG_PAUSEATEND) != 0;
|
|
chr->act_anim.completed = (chranimflags & CHRANIMFLAG_COMPLETED) != 0;
|
|
chr->act_anim.slowupdate = (chranimflags & CHRANIMFLAG_SLOWUPDATE) != 0;
|
|
chr->act_anim.lockpos = (chranimflags & CHRANIMFLAG_LOCKPOS) != 0;
|
|
chr->act_anim.ishitanim = false;
|
|
chr->act_anim.animnum = animnum;
|
|
chr->act_anim.flip = (chranimflags & CHRANIMFLAG_FLIP) != 0;
|
|
chr->act_anim.startframe = startframe;
|
|
chr->act_anim.endframe = endframe;
|
|
chr->act_anim.speed = speed;
|
|
chr->act_anim.blend = merge;
|
|
|
|
chr->sleep = chr->act_anim.slowupdate ? merge : 0;
|
|
|
|
if (merge > 0 && modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
modelSetAnimation(chr->model, animnum, (chranimflags & CHRANIMFLAG_FLIP) != 0, startframe, speed, merge);
|
|
|
|
if (endframe >= 0) {
|
|
modelSetAnimEndFrame(chr->model, endframe);
|
|
}
|
|
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrBeginDead(struct chrdata *chr)
|
|
{
|
|
if (chr->actiontype != ACT_DEAD) {
|
|
chrStopFiring(chr);
|
|
|
|
if (chr->cover != -1) {
|
|
coverSetInUse(chr->cover, false);
|
|
chr->cover = -1;
|
|
}
|
|
|
|
chr->actiontype = ACT_DEAD;
|
|
chr->act_dead.fadetimer60 = chr->aibot ? 0 : -1;
|
|
chr->act_dead.fadenow = false;
|
|
chr->act_dead.fadewheninvis = false;
|
|
chr->act_dead.invistimer60 = 0;
|
|
chr->act_dead.notifychrindex = 0;
|
|
chr->sleep = 0;
|
|
|
|
if (chr->race == RACE_DRCAROLL) {
|
|
chr->drcarollimage_left = DRCAROLLIMAGE_STATIC;
|
|
chr->drcarollimage_right = DRCAROLLIMAGE_STATIC;
|
|
}
|
|
}
|
|
}
|
|
|
|
void func0f031254(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
struct attackanimconfig *animcfg = chr->act_attack.animcfg;
|
|
|
|
if (chr->act_attack.flags & ATTACKFLAG_AIMONLY) {
|
|
if (animcfg->unk20 >= 0 && animcfg->unk20 < animcfg->unk18) {
|
|
modelSetAnimEndFrame(model, animcfg->unk20);
|
|
} else {
|
|
modelSetAnimEndFrame(model, animcfg->unk18);
|
|
}
|
|
} else if (chr->act_attack.dorecoil) {
|
|
if (animcfg->unk20 >= 0) {
|
|
modelSetAnimEndFrame(model, animcfg->unk20);
|
|
} else {
|
|
modelSetAnimEndFrame(model, animcfg->unk18);
|
|
}
|
|
} else {
|
|
if (animcfg->unk20 >= 0) {
|
|
modelSetAnimEndFrame(model, animcfg->unk20);
|
|
} else if (animcfg->unk14 >= 0) {
|
|
modelSetAnimEndFrame(model, animcfg->unk14);
|
|
} else {
|
|
modelSetAnimEndFrame(model, -1);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function implements attack behaviour common to all the attack types,
|
|
* such as stand, kneel and lie.
|
|
*/
|
|
void chrAttack(struct chrdata *chr, struct attackanimgroup **animgroups, bool flip, bool *firing, u32 attackflags, s32 entityid, bool standing)
|
|
{
|
|
struct model *model = chr->model;
|
|
s32 i;
|
|
f32 angle;
|
|
struct attackanimconfig *animcfg;
|
|
struct prop *prop;
|
|
struct weaponobj *weapon;
|
|
s32 groupindex;
|
|
bool dooneburst = false;
|
|
s32 index;
|
|
bool everytick[] = {false, false};
|
|
bool singleshot[] = {false, false};
|
|
bool dorecoil = true;
|
|
s32 race = CHRRACE(chr);
|
|
u8 sniping = false;
|
|
|
|
if (race != RACE_DRCAROLL && race != RACE_EYESPY && race != RACE_ROBOT) {
|
|
chr->actiontype = ACT_ATTACK;
|
|
|
|
if (&animgroups[0] == &g_LieAttackAnims) {
|
|
sniping = true;
|
|
|
|
if (modelGetAnimNum(chr->model) != ANIM_SNIPING_ONGROUND) {
|
|
// Getting up or getting down
|
|
animcfg = var80067d28;
|
|
modelSetAnimation(model, animcfg->animnum, flip, animcfg->unk10, chrGetRangedSpeed(chr, 0.5f, 0.8f), 16);
|
|
modelSetAnimEndFrame(model, 236);
|
|
} else {
|
|
animcfg = var80067d70;
|
|
}
|
|
} else {
|
|
// Non-sniping animations: Choose animation based on angle to target
|
|
angle = chrGetAttackEntityRelativeAngle(chr, attackflags, entityid);
|
|
|
|
if (flip) {
|
|
groupindex = (M_BADTAU - angle) * 5.0937690734863f + 0.5f;
|
|
} else {
|
|
groupindex = angle * 5.0937690734863f + 0.5f;
|
|
}
|
|
|
|
if (groupindex < 0 || groupindex > 31) {
|
|
groupindex = 0;
|
|
}
|
|
|
|
index = random() % animgroups[groupindex]->len;
|
|
animcfg = &animgroups[groupindex]->animcfg[index];
|
|
}
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
if (firing[i]) {
|
|
prop = chrGetHeldProp(chr, i);
|
|
|
|
if (prop == NULL) {
|
|
chrChooseStandAnimation(chr, 16);
|
|
return;
|
|
}
|
|
|
|
weapon = prop->weapon;
|
|
|
|
if (weaponGetNumTicksPerShot(weapon->weaponnum, weapon->gunfunc) < 1) {
|
|
// Note: the only weapon that can enter this branch is the laser
|
|
everytick[i] = true;
|
|
|
|
if (weapon->weaponnum == WEAPON_LASER) {
|
|
dorecoil = false;
|
|
}
|
|
} else {
|
|
dorecoil = false;
|
|
dooneburst = true;
|
|
}
|
|
|
|
// There's an easter egg here: Any guard with Chris T's head
|
|
// (Foster from the firing range) can fire multiple shots with
|
|
// the magnum.
|
|
if (weapon->weaponnum == WEAPON_ROCKETLAUNCHER
|
|
|| weapon->weaponnum == WEAPON_ROCKETLAUNCHER_34
|
|
|| weapon->weaponnum == WEAPON_SLAYER
|
|
|| weapon->weaponnum == WEAPON_DEVASTATOR
|
|
|| (
|
|
!g_Vars.normmplayerisrunning
|
|
&& weapon->weaponnum == WEAPON_DY357MAGNUM
|
|
&& chr->headnum != HEAD_JONATHAN
|
|
&& chr->headnum != HEAD_CHRIST)
|
|
|| (
|
|
!g_Vars.normmplayerisrunning
|
|
&& weapon->weaponnum == WEAPON_DY357LX)
|
|
|| (
|
|
!g_Vars.normmplayerisrunning
|
|
&& weapon->weaponnum == WEAPON_SHOTGUN)) {
|
|
singleshot[i] = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
chr->act_attack.turning = TURNSTATE_TURNING;
|
|
chr->act_attack.animcfg = animcfg;
|
|
chr->act_attack.fired = false;
|
|
chr->act_attack.nextgun = random() % 2;
|
|
chr->act_attack.firegun[HAND_LEFT] = firing[HAND_LEFT];
|
|
chr->act_attack.firegun[HAND_RIGHT] = firing[HAND_RIGHT];
|
|
chr->act_attack.everytick[HAND_LEFT] = everytick[HAND_LEFT];
|
|
chr->act_attack.everytick[HAND_RIGHT] = everytick[HAND_RIGHT];
|
|
chr->act_attack.singleshot[HAND_LEFT] = singleshot[HAND_LEFT];
|
|
chr->act_attack.singleshot[HAND_RIGHT] = singleshot[HAND_RIGHT];
|
|
chr->act_attack.dorecoil = dorecoil;
|
|
chr->act_attack.dooneburst = dooneburst;
|
|
chr->act_attack.pausecount = 0;
|
|
chr->act_attack.numshots = 0;
|
|
|
|
if (singleshot[HAND_LEFT] || singleshot[HAND_RIGHT]) {
|
|
if (singleshot[HAND_LEFT] && singleshot[HAND_RIGHT]) {
|
|
chr->act_attack.maxshots = 2;
|
|
} else {
|
|
chr->act_attack.maxshots = 1;
|
|
}
|
|
} else {
|
|
if (attackflags & ATTACKFLAG_SINGLESHOT) {
|
|
chr->act_attack.maxshots = 1;
|
|
} else {
|
|
chr->act_attack.maxshots = (random() % 4) + 2;
|
|
}
|
|
|
|
// @bug: ATTACKFLAG_SINGLESHOT is not respected here if both guns
|
|
// are firing.
|
|
if (firing[HAND_RIGHT] && firing[HAND_LEFT]) {
|
|
chr->act_attack.maxshots += (random() % 4) + 2;
|
|
}
|
|
}
|
|
|
|
chr->act_attack.flags = attackflags;
|
|
chr->act_attack.entityid = entityid;
|
|
chr->act_attack.standing = standing;
|
|
chr->act_attack.reaim = 0;
|
|
chr->act_attack.lastfire60 = 0;
|
|
chr->act_attack.lastontarget60 = 0;
|
|
chr->act_attack.flip = flip;
|
|
|
|
chr->sleep = 0;
|
|
chr->chrflags &= ~CHRCFLAG_INJUREDTARGET;
|
|
|
|
if (!sniping && !chr->aibot) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
modelSetAnimation(model, animcfg->animnum, flip, animcfg->unk10, chrGetRangedSpeed(chr, 0.5f, 0.8f), 16);
|
|
func0f031254(chr);
|
|
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrAttackAmount(struct chrdata *chr, u32 attackflags, u32 entityid, u32 maxshots)
|
|
{
|
|
u32 stack;
|
|
struct prop *prop = chrGetHeldProp(chr, 0);
|
|
struct attackanimgroup **things = NULL;
|
|
bool firing[] = {false, false};
|
|
u32 race = CHRRACE(chr);
|
|
|
|
if (prop) {
|
|
things = weaponIsOneHanded(prop) ? g_StandLightAttackAnims[race] : g_StandHeavyAttackAnims[race];
|
|
|
|
firing[1] = false;
|
|
firing[0] = true;
|
|
}
|
|
|
|
chrAttack(chr, things, false, firing, attackflags, entityid, false);
|
|
|
|
chr->actiontype = ACT_ATTACKAMOUNT;
|
|
chr->act_attack.numshots = 0;
|
|
chr->act_attack.maxshots = maxshots;
|
|
chr->act_attack.dooneburst = false;
|
|
}
|
|
|
|
#if PAL
|
|
s32 g_DrCarollDyingTimer = 8;
|
|
#else
|
|
s32 g_DrCarollDyingTimer = 10;
|
|
#endif
|
|
|
|
u8 var80068080 = 50;
|
|
|
|
/**
|
|
* Given a perfectly alive chr, make them begin the process of dying or being
|
|
* knocked unconscious.
|
|
*
|
|
* This function handles:
|
|
* - Eyespy destruction
|
|
* - Transitioning to ACT_DIE
|
|
* - Choosing and applying death animations
|
|
* - Updating kill statistics
|
|
* - Dropping items
|
|
*/
|
|
void chrBeginDeath(struct chrdata *chr, struct coord *dir, f32 relangle, s32 hitpart, struct gset *gset, bool knockout, s32 aplayernum)
|
|
{
|
|
bool overridden = false;
|
|
bool instant;
|
|
s32 index = -1;
|
|
s32 animnum;
|
|
u32 stack1;
|
|
struct prop *prop = chr->prop;
|
|
struct model *model = chr->model;
|
|
u32 stack2;
|
|
s32 race = CHRRACE(chr);
|
|
bool wasknockedout = false;
|
|
s32 prevplayernum;
|
|
s32 i;
|
|
s32 buddyplayernum;
|
|
struct eyespy *eyespy;
|
|
s32 objectivenum;
|
|
f32 mult1;
|
|
f32 mult2;
|
|
f32 mult3;
|
|
|
|
// If chr was previously knocked out, they are now dead so decrease KO counter
|
|
if (chr->actiontype == ACT_DRUGGEDCOMINGUP
|
|
|| chr->actiontype == ACT_DRUGGEDDROP
|
|
|| chr->actiontype == ACT_DRUGGEDKO) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (chr->actiontype == ACT_DRUGGEDKO) {
|
|
wasknockedout = true;
|
|
}
|
|
#else
|
|
wasknockedout = true;
|
|
#endif
|
|
|
|
mpstatsDecrementTotalKnockoutCount();
|
|
}
|
|
|
|
// Handle eyespy then return early
|
|
if (race == RACE_EYESPY) {
|
|
prevplayernum = g_Vars.currentplayernum;
|
|
buddyplayernum = -1;
|
|
eyespy = chrToEyespy(chr);
|
|
objectivenum = -1;
|
|
|
|
// Figure out which playernum has the eyespy that's being destroyed,
|
|
// and the buddy's playernum if applicable. Note that the player count
|
|
// can only be 1 or 2 here.
|
|
for (i = 0; i < PLAYERCOUNT(); i++) {
|
|
if (eyespy == g_Vars.players[i]->eyespy) {
|
|
setCurrentPlayerNum(i);
|
|
} else {
|
|
buddyplayernum = i;
|
|
}
|
|
}
|
|
|
|
if (g_Vars.currentplayer->eyespy) {
|
|
// Stop using eyespy if active
|
|
if (g_Vars.currentplayer->eyespy->active) {
|
|
g_Vars.currentplayer->eyespy->active = false;
|
|
g_Vars.currentplayer->devicesactive &= ~DEVICE_EYESPY;
|
|
}
|
|
|
|
// Destroy the eyespy
|
|
chr->hidden |= CHRHFLAG_REAPED;
|
|
|
|
explosionCreateSimple(g_Vars.currentplayer->eyespy->prop,
|
|
&g_Vars.currentplayer->eyespy->prop->pos,
|
|
g_Vars.currentplayer->eyespy->prop->rooms, EXPLOSIONTYPE_EYESPY, 0);
|
|
invRemoveItemByNum(WEAPON_EYESPY);
|
|
|
|
func0f0926bc(g_Vars.currentplayer->eyespy->prop, 1, 0xffff);
|
|
g_Vars.currentplayer->eyespy = NULL;
|
|
setCurrentPlayerNum(prevplayernum);
|
|
|
|
// For Investigation and G5 Building, set a stage flag to show that
|
|
// the eyespy is destroyed. The scripting in those stages checks for
|
|
// this flag and fails the objective if set.
|
|
switch (stageGetIndex(g_Vars.stagenum)) {
|
|
case STAGEINDEX_INVESTIGATION:
|
|
objectivenum = 0;
|
|
break;
|
|
case STAGEINDEX_G5BUILDING:
|
|
if (lvGetDifficulty() == DIFF_A) {
|
|
objectivenum = 2;
|
|
} else if (lvGetDifficulty() == DIFF_SA) {
|
|
objectivenum = 2;
|
|
} else {
|
|
objectivenum = 2;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// But don't set the flag if the coop buddy still has an eyespy
|
|
if (objectivenum >= 0 && buddyplayernum >= 0) {
|
|
setCurrentPlayerNum(buddyplayernum);
|
|
|
|
if (g_Vars.currentplayer->eyespy) {
|
|
objectivenum = -1;
|
|
}
|
|
|
|
setCurrentPlayerNum(prevplayernum);
|
|
}
|
|
|
|
if (objectivenum >= 0 && objectiveCheck(objectivenum) != OBJECTIVE_COMPLETE) {
|
|
g_StageFlags |= STAGEFLAG_EYESPY_DESTROYED;
|
|
}
|
|
}
|
|
|
|
setCurrentPlayerNum(prevplayernum);
|
|
return;
|
|
}
|
|
|
|
// instant = whether to merge into death animation or switch to it instantly
|
|
instant = chr->actiontype == ACT_ARGH && chr->act_argh.lvframe60 == g_Vars.lvframe60;
|
|
|
|
for (i = 0; g_AnimTablesByRace[race][i].hitpart != -1; i++) {
|
|
if (g_AnimTablesByRace[race][i].hitpart == hitpart) {
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Set up chr's new action
|
|
chr->blurdrugamount = 0;
|
|
|
|
chrStopFiring(chr);
|
|
chrUncloak(chr, true);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
chr->chrflags &= ~CHRCFLAG_HIDDEN;
|
|
#endif
|
|
|
|
chr->actiontype = (knockout == true ? ACT_DRUGGEDDROP : ACT_DIE);
|
|
|
|
chr->act_die.notifychrindex = 0;
|
|
chr->act_die.timeextra = 0;
|
|
chr->act_die.drcarollimagedelay = TICKS(45);
|
|
chr->act_die.thudframe1 = -1;
|
|
chr->act_die.thudframe2 = -1;
|
|
|
|
if (chr->race == RACE_DRCAROLL) {
|
|
chr->drcarollimage_left = (s32)((random() % 400) * 0.01f) + 1;
|
|
chr->drcarollimage_right = (s32)((random() % 400) * 0.01f) + 1;
|
|
}
|
|
|
|
chr->sleep = 0;
|
|
|
|
// Handle robots and Dr Caroll then return early
|
|
if (race == RACE_ROBOT || race == RACE_DRCAROLL) {
|
|
mult1 = gsetGetStrength(gset) * 0.5f;
|
|
|
|
if (mult1 <= 0) {
|
|
mult1 = 3;
|
|
}
|
|
|
|
if (mult1 != 0.0f) {
|
|
chr->elapseextra = 0;
|
|
chr->timeextra = mult1 * 15;
|
|
chr->extraspeed.x = dir->x * mult1;
|
|
chr->extraspeed.y = dir->y * mult1;
|
|
chr->extraspeed.z = dir->z * mult1;
|
|
}
|
|
|
|
if (race == RACE_DRCAROLL) {
|
|
g_DrCarollDyingTimer = 0;
|
|
|
|
chr->soundtimer = 0;
|
|
chr->voicebox = VOICEBOX_MALE1;
|
|
|
|
modelSetAnimation(chr->model, ANIM_0164, false, 0, 0.5f, 16);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Handle humans and Skedar
|
|
if (race == RACE_HUMAN) {
|
|
animnum = modelGetAnimNum(chr->model);
|
|
|
|
// Chrs in lying-down sniping poses don't use standard death animations
|
|
if (animnum == ANIM_SNIPING_GETDOWN
|
|
|| animnum == ANIM_SNIPING_GETUP
|
|
|| animnum == ANIM_SNIPING_ONGROUND) {
|
|
modelSetAnimation(chr->model, ANIM_SNIPING_DIE, false, 0, 0.5f, 16);
|
|
} else {
|
|
// Consider making the chr do an animation where they slump against
|
|
// a wall or object which is behind them.
|
|
if ((relangle < 1.5705462694168f || relangle > 4.7116389274597f)
|
|
&& random() % 20 == 0
|
|
&& chr->specialdie == SPECIALDIE_NONE) {
|
|
f32 angle1;
|
|
f32 angle2 = chrGetInverseTheta(chr);
|
|
f32 fval1;
|
|
f32 fval2;
|
|
|
|
angle1 = angle2 + 3.3155977725983f;
|
|
angle2 += 2.966587305069f;
|
|
|
|
if (angle1 >= M_BADTAU) {
|
|
angle1 -= M_BADTAU;
|
|
}
|
|
|
|
if (angle2 >= M_BADTAU) {
|
|
angle2 -= M_BADTAU;
|
|
}
|
|
|
|
fval1 = func0f02e684(prop, angle1, 150);
|
|
fval2 = func0f02e684(prop, angle2, 150);
|
|
|
|
if (fval1 < 150 && fval2 < 150
|
|
&& fval1 - fval2 < 10 && fval1 - fval2 > -10
|
|
&& !wasknockedout) {
|
|
struct animtablerow *row = &g_AnimTableHumanSlumped[random() % 4];
|
|
u32 stack3;
|
|
|
|
chr->act_die.thudframe1 = row->thudframe1;
|
|
chr->act_die.thudframe2 = row->thudframe2;
|
|
|
|
modelSetAnimationWithMerge(model, row->animnum, row->flip, 0, row->speed, 16, !instant);
|
|
|
|
if (row->endframe >= 0) {
|
|
modelSetAnimEndFrame(model, row->endframe);
|
|
}
|
|
|
|
chr->radius = 10;
|
|
chr->chrflags &= ~CHRCFLAG_HAS_SPECIAL_DEATH_ANIMATION;
|
|
|
|
overridden = true;
|
|
}
|
|
}
|
|
|
|
// Consider making the chr do a fall forward animation.
|
|
// The player must be behind the chr for it to happen.
|
|
if (relangle > 2.3558194637299f && relangle < 3.9263656139374f
|
|
&& random() % 5 < 2
|
|
&& chr->specialdie == SPECIALDIE_NONE) {
|
|
struct animtablerow *row;
|
|
|
|
struct animtablerow rows[] = {
|
|
{ 0x005b, 0, -1, 0.6, 0, 27, -1 },
|
|
{ 0x0255, 0, -1, 0.5, 0, 25, -1 },
|
|
};
|
|
|
|
bool flip;
|
|
|
|
overridden = true;
|
|
|
|
if (hitpart == HITPART_LBICEP || hitpart == HITPART_RBICEP) {
|
|
row = &rows[0];
|
|
|
|
if (hitpart == HITPART_LBICEP) {
|
|
flip = true;
|
|
} else {
|
|
flip = false;
|
|
}
|
|
} else {
|
|
row = &rows[1];
|
|
flip = random() % 2;
|
|
}
|
|
|
|
chr->act_die.thudframe1 = row->thudframe1;
|
|
chr->act_die.thudframe2 = row->thudframe2;
|
|
|
|
modelSetAnimationWithMerge(model, row->animnum, flip, 0, row->speed, 16, !instant);
|
|
|
|
if (row->endframe >= 0) {
|
|
modelSetAnimEndFrame(model, chrGetRangedArghSpeed(chr, row->endframe, 8));
|
|
} else {
|
|
modelSetAnimEndFrame(model, chrGetRangedArghSpeed(chr, animGetNumFrames(row->animnum) - 1, 8));
|
|
}
|
|
|
|
chr->chrflags &= ~CHRCFLAG_HAS_SPECIAL_DEATH_ANIMATION;
|
|
}
|
|
|
|
if (!overridden && index >= 0) {
|
|
// Handle specialdie animations or choose a random one if not
|
|
// using specialdie
|
|
if (g_AnimTablesByRace[race][index].deathanims
|
|
&& g_AnimTablesByRace[race][index].deathanimcount > 0
|
|
&& !wasknockedout) {
|
|
struct animtablerow *row;
|
|
|
|
if (chr->specialdie == SPECIALDIE_NONE) {
|
|
s32 tmp = random() % g_AnimTablesByRace[race][index].deathanimcount;
|
|
row = &g_AnimTablesByRace[race][index].deathanims[tmp];
|
|
} else if (chr->specialdie == SPECIALDIE_ONCHAIR) {
|
|
row = &g_SpecialDieAnims[chr->specialdie + random() % 2];
|
|
|
|
// chr->myspecial is the tag number of the chr's chair
|
|
if (chr->myspecial >= 0) {
|
|
struct defaultobj *obj = objFindByTagId(chr->myspecial);
|
|
obj->flags3 &= ~OBJFLAG3_PUSHABLE;
|
|
obj->flags |= OBJFLAG_INVINCIBLE;
|
|
|
|
// The original source likely didn't have the brackets here,
|
|
// but I'm including them to show the logic that's actually
|
|
// being used. There is no bug here, as obj and obj->prop
|
|
// are always set at this point so these checks are
|
|
// unnecessary.
|
|
if ((obj && obj->prop && obj->modelnum == MODEL_DD_REDARM)
|
|
|| obj->modelnum == MODEL_DD_REDSOFA) {
|
|
row = &g_SpecialDieAnims[chr->specialdie - 1];
|
|
}
|
|
}
|
|
} else {
|
|
row = &g_SpecialDieAnims[chr->specialdie - 1];
|
|
}
|
|
|
|
chr->act_die.thudframe1 = row->thudframe1;
|
|
chr->act_die.thudframe2 = row->thudframe2;
|
|
|
|
if (chr->specialdie == SPECIALDIE_NONE) {
|
|
modelSetAnimationWithMerge(model, row->animnum, row->flip, 0, row->speed, 16, !instant);
|
|
} else {
|
|
modelSetAnimationWithMerge(model, row->animnum, row->flip, 0, row->speed, 30, !instant);
|
|
}
|
|
|
|
if (row->endframe >= 0) {
|
|
modelSetAnimEndFrame(model, row->endframe);
|
|
}
|
|
|
|
mult2 = gsetGetStrength(gset);
|
|
|
|
if (mult2 <= 0 && (chr->chrflags & CHRCFLAG_DIEWITHFORCE)) {
|
|
mult2 = 6;
|
|
}
|
|
|
|
if (row->unk10 && mult2 > 0) {
|
|
chr->act_die.timeextra = mult2 * 15;
|
|
chr->act_die.elapseextra = 0;
|
|
chr->act_die.extraspeed.x = dir->x * mult2;
|
|
chr->act_die.extraspeed.y = dir->y * mult2;
|
|
chr->act_die.extraspeed.z = dir->z * mult2;
|
|
}
|
|
|
|
chr->chrflags &= ~CHRCFLAG_HAS_SPECIAL_DEATH_ANIMATION;
|
|
}
|
|
}
|
|
}
|
|
} else if (race == RACE_SKEDAR) {
|
|
struct animtablerow *row;
|
|
|
|
if (relangle > 2.3558194637299f && relangle < 3.9263656139374f) {
|
|
// Player is behind the Skedar - use specific set of anims
|
|
row = &g_AnimTablesByRace[race][1 + (random() % 6)].deathanims[random() % 3];
|
|
|
|
chr->act_die.thudframe1 = row->thudframe1;
|
|
chr->act_die.thudframe2 = row->thudframe2;
|
|
|
|
modelSetAnimationWithMerge(model, row->animnum, row->flip, 0, row->speed, 16, !instant);
|
|
|
|
if (row->endframe >= 0) {
|
|
modelSetAnimEndFrame(model, row->endframe);
|
|
}
|
|
} else {
|
|
// Normal Skedar death
|
|
if (index >= 0
|
|
&& g_AnimTablesByRace[race][index].deathanims != NULL
|
|
&& g_AnimTablesByRace[race][index].deathanimcount > 0) {
|
|
s32 tmp = random() % g_AnimTablesByRace[race][index].deathanimcount;
|
|
row = &g_AnimTablesByRace[race][index].deathanims[tmp];
|
|
} else {
|
|
row = &g_AnimTablesByRace[race][0].deathanims[0];
|
|
}
|
|
|
|
chr->act_die.thudframe1 = row->thudframe1;
|
|
chr->act_die.thudframe2 = row->thudframe2;
|
|
|
|
modelSetAnimationWithMerge(model, row->animnum, row->flip, 0, row->speed, 16, !instant);
|
|
|
|
if (row->endframe >= 0) {
|
|
modelSetAnimEndFrame(model, row->endframe);
|
|
}
|
|
|
|
mult3 = gsetGetStrength(gset);
|
|
|
|
if (mult3 <= 0 && (chr->chrflags & CHRCFLAG_DIEWITHFORCE)) {
|
|
mult3 = 6;
|
|
}
|
|
|
|
if (row->unk10 != 0 && mult3 > 0) {
|
|
chr->act_die.timeextra = mult3 * 15;
|
|
chr->act_die.elapseextra = 0;
|
|
chr->act_die.extraspeed.x = dir->x * mult3;
|
|
chr->act_die.extraspeed.y = dir->y * mult3;
|
|
chr->act_die.extraspeed.z = dir->z * mult3;
|
|
}
|
|
}
|
|
} else if (race == RACE_DRCAROLL) {
|
|
// empty
|
|
}
|
|
|
|
// Handle multiplayer stats and kill count
|
|
if (g_Vars.mplayerisrunning) {
|
|
mpstatsRecordDeath(aplayernum, mpPlayerGetIndex(chr));
|
|
} else if (aplayernum >= 0) {
|
|
s32 prevplayernum = g_Vars.currentplayernum;
|
|
setCurrentPlayerNum(aplayernum);
|
|
mpstatsRecordPlayerKill();
|
|
setCurrentPlayerNum(prevplayernum);
|
|
}
|
|
|
|
if (chr->chrflags & CHRCFLAG_KILLCOUNTABLE) {
|
|
mpstatsIncrementTotalKillCount();
|
|
}
|
|
|
|
// Drop items
|
|
if (race == RACE_HUMAN || race == RACE_SKEDAR) {
|
|
if (chr->weapons_held[0] && (chr->weapons_held[0]->obj->flags & OBJFLAG_AIUNDROPPABLE) == 0) {
|
|
objSetDropped(chr->weapons_held[0], DROPTYPE_DEFAULT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
}
|
|
|
|
if (chr->weapons_held[1] && (chr->weapons_held[1]->obj->flags & OBJFLAG_AIUNDROPPABLE) == 0) {
|
|
objSetDropped(chr->weapons_held[1], DROPTYPE_DEFAULT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
}
|
|
|
|
chrDropConcealedItems(chr);
|
|
}
|
|
}
|
|
|
|
void chrBeginArgh(struct chrdata *chr, f32 angle, s32 hitpart)
|
|
{
|
|
bool doneanim = false;
|
|
s32 instant;
|
|
s32 index = -1;
|
|
struct model *model = chr->model;
|
|
s32 i;
|
|
s32 race = CHRRACE(chr);
|
|
s32 animnum = modelGetAnimNum(chr->model);
|
|
|
|
if (animnum == ANIM_SNIPING_GETDOWN
|
|
|| animnum == ANIM_SNIPING_GETUP
|
|
|| animnum == ANIM_SNIPING_ONGROUND) {
|
|
chrFlinchBody(chr);
|
|
return;
|
|
}
|
|
|
|
if (race == RACE_EYESPY || chr->aibot) {
|
|
return;
|
|
}
|
|
|
|
if (race == RACE_DRCAROLL) {
|
|
chr->actiontype = ACT_ARGH;
|
|
chr->act_argh.notifychrindex = 0;
|
|
chr->act_argh.lvframe60 = g_Vars.lvframe60;
|
|
|
|
chr->sleep = 0;
|
|
|
|
modelSetAnimation(chr->model, ANIM_0163, false, 0, 0.5f, 16);
|
|
|
|
chr->drcarollimage_left = DRCAROLLIMAGE_X;
|
|
chr->drcarollimage_right = DRCAROLLIMAGE_X;
|
|
return;
|
|
}
|
|
|
|
instant = chr->actiontype == ACT_ARGH && chr->act_argh.lvframe60 == g_Vars.lvframe60;
|
|
|
|
for (i = 0; g_AnimTablesByRace[race][i].hitpart != -1; i++) {
|
|
if (g_AnimTablesByRace[race][i].hitpart == hitpart) {
|
|
index = i;
|
|
|
|
if (chr->hitpart == 0) {
|
|
chr->hitpart = hitpart;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If shot in the butt from behind, 2 in 5 chance of doing a special anim
|
|
if (race == RACE_HUMAN
|
|
&& hitpart == HITPART_PELVIS
|
|
&& angle > 2.3558194637299f
|
|
&& angle < 3.9263656139374f
|
|
&& random() % 5 < 2) {
|
|
struct animtablerow *row;
|
|
struct animtablerow rows[] = {
|
|
{ 0x013b, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0x013c, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0x013f, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0x0142, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0x0145, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0x0148, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0x0036, 0, -1, 0.5, 0, -1, -1 },
|
|
{ 0x0037, 0, -1, 0.5, 0, -1, -1 },
|
|
};
|
|
|
|
chrStopFiring(chr);
|
|
|
|
chr->actiontype = ACT_ARGH;
|
|
chr->act_argh.notifychrindex = 0;
|
|
chr->act_argh.lvframe60 = g_Vars.lvframe60;
|
|
chr->sleep = 0;
|
|
|
|
row = &rows[random() % 8];
|
|
|
|
modelSetAnimationWithMerge(model, row->animnum, row->flip, 0, row->speed, 16, !instant);
|
|
|
|
if (row->endframe >= 0) {
|
|
modelSetAnimEndFrame(model, chrGetRangedArghSpeed(chr, row->endframe, 8));
|
|
doneanim = true;
|
|
} else {
|
|
modelSetAnimEndFrame(model, chrGetRangedArghSpeed(chr, animGetNumFrames(row->animnum) - 1, 8));
|
|
doneanim = true;
|
|
}
|
|
}
|
|
|
|
if (!doneanim
|
|
&& index >= 0
|
|
&& g_AnimTablesByRace[race][index].injuryanims
|
|
&& g_AnimTablesByRace[race][index].injuryanimcount > 0) {
|
|
// If shot in a hand that's holding a gun, remap the hit location to the
|
|
// forearm because the hand injury animations assume the hand is empty.
|
|
struct prop *lgun = chrGetHeldProp(chr, HAND_LEFT);
|
|
struct prop *rgun = chrGetHeldProp(chr, HAND_RIGHT);
|
|
s32 rowindex;
|
|
struct animtablerow *row;
|
|
|
|
if (race == RACE_HUMAN) {
|
|
if (index == 9 && lgun) { // left hand
|
|
index = 10; // left forearm
|
|
} else if (index == 12 && rgun) { // right hand
|
|
index = 13; // right forearm
|
|
}
|
|
}
|
|
|
|
// Select a random animation for this hit location and apply it
|
|
rowindex = random() % g_AnimTablesByRace[race][index].injuryanimcount;
|
|
|
|
row = &g_AnimTablesByRace[race][index].injuryanims[rowindex];
|
|
|
|
chrStopFiring(chr);
|
|
|
|
chr->actiontype = ACT_ARGH;
|
|
chr->act_argh.notifychrindex = 0;
|
|
chr->act_argh.lvframe60 = g_Vars.lvframe60;
|
|
chr->sleep = 0;
|
|
|
|
modelSetAnimationWithMerge(model, row->animnum, row->flip, 0, row->speed, 16, !instant);
|
|
|
|
if (row->endframe >= 0) {
|
|
modelSetAnimEndFrame(model, chrGetRangedArghSpeed(chr, row->endframe, 8));
|
|
} else {
|
|
modelSetAnimEndFrame(model, chrGetRangedArghSpeed(chr, animGetNumFrames(row->animnum) - 1, 8));
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrReactToDamage(struct chrdata *chr, struct coord *vector, f32 angle, s32 hitpart, struct gset *gset, s32 aplayernum)
|
|
{
|
|
s32 race = CHRRACE(chr);
|
|
bool knockedout = false;
|
|
s32 animnum = modelGetAnimNum(chr->model);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (chr->actiontype == ACT_DRUGGEDKO)
|
|
#else
|
|
if (chr->actiontype == ACT_DRUGGEDCOMINGUP
|
|
|| chr->actiontype == ACT_DRUGGEDDROP
|
|
|| chr->actiontype == ACT_DRUGGEDKO)
|
|
#endif
|
|
{
|
|
knockedout = true;
|
|
}
|
|
|
|
if (race == RACE_EYESPY) {
|
|
f32 strength = gsetGetStrength(gset);
|
|
struct eyespy *eyespy = chrToEyespy(chr);
|
|
|
|
if (eyespy) {
|
|
if (strength <= 0) {
|
|
strength = 6;
|
|
}
|
|
|
|
strength *= 4;
|
|
|
|
eyespy->hit = EYESPYHIT_DAMAGE;
|
|
eyespy->vel.x += vector->x * strength;
|
|
eyespy->vel.z += vector->z * strength;
|
|
}
|
|
}
|
|
|
|
if (chr->damage >= chr->maxdamage) {
|
|
chrBeginDeath(chr, vector, angle, hitpart, gset, false, aplayernum);
|
|
} else if (animnum == ANIM_SNIPING_GETDOWN
|
|
|| animnum == ANIM_SNIPING_GETUP
|
|
|| animnum == ANIM_SNIPING_ONGROUND) {
|
|
chrFlinchBody(chr);
|
|
} else if (race == RACE_EYESPY) {
|
|
// empty
|
|
} else if (race == RACE_DRCAROLL || race == RACE_ROBOT) {
|
|
f32 strength = gsetGetStrength(gset);
|
|
|
|
if (race == RACE_DRCAROLL) {
|
|
strength *= 0.5f;
|
|
}
|
|
|
|
if (strength <= 0) {
|
|
strength = 6;
|
|
}
|
|
|
|
if (strength > 0) {
|
|
chr->elapseextra = 0;
|
|
chr->timeextra = strength * 15;
|
|
chr->extraspeed.x = vector->x * strength;
|
|
chr->extraspeed.y = vector->y * strength;
|
|
chr->extraspeed.z = vector->z * strength;
|
|
}
|
|
|
|
if (race == RACE_DRCAROLL) {
|
|
chrBeginArgh(chr, 0, 0);
|
|
}
|
|
} else if (!knockedout) {
|
|
chrBeginArgh(chr, angle, hitpart);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Launch a chr away from the given pos (for explosions).
|
|
*/
|
|
void chrYeetFromPos(struct chrdata *chr, struct coord *exppos, f32 force)
|
|
{
|
|
struct model *model = chr->model;
|
|
struct prop *prop = chr->prop;
|
|
f32 faceangle;
|
|
f32 latangle;
|
|
u32 stack1;
|
|
s32 angleindex;
|
|
u32 stack2;
|
|
struct yeetanim *row;
|
|
struct coord dist;
|
|
u32 stack3;
|
|
s32 race = CHRRACE(chr);
|
|
f32 speed;
|
|
s32 subindex;
|
|
f32 angletoexplosion;
|
|
|
|
if (race != RACE_DRCAROLL && race != RACE_EYESPY && race != RACE_ROBOT) {
|
|
faceangle = chrGetInverseTheta(chr);
|
|
latangle = atan2f(prop->pos.x - exppos->x, prop->pos.z - exppos->z);
|
|
|
|
dist.x = prop->pos.x - exppos->x;
|
|
dist.y = prop->pos.y - exppos->y;
|
|
dist.z = prop->pos.z - exppos->z;
|
|
|
|
if (dist.f[0] == 0 && dist.f[1] == 0 && dist.f[2] == 0) {
|
|
dist.z = 1;
|
|
}
|
|
|
|
speed = 0.625f * force / sqrtf(dist.f[0] * dist.f[0] + dist.f[1] * dist.f[1] + dist.f[2] * dist.f[2]);
|
|
angletoexplosion = latangle - faceangle;
|
|
|
|
dist.x *= speed;
|
|
dist.y *= speed;
|
|
dist.z *= speed;
|
|
|
|
chr->fallspeed.x = dist.x;
|
|
chr->fallspeed.y = dist.y;
|
|
chr->fallspeed.z = dist.z;
|
|
|
|
if (latangle < faceangle) {
|
|
angletoexplosion += M_BADTAU;
|
|
}
|
|
|
|
angleindex = angletoexplosion * 1.2734422683716f + 0.5f;
|
|
|
|
if (angleindex >= 8) {
|
|
angleindex = 0;
|
|
}
|
|
|
|
subindex = random() % g_YeetAnimIndexesByRaceAngle[race][angleindex].count;
|
|
|
|
if (race == RACE_HUMAN) {
|
|
row = &g_YeetAnimsHuman[g_YeetAnimIndexesByRaceAngle[race][angleindex].indexes[subindex]];
|
|
} else if (race == RACE_SKEDAR) {
|
|
row = &g_YeetAnimsSkedar[g_YeetAnimIndexesByRaceAngle[race][angleindex].indexes[subindex]];
|
|
}
|
|
|
|
chrStopFiring(chr);
|
|
chrUncloak(chr, true);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
chr->chrflags &= ~CHRCFLAG_HIDDEN;
|
|
#endif
|
|
|
|
chr->actiontype = ACT_DIE;
|
|
|
|
chr->act_die.notifychrindex = 0;
|
|
chr->act_die.thudframe1 = row->thudframe;
|
|
chr->act_die.thudframe2 = -1;
|
|
chr->act_die.timeextra = 0;
|
|
chr->act_die.drcarollimagedelay = TICKS(45);
|
|
|
|
if (chr->race == RACE_DRCAROLL) {
|
|
chr->drcarollimage_left = 1 + (s32)((random() % 400) * 0.01f);
|
|
chr->drcarollimage_right = 1 + (s32)((random() % 400) * 0.01f);
|
|
}
|
|
|
|
chr->sleep = 0;
|
|
modelSetAnimation(model, row->animnum, row->flip, row->startframe, row->speed, 8);
|
|
|
|
if (row->endframe >= 0.0f) {
|
|
modelSetAnimEndFrame(model, row->endframe);
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 gsetGetBlurAmount(struct gset *gset)
|
|
{
|
|
s32 amount = TICKS(1000);
|
|
|
|
if (g_Vars.normmplayerisrunning == false) {
|
|
amount = TICKS(250);
|
|
}
|
|
|
|
if (gset->weaponnum == WEAPON_TRANQUILIZER) {
|
|
amount = TICKS(2000);
|
|
}
|
|
|
|
if (gset->weaponnum == WEAPON_BOLT) {
|
|
amount = TICKS(5000);
|
|
}
|
|
|
|
if (gset->weaponnum == WEAPON_NBOMB) {
|
|
amount = TICKS(100);
|
|
}
|
|
|
|
return amount;
|
|
}
|
|
|
|
void chrKnockOut(struct chrdata *chr, f32 angle, s32 hitpart, struct gset *gset)
|
|
{
|
|
if (chr->actiontype != ACT_DRUGGEDCOMINGUP
|
|
&& chr->actiontype != ACT_DRUGGEDDROP
|
|
&& chr->actiontype != ACT_DRUGGEDKO) {
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
if (mpstatsGetTotalKnockoutCount() < 2) {
|
|
chr->chrflags |= CHRCFLAG_KEEPCORPSEKO;
|
|
|
|
if (mainGetStageNum() == STAGE_VILLA) {
|
|
chr->hidden |= CHRHFLAG_ANTINONINTERACTABLE;
|
|
}
|
|
}
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
if (mpstatsGetTotalKnockoutCount() < 2) {
|
|
chr->chrflags |= CHRCFLAG_KEEPCORPSEKO;
|
|
}
|
|
#endif
|
|
|
|
mpstatsIncrementTotalKnockoutCount();
|
|
|
|
chr->actiontype = ACT_DRUGGEDCOMINGUP;
|
|
chr->act_druggedcomingup.timer60 = 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return true if the chr's current animation would be too awkward to transition
|
|
* into an injury animation or if they're already in the PREARGH action state,
|
|
* and set dst to the anim frame number where the chr will become available for
|
|
* transition to an injury animation.
|
|
*
|
|
* The attack roll animation is the only one which is too awkward to transition.
|
|
*/
|
|
bool chrIsAnimPreventingArgh(struct chrdata *chr, f32 *dst)
|
|
{
|
|
bool result = false;
|
|
s32 race = CHRRACE(chr);
|
|
|
|
if (race == RACE_DRCAROLL || race == RACE_EYESPY || chr->aibot) {
|
|
return false;
|
|
}
|
|
|
|
if (race == RACE_HUMAN) {
|
|
s32 animnum = modelGetAnimNum(chr->model);
|
|
f32 endframe;
|
|
|
|
if (animnum == ANIM_SNIPING_GETDOWN
|
|
|| animnum == ANIM_SNIPING_GETUP
|
|
|| animnum == ANIM_SNIPING_ONGROUND) {
|
|
chrFlinchBody(chr);
|
|
} else if (chr->actiontype == ACT_ATTACKROLL
|
|
&& modelGetAnimNum(chr->model) == chr->act_attack.animcfg->animnum) {
|
|
if (chr->act_attack.onehanded) {
|
|
if (chr->act_attack.animcfg == &g_RollAttackAnims[4]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[5]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[6]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[7]) {
|
|
endframe = chr->act_attack.animcfg->unk04 - 8;
|
|
|
|
if (chr->act_attack.animcfg->unk14 < chr->act_attack.animcfg->unk04) {
|
|
endframe = chr->act_attack.animcfg->unk14;
|
|
}
|
|
|
|
if (endframe > modelGetCurAnimFrame(chr->model)) {
|
|
*dst = endframe;
|
|
result = true;
|
|
}
|
|
}
|
|
} else {
|
|
endframe = chr->act_attack.animcfg->unk04 - 8;
|
|
|
|
if (endframe > modelGetCurAnimFrame(chr->model)) {
|
|
*dst = endframe;
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (chr->actiontype == ACT_PREARGH) {
|
|
result = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void chrChoke(struct chrdata *chr, s32 choketype)
|
|
{
|
|
bool male = false;
|
|
s16 soundnum = -1;
|
|
s32 race = CHRRACE(chr);
|
|
s32 playernum;
|
|
s32 allowoverride = false;
|
|
|
|
static s32 nextindexdrcaroll = 0;
|
|
static s32 nextindexmaian = 0;
|
|
static s32 nextindexskedar = 0;
|
|
static s32 nextindexshock = 0;
|
|
static s32 nextindexmale = 0;
|
|
static s32 nextindexfemale = 0;
|
|
|
|
if (race == RACE_EYESPY || race == RACE_ROBOT) {
|
|
return;
|
|
}
|
|
|
|
if (chr->prop->type == PROPTYPE_PLAYER) {
|
|
playernum = playermgrGetPlayerNumByProp(chr->prop);
|
|
|
|
if (g_Vars.players[playernum]->isdead) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (g_HeadsAndBodies[chr->headnum].ismale) {
|
|
male = true;
|
|
}
|
|
|
|
if (race == RACE_DRCAROLL) {
|
|
s16 sounds[] = {
|
|
SFX_ARGH_DRCAROLL_0240,
|
|
SFX_ARGH_DRCAROLL_024C,
|
|
SFX_ARGH_DRCAROLL_0250,
|
|
SFX_ARGH_DRCAROLL_0251,
|
|
SFX_ARGH_DRCAROLL_0259,
|
|
SFX_ARGH_DRCAROLL_025A,
|
|
};
|
|
|
|
if (g_DrCarollDyingTimer > TICKS(10)) {
|
|
g_DrCarollDyingTimer = 0;
|
|
|
|
soundnum = sounds[nextindexdrcaroll];
|
|
nextindexdrcaroll++;
|
|
|
|
if (nextindexdrcaroll >= ARRAYCOUNT(sounds)) {
|
|
nextindexdrcaroll = 0;
|
|
}
|
|
}
|
|
} else if (chr->headnum == HEAD_THEKING
|
|
|| chr->headnum == HEAD_ELVIS
|
|
|| chr->headnum == HEAD_MAIAN_S
|
|
|| chr->headnum == HEAD_ELVIS_GOGS) {
|
|
s16 sounds[] = {
|
|
SFX_ARGH_MAIAN_05DF,
|
|
SFX_ARGH_MAIAN_05E0,
|
|
SFX_ARGH_MAIAN_05E1
|
|
};
|
|
|
|
soundnum = sounds[random() % 3];
|
|
nextindexmaian++;
|
|
|
|
if (nextindexmaian >= ARRAYCOUNT(sounds)) {
|
|
nextindexmaian = 0;
|
|
}
|
|
} else if (race == RACE_SKEDAR) {
|
|
if (chr->bodynum == BODY_MINISKEDAR) {
|
|
s16 sounds[] = {
|
|
SFX_SKEDAR_ROAR_0536,
|
|
SFX_SKEDAR_ROAR_0537,
|
|
SFX_SKEDAR_ROAR_0538,
|
|
SFX_SKEDAR_ROAR_0539,
|
|
SFX_SKEDAR_ROAR_053A,
|
|
};
|
|
|
|
soundnum = sounds[random() % 5];
|
|
nextindexskedar++;
|
|
|
|
if (nextindexskedar >= ARRAYCOUNT(sounds)) {
|
|
nextindexskedar = 0;
|
|
}
|
|
} else {
|
|
s16 sounds[] = {
|
|
SFX_SKEDAR_ROAR_052D,
|
|
SFX_SKEDAR_ROAR_052E,
|
|
SFX_SKEDAR_ROAR_052F,
|
|
};
|
|
|
|
soundnum = sounds[random() % 3];
|
|
nextindexskedar++;
|
|
|
|
if (nextindexskedar >= ARRAYCOUNT(sounds)) {
|
|
nextindexskedar = 0;
|
|
}
|
|
}
|
|
} else if (chr->headnum == HEAD_DDSHOCK) {
|
|
s16 sounds[] = {
|
|
SFX_ARGH_MALE_0086,
|
|
SFX_ARGH_MALE_0088,
|
|
SFX_ARGH_MALE_008A,
|
|
SFX_ARGH_MALE_008C,
|
|
SFX_ARGH_MALE_008E,
|
|
SFX_ARGH_MALE_0090,
|
|
SFX_ARGH_MALE_0092,
|
|
SFX_ARGH_MALE_0094,
|
|
SFX_ARGH_MALE_0096,
|
|
SFX_ARGH_MALE_0098,
|
|
SFX_ARGH_MALE_009A,
|
|
SFX_ARGH_MALE_009C,
|
|
SFX_ARGH_MALE_009E,
|
|
SFX_ARGH_MALE_0087,
|
|
};
|
|
|
|
soundnum = sounds[nextindexshock];
|
|
nextindexshock++;
|
|
|
|
if (nextindexshock >= ARRAYCOUNT(sounds)) {
|
|
nextindexshock = 0;
|
|
}
|
|
|
|
allowoverride = true;
|
|
} else if (male) {
|
|
s16 sounds[] = {
|
|
SFX_ARGH_MALE_0086,
|
|
SFX_ARGH_MALE_0087,
|
|
SFX_ARGH_MALE_0088,
|
|
SFX_ARGH_MALE_0089,
|
|
SFX_ARGH_MALE_008A,
|
|
SFX_ARGH_MALE_008B,
|
|
SFX_ARGH_MALE_008C,
|
|
SFX_ARGH_MALE_008D,
|
|
SFX_ARGH_MALE_008E,
|
|
SFX_ARGH_MALE_008F,
|
|
SFX_ARGH_MALE_0090,
|
|
SFX_ARGH_MALE_0091,
|
|
SFX_ARGH_MALE_0092,
|
|
SFX_ARGH_MALE_0093,
|
|
SFX_ARGH_MALE_0094,
|
|
SFX_ARGH_MALE_0095,
|
|
SFX_ARGH_MALE_0096,
|
|
SFX_ARGH_MALE_0097,
|
|
SFX_ARGH_MALE_0098,
|
|
SFX_ARGH_MALE_0099,
|
|
SFX_ARGH_MALE_009A,
|
|
SFX_ARGH_MALE_009B,
|
|
SFX_ARGH_MALE_009C,
|
|
SFX_ARGH_MALE_009D,
|
|
SFX_ARGH_MALE_009E,
|
|
};
|
|
|
|
soundnum = sounds[nextindexmale];
|
|
nextindexmale++;
|
|
|
|
allowoverride = true;
|
|
|
|
if (nextindexmale >= ARRAYCOUNT(sounds)) {
|
|
nextindexmale = 0;
|
|
}
|
|
} else if (chr->headnum == HEAD_DARK_COMBAT
|
|
|| chr->headnum == HEAD_DARK_FROCK
|
|
|| chr->headnum == HEAD_DARKAQUA
|
|
|| chr->headnum == HEAD_DARK_SNOW) {
|
|
s16 sounds[] = {
|
|
SFX_ARGH_JO_02AA,
|
|
SFX_ARGH_JO_02AB,
|
|
SFX_ARGH_JO_02AC,
|
|
SFX_ARGH_JO_02AD,
|
|
SFX_ARGH_JO_02AE,
|
|
SFX_ARGH_JO_02AF,
|
|
SFX_ARGH_JO_02B0,
|
|
SFX_ARGH_JO_02B1,
|
|
SFX_ARGH_JO_02B2,
|
|
SFX_ARGH_JO_02B3,
|
|
};
|
|
|
|
soundnum = sounds[random() % 10];
|
|
allowoverride = true;
|
|
} else {
|
|
s16 sounds[] = {
|
|
SFX_ARGH_FEMALE_000D,
|
|
SFX_ARGH_FEMALE_000E,
|
|
SFX_ARGH_FEMALE_000F,
|
|
};
|
|
|
|
soundnum = sounds[nextindexfemale];
|
|
nextindexfemale++;
|
|
|
|
if (nextindexfemale >= ARRAYCOUNT(sounds)) {
|
|
nextindexfemale = 0;
|
|
}
|
|
|
|
allowoverride = true;
|
|
}
|
|
|
|
if (allowoverride) {
|
|
if (choketype == CHOKETYPE_GURGLE) {
|
|
s32 sounds[] = {
|
|
SFX_M1_CHOKING,
|
|
SFX_GURGLE_05B1,
|
|
SFX_GURGLE_05B2,
|
|
};
|
|
|
|
if ((random() % 8) == 0) {
|
|
soundnum = sounds[random() % 3];
|
|
}
|
|
|
|
chr->soundgap = 10;
|
|
chr->soundtimer = 0;
|
|
} else if (choketype == CHOKETYPE_COUGH) {
|
|
if (male) {
|
|
if ((random() % 2) == 0) {
|
|
soundnum = SFX_COUGH_04AF;
|
|
} else {
|
|
soundnum = SFX_COUGH_04B0;
|
|
}
|
|
} else {
|
|
s32 index = random() % 4;
|
|
s32 sounds[] = {
|
|
SFX_COUGH_05AB,
|
|
SFX_COUGH_05AC,
|
|
SFX_COUGH_05AD,
|
|
SFX_COUGH_05AE,
|
|
};
|
|
|
|
soundnum = sounds[index];
|
|
}
|
|
|
|
chr->soundgap = 10;
|
|
chr->soundtimer = 0;
|
|
}
|
|
}
|
|
|
|
if (soundnum >= 0) {
|
|
if (chr->prop->type == PROPTYPE_PLAYER) {
|
|
if (g_Vars.players[playernum]->chokehandle == NULL) {
|
|
sndStart(var80095200, soundnum, &g_Vars.players[playernum]->chokehandle, -1, -1, -1, -1, -1);
|
|
}
|
|
} else {
|
|
func0f0926bc(chr->prop, 9, 0);
|
|
|
|
if (!func0f092610(chr->prop, 13)) {
|
|
propsnd0f0939f8(NULL, chr->prop, soundnum, -1,
|
|
-1, 0, 0, 13, NULL, -1, NULL, -1, -1, -1, -1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
f32 chrGetShield(struct chrdata *chr)
|
|
{
|
|
return chr->cshield;
|
|
}
|
|
|
|
void chrSetShield(struct chrdata *chr, f32 amount)
|
|
{
|
|
if (amount < 0) {
|
|
amount = 0;
|
|
}
|
|
|
|
chr->cshield = amount;
|
|
|
|
if ((chr->hidden & CHRHFLAG_INFINITESHIELD) && chr->cshield < 1) {
|
|
chr->cshield = 1;
|
|
}
|
|
|
|
if (chr->prop->type == PROPTYPE_PLAYER) {
|
|
s32 playernum = playermgrGetPlayerNumByProp(chr->prop);
|
|
|
|
if (playernum >= 0) {
|
|
s32 prevplayernum = g_Vars.currentplayernum;
|
|
setCurrentPlayerNum(playernum);
|
|
playerDisplayHealth();
|
|
g_Vars.currentplayerstats->armourcount += amount * 0.125f;
|
|
setCurrentPlayerNum(prevplayernum);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool func0f034080(struct chrdata *chr, struct modelnode *node, struct prop *prop, struct model *model, s32 side, s16 *arg5)
|
|
{
|
|
if (chrGetShield(chr) > 0) {
|
|
if (node && (node->type & 0xff) == MODELNODETYPE_BBOX) {
|
|
shieldhitCreate(chr->prop, chrGetShield(chr), prop, node, model, side, arg5);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Damage the chr, bypassing any shield.
|
|
*
|
|
* Used for knife poison, nbomb damage, Investigation radioactivity and Escape gas.
|
|
*/
|
|
void chrDamageByMisc(struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *prop)
|
|
{
|
|
chrDamage(chr, damage, vector, gset, prop, HITPART_GENERAL,
|
|
false, // damageshield
|
|
NULL, // prop2
|
|
NULL, // node
|
|
NULL, // model
|
|
-1, // side
|
|
NULL, // arg11
|
|
false, // explosion
|
|
NULL); // explosionpos
|
|
}
|
|
|
|
void chrDamageByLaser(struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *prop)
|
|
{
|
|
chrDamage(chr, damage, vector, gset, prop, HITPART_GENERAL,
|
|
true, // damageshield
|
|
chr->prop, // prop2
|
|
NULL, // node
|
|
NULL, // model
|
|
-1, // side
|
|
NULL, // arg11
|
|
false, // explosion
|
|
NULL); // explosionpos
|
|
}
|
|
|
|
void func0f0341dc(struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *prop, s32 hitpart, struct prop *prop2, struct modelnode *node, struct model *model, s32 side, s16 *arg10)
|
|
{
|
|
chrDamage(chr, damage, vector, gset, prop, hitpart,
|
|
true, // damageshield
|
|
prop2, // prop2
|
|
node, // node
|
|
model, // model
|
|
side, // side
|
|
arg10, // arg11
|
|
false, // explosion
|
|
NULL); // explosionpos
|
|
}
|
|
|
|
/**
|
|
* Unused, and same as chrDamageByImpact but sets hitpart to HITPART_GENERAL instead of argument.
|
|
*/
|
|
void func0f034248(struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *prop)
|
|
{
|
|
struct modelnode *node = NULL;
|
|
struct model *model = NULL;
|
|
s32 side = 0;
|
|
s32 hitpart = HITPART_GENERAL;
|
|
|
|
if (chrGetShield(chr) >= 0 && chr->model) {
|
|
chrCalculateShieldHit(chr, &chr->prop->pos, vector, &node, &hitpart, &model, &side);
|
|
}
|
|
|
|
chrDamage(chr, damage, vector, gset, prop, HITPART_GENERAL,
|
|
true, // damageshield
|
|
chr->prop, // prop2
|
|
node, // node
|
|
model, // model
|
|
side, // side
|
|
NULL, // arg11
|
|
false, // explosion
|
|
NULL); // explosionpos
|
|
}
|
|
|
|
/**
|
|
* Used for punching, but also used by AI commands to make chrs take damage.
|
|
*/
|
|
void chrDamageByImpact(struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset, struct prop *prop, s32 hitpart)
|
|
{
|
|
struct modelnode *node = NULL;
|
|
struct model *model = NULL;
|
|
s32 side = 0;
|
|
|
|
if (chrGetShield(chr) >= 0 && chr->model) {
|
|
chrCalculateShieldHit(chr, &chr->prop->pos, vector, &node, &hitpart, &model, &side);
|
|
}
|
|
|
|
chrDamage(chr, damage, vector, gset, prop, hitpart,
|
|
true, // damageshield
|
|
chr->prop, // prop2
|
|
node, // node
|
|
model, // model
|
|
side, // side
|
|
NULL, // arg11
|
|
false, // explosion
|
|
NULL); // explosionpos
|
|
}
|
|
|
|
void chrDamageByExplosion(struct chrdata *chr, f32 damage, struct coord *vector, struct prop *prop, struct coord *explosionpos)
|
|
{
|
|
chrDamage(chr, damage, vector, NULL, prop, HITPART_GENERAL,
|
|
true, // damageshield
|
|
chr->prop, // prop2
|
|
NULL, // node
|
|
NULL, // model
|
|
-1, // side
|
|
NULL, // arg11
|
|
true, // explosion
|
|
explosionpos);
|
|
}
|
|
|
|
void playerUpdateDamageStats(struct prop *attacker, struct prop *victim, f32 damage)
|
|
{
|
|
s32 playernum;
|
|
|
|
if (attacker && attacker->type == PROPTYPE_PLAYER) {
|
|
playernum = playermgrGetPlayerNumByProp(attacker);
|
|
|
|
if (playernum >= 0) {
|
|
g_Vars.playerstats[playernum].damtransmitted += damage;
|
|
}
|
|
}
|
|
|
|
if (victim && victim->type == PROPTYPE_PLAYER) {
|
|
playernum = playermgrGetPlayerNumByProp(victim);
|
|
|
|
if (playernum >= 0) {
|
|
g_Vars.playerstats[playernum].damreceived += damage;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Handle a chr being damaged.
|
|
*
|
|
* Calculates and damage based on many factors and applies it to the chr,
|
|
* killing them if needed.
|
|
*
|
|
* The chr can be a player, aibot or regular chr. The chr can also be of any
|
|
* race (human, Skedar, Dr Caroll, robot or eyespy).
|
|
*
|
|
* chr - the chr being damaged
|
|
* damage - the base amount of damage to deal, prior to scaling factors
|
|
* vector - position of the attacker?
|
|
* gset - gun settings struct
|
|
* aprop - the attacker's prop struct
|
|
* hitpart - "i've been hit" value, ie. the body part (see HITPART constants)
|
|
* damageshield - false if attack should bypass shield if any
|
|
* prop2 - ?
|
|
* node - if shielded, model node (of type bbox) which was hit
|
|
* model - if shielded, model of chr
|
|
* side - if shielded, side of the model node's bounding box which was hit (0-5)
|
|
* arg11 - ?
|
|
* explosion - true if damage is coming from an explosion
|
|
* explosionpos - position of said explosion
|
|
*/
|
|
void chrDamage(struct chrdata *chr, f32 damage, struct coord *vector, struct gset *gset,
|
|
struct prop *aprop, s32 hitpart, bool damageshield, struct prop *prop2,
|
|
struct modelnode *node, struct model *model, s32 side, s16 *arg11,
|
|
bool explosion, struct coord *explosionpos)
|
|
{
|
|
bool onehitko = false;
|
|
s32 race = CHRRACE(chr);
|
|
f32 shield;
|
|
bool makedizzy;
|
|
bool isclose;
|
|
struct prop *vprop = chr->prop;
|
|
f32 headshotdamagescale = 1;
|
|
bool usedshield = false;
|
|
bool showshield = false;
|
|
bool showdamage = false;
|
|
struct gset gset2 = {0};
|
|
f32 explosionforce = damage;
|
|
f32 healthscale = 1;
|
|
f32 armourscale = 1;
|
|
bool isfar = true;
|
|
bool forceapplydamage = false;
|
|
struct weaponfunc *func;
|
|
f32 amount;
|
|
bool canchoke = true;
|
|
s32 aplayernum = -1;
|
|
s32 choketype = CHOKETYPE_NONE;
|
|
|
|
if (hitpart == HITPART_HEAD) {
|
|
choketype = CHOKETYPE_GURGLE;
|
|
}
|
|
|
|
if (gset) {
|
|
if (gset->weaponnum == WEAPON_COMBATKNIFE) {
|
|
if (gset->weaponfunc == FUNC_2) {
|
|
canchoke = false;
|
|
}
|
|
|
|
if (gset->weaponfunc == FUNC_POISON) {
|
|
choketype = CHOKETYPE_COUGH;
|
|
}
|
|
} else if (gset->weaponnum == WEAPON_TRANQUILIZER) {
|
|
if (gset->weaponfunc == FUNC_SECONDARY) {
|
|
choketype = CHOKETYPE_GURGLE;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Don't damage if in CI training outside of training session
|
|
if (chr->prop == g_Vars.currentplayer->prop
|
|
&& g_Vars.currentplayer->training == false
|
|
&& mainGetStageNum() == STAGE_CITRAINING) {
|
|
return;
|
|
}
|
|
|
|
// Don't damage if attacker was anti and chr is non-interactable by anti
|
|
if (g_Vars.antiplayernum >= 0
|
|
&& aprop
|
|
&& aprop == g_Vars.anti->prop
|
|
&& (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE)) {
|
|
return;
|
|
}
|
|
|
|
// Don't damage if coop and friendly fire is off (human buddy)
|
|
if (g_Vars.coopplayernum >= 0
|
|
&& g_Vars.coopfriendlyfire == false
|
|
&& aprop
|
|
&& aprop != vprop
|
|
&& aprop->type == PROPTYPE_PLAYER
|
|
&& vprop->type == PROPTYPE_PLAYER) {
|
|
return;
|
|
}
|
|
|
|
// Don't damage if coop and friendly fire is off (AI buddy)
|
|
if (g_MissionConfig.iscoop
|
|
&& g_Vars.coopfriendlyfire == false
|
|
&& aprop
|
|
&& aprop != vprop
|
|
&& (aprop->type == PROPTYPE_PLAYER || aprop->type == PROPTYPE_CHR)
|
|
&& chr->team == TEAM_ALLY
|
|
&& aprop->chr->team == TEAM_ALLY) {
|
|
return;
|
|
}
|
|
|
|
// Don't allow coop AI to kill or destroy anything
|
|
// which anti wouldn't be able to
|
|
if (g_MissionConfig.iscoop
|
|
&& aprop
|
|
&& aprop != vprop
|
|
&& aprop->type == PROPTYPE_CHR
|
|
&& aprop->chr->team == TEAM_ALLY
|
|
&& (chr->hidden & CHRHFLAG_ANTINONINTERACTABLE)) {
|
|
return;
|
|
}
|
|
|
|
if (gset == NULL) {
|
|
gset = &gset2;
|
|
}
|
|
|
|
func = gsetGetWeaponFunction(gset);
|
|
isclose = func && (func->type & 0xff) == INVENTORYFUNCTYPE_CLOSE;
|
|
makedizzy = race != RACE_DRCAROLL && gsetHasFunctionFlags(gset, FUNCFLAG_MAKEDIZZY);
|
|
|
|
if (chr->prop == g_Vars.currentplayer->prop && g_Vars.currentplayer->invincible) {
|
|
return;
|
|
}
|
|
|
|
if (isclose) {
|
|
isfar = false;
|
|
}
|
|
|
|
// Set a flag on the victim that makes them switch to their "shot" AI list
|
|
chr->chrflags |= CHRCFLAG_TRIGGERSHOTLIST;
|
|
|
|
// Set a flag on the attacker so their AI scripting can tell that they've
|
|
// hit their target
|
|
if (aprop
|
|
&& aprop->type == PROPTYPE_CHR
|
|
&& chrGetTargetProp(aprop->chr) == chr->prop) {
|
|
aprop->chr->chrflags |= CHRCFLAG_INJUREDTARGET;
|
|
}
|
|
|
|
// Disarm only hurts the victim in solo missions and if the victim is an NPC
|
|
if (gsetHasFunctionFlags(gset, FUNCFLAG_DISARM)
|
|
&& gset->weaponnum == WEAPON_UNARMED
|
|
&& (vprop->type == PROPTYPE_PLAYER || g_Vars.normmplayerisrunning)) {
|
|
damage = 0;
|
|
}
|
|
|
|
// Apply damage scaling based on difficulty settings
|
|
if (g_Vars.mplayerisrunning == false) {
|
|
// Solo
|
|
if (explosion) {
|
|
if (vprop->type == PROPTYPE_PLAYER) {
|
|
damage *= g_ExplosionDamageTxScale;
|
|
}
|
|
} else if (aprop && aprop->type == PROPTYPE_PLAYER) {
|
|
// Player is attacking
|
|
damage *= g_PlayerDamageTxScale;
|
|
headshotdamagescale = 25;
|
|
} else if (aprop && aprop->type == PROPTYPE_CHR && vprop->type == PROPTYPE_PLAYER) {
|
|
// Chr is attacking player
|
|
damage *= g_PlayerDamageRxScale * pdmodeGetEnemyDamage();
|
|
}
|
|
|
|
if (vprop->type != PROPTYPE_PLAYER) {
|
|
damage /= pdmodeGetEnemyHealth();
|
|
}
|
|
|
|
if (vprop->type == PROPTYPE_PLAYER) {
|
|
healthscale = g_Vars.players[playermgrGetPlayerNumByProp(vprop)]->healthscale;
|
|
armourscale = g_Vars.players[playermgrGetPlayerNumByProp(vprop)]->armourscale;
|
|
}
|
|
} else if (g_Vars.coopplayernum >= 0) {
|
|
// Co-op
|
|
if (explosion) {
|
|
if (vprop->type == PROPTYPE_PLAYER) {
|
|
damage *= g_ExplosionDamageTxScale;
|
|
}
|
|
} else if (aprop && aprop->type == PROPTYPE_PLAYER && vprop->type != PROPTYPE_PLAYER) {
|
|
damage *= g_PlayerDamageTxScale;
|
|
headshotdamagescale = 25;
|
|
} else if (aprop && aprop->type == PROPTYPE_CHR && vprop->type == PROPTYPE_PLAYER) {
|
|
damage *= g_PlayerDamageRxScale * pdmodeGetEnemyDamage();
|
|
}
|
|
|
|
if (vprop->type != PROPTYPE_PLAYER) {
|
|
damage /= pdmodeGetEnemyHealth();
|
|
}
|
|
|
|
if (vprop->type == PROPTYPE_PLAYER) {
|
|
healthscale = g_Vars.players[playermgrGetPlayerNumByProp(vprop)]->healthscale;
|
|
armourscale = g_Vars.players[playermgrGetPlayerNumByProp(vprop)]->armourscale;
|
|
}
|
|
} else if (g_Vars.antiplayernum >= 0) {
|
|
// Anti
|
|
if (explosion) {
|
|
if (vprop == g_Vars.bond->prop) {
|
|
damage *= g_ExplosionDamageTxScale;
|
|
}
|
|
} else if (aprop && aprop == g_Vars.bond->prop) {
|
|
damage *= g_PlayerDamageTxScale;
|
|
headshotdamagescale = 25;
|
|
} else if (aprop && aprop != g_Vars.bond->prop && vprop == g_Vars.bond->prop) {
|
|
damage *= g_PlayerDamageRxScale * pdmodeGetEnemyDamage();
|
|
}
|
|
|
|
if (vprop != g_Vars.bond->prop) {
|
|
damage /= pdmodeGetEnemyHealth();
|
|
}
|
|
|
|
if (vprop == g_Vars.bond->prop) {
|
|
healthscale = g_Vars.players[playermgrGetPlayerNumByProp(vprop)]->healthscale;
|
|
armourscale = g_Vars.players[playermgrGetPlayerNumByProp(vprop)]->armourscale;
|
|
}
|
|
|
|
// Anti shooting other enemies is lethal
|
|
if (aprop && aprop == g_Vars.anti->prop && vprop != g_Vars.bond->prop) {
|
|
damage *= 100;
|
|
}
|
|
} else {
|
|
// Normal multiplayer
|
|
if (vprop->type == PROPTYPE_PLAYER) {
|
|
s32 prevplayernum = g_Vars.currentplayernum;
|
|
setCurrentPlayerNum(playermgrGetPlayerNumByProp(vprop));
|
|
damage *= g_Vars.currentplayerstats->damagescale;
|
|
setCurrentPlayerNum(prevplayernum);
|
|
}
|
|
}
|
|
|
|
// Apply rumble
|
|
if (vprop->type == PROPTYPE_PLAYER) {
|
|
s32 prevplayernum = g_Vars.currentplayernum;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
s32 contpad1;
|
|
s32 contpad2;
|
|
|
|
setCurrentPlayerNum(playermgrGetPlayerNumByProp(vprop));
|
|
|
|
joyGetContpadNumsForPlayer(g_Vars.currentplayernum, &contpad1, &contpad2);
|
|
|
|
if (contpad1 >= 0) {
|
|
pakRumble(contpad1, 0.25f, -1, -1);
|
|
}
|
|
|
|
if (contpad2 >= 0) {
|
|
pakRumble(contpad2, 0.25f, -1, -1);
|
|
}
|
|
#else
|
|
setCurrentPlayerNum(playermgrGetPlayerNumByProp(vprop));
|
|
|
|
pakRumble((s8)g_Vars.currentplayernum, 0.25f, -1, -1);
|
|
|
|
if (optionsGetControlMode(g_Vars.currentplayerstats->mpindex) >= CONTROLMODE_21) {
|
|
pakRumble((s8)(PLAYERCOUNT() + g_Vars.currentplayernum), 0.25f, -1, -1);
|
|
}
|
|
#endif
|
|
|
|
setCurrentPlayerNum(prevplayernum);
|
|
}
|
|
|
|
// Find the attacker's player number if possible
|
|
// (includes MP aibots, not applicable for solo chrs)
|
|
if (g_Vars.mplayerisrunning) {
|
|
if (aprop && (aprop->type == PROPTYPE_PLAYER || aprop->type == PROPTYPE_CHR)) {
|
|
aplayernum = mpPlayerGetIndex(aprop->chr);
|
|
}
|
|
} else {
|
|
if (aprop && aprop->type == PROPTYPE_PLAYER) {
|
|
aplayernum = playermgrGetPlayerNumByProp(aprop);
|
|
}
|
|
}
|
|
|
|
// If using the shotgun, scale the damage based on distance
|
|
if (aprop && aprop->type == PROPTYPE_CHR && gset->weaponnum == WEAPON_SHOTGUN) {
|
|
f32 xdiff = aprop->pos.x - vprop->pos.x;
|
|
f32 ydiff = aprop->pos.y - vprop->pos.y;
|
|
f32 zdiff = aprop->pos.z - vprop->pos.z;
|
|
f32 sqdist = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
|
|
|
|
if (sqdist < 200 * 200) {
|
|
damage *= 4.0f + (s32)(random() % 3); // 4, 5 or 6
|
|
} else if (sqdist < 400 * 400) {
|
|
damage *= 3.0f + (s32)(random() % 2); // 3 or 4
|
|
} else if (sqdist < 800 * 800) {
|
|
damage *= 2.0f + (s32)(random() % 2); // 2 or 3
|
|
} else if (sqdist < 1600 * 1600) {
|
|
damage *= 1.0f + (s32)(random() % 2); // 1 or 2
|
|
}
|
|
}
|
|
|
|
// damageshield is an argument to this function,
|
|
// but is forced on if using the Farsight.
|
|
if (gset && gset->weaponnum == WEAPON_FARSIGHT) {
|
|
damageshield = true;
|
|
damage *= 10;
|
|
}
|
|
|
|
// Handle shield damage
|
|
if (damageshield) {
|
|
shield = chrGetShield(chr);
|
|
|
|
if (chr->aibot && chr->aibot->config->type == BOTTYPE_TURTLE) {
|
|
armourscale = 4;
|
|
}
|
|
|
|
if (shield > 0) {
|
|
if (g_Vars.normmplayerisrunning) {
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
// Fixing a @bug?
|
|
damage = damage * mpHandicapToDamageScale(g_PlayerConfigsArray[g_Vars.currentplayerstats->mpindex].handicap);
|
|
#else
|
|
damage /= mpHandicapToDamageScale(g_PlayerConfigsArray[g_Vars.currentplayerstats->mpindex].handicap);
|
|
#endif
|
|
}
|
|
|
|
chr->chrflags |= CHRCFLAG_SHIELDDAMAGED;
|
|
|
|
if (prop2 && node && chr->model) {
|
|
func0f034080(chr, node, prop2, model, side, arg11);
|
|
} else {
|
|
shieldhitCreate(chr->prop, chrGetShield(chr), NULL, NULL, NULL, 0, 0);
|
|
}
|
|
|
|
if (g_Vars.normmplayerisrunning && (g_MpSetup.options & MPOPTION_ONEHITKILLS)) {
|
|
damage = 0;
|
|
chrSetShield(chr, 0);
|
|
} else if (shield >= damage / armourscale) {
|
|
// Has enough shield to sustain the damage
|
|
shield -= damage / armourscale;
|
|
damage = 0;
|
|
chrSetShield(chr, shield);
|
|
} else {
|
|
// Shield is now gone
|
|
damage = 0;
|
|
chrSetShield(chr, 0);
|
|
}
|
|
|
|
showshield = true;
|
|
usedshield = true;
|
|
}
|
|
}
|
|
|
|
// Handle hat shots. This is left over from GE, as hats don't exist in PD
|
|
if (damage > 0 && hitpart == HITPART_HAT && chr->weapons_held[2]) {
|
|
s32 type = hatGetType(chr->weapons_held[2]);
|
|
|
|
if (type == HATTYPE_CLOTH) {
|
|
// Hat remains on head and damages the chr (eg. Moonraker Elite)
|
|
hitpart = HITPART_HEAD;
|
|
} else if (type != HATTYPE_METAL) {
|
|
// Normal hat
|
|
damage = 0;
|
|
objSetDropped(chr->weapons_held[2], DROPTYPE_HAT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
} else {
|
|
// Metal helmets don't fall off and make a metallic chink noise when shot
|
|
u16 sounds[] = { SFX_HIT_METAL_807B, SFX_HIT_METAL_8079, SFX_HATHIT_807C };
|
|
damage = 0;
|
|
|
|
propsnd0f0939f8(NULL, chr->prop, sounds[random() % 3], -1,
|
|
-1, 0, 0, 0, NULL, -1, NULL, -1, -1, -1, -1);
|
|
}
|
|
}
|
|
|
|
// Handle incrementing player shot count
|
|
if (aprop && aprop->type == PROPTYPE_PLAYER && !explosion) {
|
|
bool alreadydead = false;
|
|
s32 prevplayernum = g_Vars.currentplayernum;
|
|
setCurrentPlayerNum(playermgrGetPlayerNumByProp(aprop));
|
|
|
|
// ACT_DIE is not checked here, so it would appear that shooting
|
|
// a chr as they're dying will increment the shots hit count
|
|
if (chr && chr->actiontype == ACT_DEAD) {
|
|
alreadydead = true;
|
|
}
|
|
|
|
if (vprop->type == PROPTYPE_PLAYER && g_Vars.players[playermgrGetPlayerNumByProp(vprop)]->isdead) {
|
|
alreadydead = true;
|
|
}
|
|
|
|
if (!alreadydead && hitpart) {
|
|
switch (hitpart) {
|
|
case HITPART_HEAD:
|
|
mpstatsIncrementPlayerShotCount2(gset, SHOTREGION_HEAD);
|
|
break;
|
|
case HITPART_GUN:
|
|
mpstatsIncrementPlayerShotCount2(gset, SHOTREGION_GUN);
|
|
break;
|
|
case HITPART_HAT:
|
|
mpstatsIncrementPlayerShotCount2(gset, SHOTREGION_HAT);
|
|
break;
|
|
case HITPART_PELVIS:
|
|
case HITPART_TORSO:
|
|
mpstatsIncrementPlayerShotCount2(gset, SHOTREGION_BODY);
|
|
break;
|
|
default:
|
|
mpstatsIncrementPlayerShotCount2(gset, SHOTREGION_LIMB);
|
|
break;
|
|
}
|
|
}
|
|
|
|
setCurrentPlayerNum(prevplayernum);
|
|
}
|
|
|
|
// If the chr is invincible, make them flinch then we're done
|
|
if (chr->chrflags & CHRCFLAG_INVINCIBLE) {
|
|
chrFlinchBody(chr);
|
|
return;
|
|
}
|
|
|
|
// If chr is dying or already dead, consider making their head flinch
|
|
// then we're done
|
|
if (chr->actiontype == ACT_DIE || chr->actiontype == ACT_DEAD) {
|
|
if (hitpart == HITPART_HEAD && chr->actiontype == ACT_DIE && race != RACE_SKEDAR && isfar) {
|
|
struct coord pos;
|
|
pos.x = vprop->pos.x - vector->x;
|
|
pos.y = vprop->pos.y - vector->y;
|
|
pos.z = vprop->pos.z - vector->z;
|
|
chrFlinchHead(chr, chrGetAngleToPos(chr, &pos));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// At this point the chr is known to be alive before they were shot
|
|
{
|
|
struct prop *weapon;
|
|
struct coord sp9c;
|
|
f32 angle;
|
|
|
|
sp9c.x = vprop->pos.x - vector->x;
|
|
sp9c.y = vprop->pos.y - vector->y;
|
|
sp9c.z = vprop->pos.z - vector->z;
|
|
angle = chrGetAngleToPos(chr, &sp9c);
|
|
|
|
// Knife in the back to an unalerted chr is lethal
|
|
if (gset->weaponnum == WEAPON_COMBATKNIFE
|
|
&& gset->weaponfunc == FUNC_PRIMARY
|
|
&& angle > 2.0940616130829f
|
|
&& angle < 4.1881237030029f
|
|
&& (chr->alertness < 100 || chr->lastseetarget60 == 0)) {
|
|
damage *= 1000;
|
|
}
|
|
|
|
// Punching and pistol whipping is less effective from the front
|
|
if (gsetHasFunctionFlags(gset, FUNCFLAG_BLUNTIMPACT)) {
|
|
if (angle < 1.0470308065414f || angle > 5.2351541519165f) {
|
|
damage *= 0.4f;
|
|
} else if (angle < 2.0940616130829f || angle > 4.1881237030029f) {
|
|
damage *= 0.7f;
|
|
} else if (chr->alertness < 100) {
|
|
onehitko = true;
|
|
}
|
|
|
|
if (chrGetHeldProp(chr, HAND_RIGHT) == NULL
|
|
&& chrGetHeldProp(chr, HAND_LEFT) == NULL
|
|
&& (chr->gunprop == NULL || chr->actiontype == ACT_SURRENDER || chr->actiontype == ACT_SURPRISED)) {
|
|
// Chr is unarmed and has no hope of getting their gun
|
|
onehitko = true;
|
|
}
|
|
|
|
forceapplydamage = true;
|
|
}
|
|
|
|
if (hitpart == HITPART_GENERAL) {
|
|
// Halve the damage because it's doubled for torso below
|
|
hitpart = HITPART_TORSO;
|
|
damage *= 0.5f;
|
|
} else if (hitpart == HITPART_GENERALHALF) {
|
|
// Likewise, quarter it here so it becomes half below
|
|
hitpart = HITPART_TORSO;
|
|
damage *= 0.25f;
|
|
}
|
|
|
|
// Hits to a Skedar's tail are 10x more lethal
|
|
if (race == RACE_SKEDAR && hitpart == HITPART_TAIL) {
|
|
damage *= 10;
|
|
}
|
|
|
|
// Apply damage multipliers based on which body parts were hit,
|
|
// and flinch head if shot in the head
|
|
if (hitpart == HITPART_HEAD) {
|
|
if (race == RACE_SKEDAR) {
|
|
damage += damage;
|
|
chrFlinchHead(chr, angle);
|
|
} else {
|
|
damage *= 4;
|
|
|
|
if (isfar && !usedshield) {
|
|
chrFlinchHead(chr, angle);
|
|
damage *= headshotdamagescale;
|
|
|
|
if (gset->weaponnum == WEAPON_COMBATKNIFE && gset->weaponfunc != FUNC_POISON) {
|
|
damage += damage;
|
|
}
|
|
}
|
|
}
|
|
} else if (hitpart == HITPART_TORSO) {
|
|
// Double damage for torso hits
|
|
damage += damage;
|
|
} else if (hitpart == HITPART_GUN) {
|
|
// No damage for gun hits
|
|
damage = 0;
|
|
makedizzy = false;
|
|
} else if (hitpart == HITPART_HAT) {
|
|
// No damage for hat hits
|
|
damage = 0;
|
|
makedizzy = false;
|
|
}
|
|
|
|
// Handle situations where the player is the one being shot, then return
|
|
if (vprop->type == PROPTYPE_PLAYER) {
|
|
s32 prevplayernum = g_Vars.currentplayernum;
|
|
setCurrentPlayerNum(playermgrGetPlayerNumByProp(vprop));
|
|
|
|
if (g_Vars.normmplayerisrunning) {
|
|
damage /= mpHandicapToDamageScale(g_PlayerConfigsArray[g_Vars.currentplayerstats->mpindex].handicap);
|
|
}
|
|
|
|
if (g_Vars.currentplayer->isdead == false && !g_PlayerInvincible) {
|
|
f32 boostscale;
|
|
|
|
// Handle player losing gun
|
|
if (gsetHasFunctionFlags(gset, FUNCFLAG_DISARM)) {
|
|
bgunDisarm(aprop);
|
|
}
|
|
|
|
// Handle player dizziness
|
|
if (makedizzy && g_Vars.currentplayer->invincible == false) {
|
|
f32 blurscale = 1;
|
|
struct chrdata *achr = NULL;
|
|
|
|
if (aprop) {
|
|
achr = aprop->chr;
|
|
|
|
if (achr && achr->bodynum == BODY_MINISKEDAR) {
|
|
blurscale = 4;
|
|
}
|
|
}
|
|
|
|
if (!achr
|
|
|| !achr->aibot
|
|
|| !gsetHasFunctionFlags(gset, FUNCFLAG_00400000)
|
|
|| chr->blurdrugamount < TICKS(4500)) {
|
|
chr->blurdrugamount += gsetGetBlurAmount(gset) * blurscale;
|
|
}
|
|
|
|
chr->blurnumtimesdied = 0;
|
|
}
|
|
|
|
// Handle player damage
|
|
if (g_Vars.currentplayer->invincible == false && damage > 0) {
|
|
f32 statsamount = amount = damage * 0.125f;
|
|
|
|
if (statsamount > g_Vars.currentplayer->bondhealth) {
|
|
statsamount = g_Vars.currentplayer->bondhealth;
|
|
}
|
|
|
|
if (g_Vars.normmplayerisrunning && (g_MpSetup.options & MPOPTION_ONEHITKILLS)) {
|
|
statsamount = g_Vars.currentplayer->bondhealth;
|
|
}
|
|
|
|
playerUpdateDamageStats(aprop, vprop, statsamount);
|
|
playerDisplayHealth();
|
|
|
|
if (g_Vars.normmplayerisrunning && (g_MpSetup.options & MPOPTION_ONEHITKILLS)) {
|
|
g_Vars.currentplayer->bondhealth = 0;
|
|
}
|
|
|
|
g_Vars.currentplayer->bondhealth -= amount / healthscale;
|
|
|
|
chr->lastattacker = (aprop ? aprop->chr : NULL);
|
|
|
|
showdamage = true;
|
|
|
|
if (g_Vars.currentplayer->training == false
|
|
&& g_Vars.currentplayer->bondhealth <= 0) {
|
|
playerDieByShooter(aplayernum, false);
|
|
chr->blurnumtimesdied++;
|
|
}
|
|
|
|
if (!lvIsPaused() && canchoke) {
|
|
chrChoke(chr, choketype);
|
|
}
|
|
|
|
chrFlinchBody(chr);
|
|
}
|
|
|
|
// Handle player boost
|
|
if (isclose && gset->weaponnum == WEAPON_REAPER) {
|
|
boostscale = 0.1f;
|
|
} else if (g_Vars.normmplayerisrunning) {
|
|
boostscale = 0.75f;
|
|
} else {
|
|
boostscale = 1;
|
|
}
|
|
|
|
g_Vars.currentplayer->bondshotspeed.x += vector->x * boostscale;
|
|
g_Vars.currentplayer->bondshotspeed.z += vector->z * boostscale;
|
|
|
|
if (showdamage) {
|
|
playerDisplayDamage();
|
|
}
|
|
|
|
if (showshield) {
|
|
playerDisplayShield();
|
|
}
|
|
|
|
if (g_Vars.normmplayerisrunning && aprop && aprop->type == PROPTYPE_PLAYER) {
|
|
playerCheckIfShotInBack(prevplayernum, vector->x, vector->z);
|
|
}
|
|
}
|
|
|
|
setCurrentPlayerNum(prevplayernum);
|
|
return;
|
|
}
|
|
|
|
// This check is pointless - a similar check and return exists earlier
|
|
if (chr->actiontype == ACT_DIE || chr->actiontype == ACT_DEAD) {
|
|
return;
|
|
}
|
|
|
|
// At this point we know we're dealing with a NPC being shot, and the
|
|
// NPC was alive prior to being shot.
|
|
|
|
// Handle aibot/chr losing gun
|
|
if (gsetHasFunctionFlags(gset, FUNCFLAG_DISARM)
|
|
&& ((chr->flags & CHRFLAG0_CANLOSEGUN) || chr->aibot)) {
|
|
if (chr->aibot) {
|
|
botDisarm(chr, aprop);
|
|
} else {
|
|
weapon = chrGetHeldProp(chr, HAND_RIGHT);
|
|
|
|
if (weapon) {
|
|
chr->gunprop = weapon;
|
|
objSetDropped(weapon, DROPTYPE_DEFAULT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
}
|
|
|
|
weapon = chrGetHeldProp(chr, HAND_LEFT);
|
|
|
|
if (weapon) {
|
|
chr->gunprop = weapon;
|
|
objSetDropped(weapon, DROPTYPE_DEFAULT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle chr damage
|
|
if (chr->damage < chr->maxdamage
|
|
|| (!g_Vars.normmplayerisrunning && chr->actiontype != ACT_PREARGH)) {
|
|
f32 sp80 = 0;
|
|
|
|
chr->numarghs++;
|
|
|
|
// Handle chr dizziness and psychosis
|
|
if (makedizzy && race != RACE_DRCAROLL && race != RACE_ROBOT) {
|
|
if (gsetHasFunctionFlags(gset, FUNCFLAG_PSYCHOSIS)) {
|
|
chr->hidden |= CHRHFLAG_PSYCHOSISED;
|
|
} else {
|
|
chr->blurdrugamount += gsetGetBlurAmount(gset);
|
|
chr->blurnumtimesdied = 0;
|
|
|
|
if (!chr->aibot && chr->blurdrugamount >= TICKS(5000)) {
|
|
onehitko = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle chr boost
|
|
if (chr->aibot) {
|
|
f32 boostscale;
|
|
|
|
if (isclose && gset->weaponnum == WEAPON_REAPER) {
|
|
boostscale = 0.1f;
|
|
} else {
|
|
boostscale = 0.75f;
|
|
}
|
|
|
|
chr->aibot->shotspeed.x += vector->x * boostscale;
|
|
chr->aibot->shotspeed.z += vector->z * boostscale;
|
|
}
|
|
|
|
if (gset->weaponnum == WEAPON_UNARMED) {
|
|
sp80 = 2;
|
|
}
|
|
|
|
if (gset->weaponnum == WEAPON_TRANQUILIZER || gset->weaponnum == WEAPON_PSYCHOSISGUN) {
|
|
forceapplydamage = true;
|
|
}
|
|
|
|
// Handle one-hit knockouts
|
|
if (onehitko && chr->aibot == NULL && race == RACE_HUMAN) {
|
|
chrKnockOut(chr, angle, hitpart, gset);
|
|
func0f0926bc(chr->prop, 9, 0);
|
|
|
|
if (canchoke) {
|
|
chrChoke(chr, choketype);
|
|
}
|
|
|
|
if (gset->weaponnum == WEAPON_UNARMED && chr->actiontype != ACT_DRUGGEDKO) {
|
|
return;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Handle applying damage to NPCs
|
|
// Don't enter this branch if there is no damage to give,
|
|
// or we are making a chr dizzy in solo mode (unless force is set)
|
|
if (damage > 0 && (g_Vars.normmplayerisrunning || !makedizzy || forceapplydamage)) {
|
|
f32 amount = damage;
|
|
|
|
if (chr->damage + damage > chr->maxdamage) {
|
|
amount = chr->maxdamage - chr->damage;
|
|
}
|
|
|
|
amount *= 0.125f;
|
|
|
|
playerUpdateDamageStats(aprop, vprop, amount);
|
|
|
|
chr->damage += damage;
|
|
chr->lastattacker = (aprop ? aprop->chr : NULL);
|
|
chr->chrflags |= CHRCFLAG_JUST_INJURED;
|
|
|
|
if (chr->aibot) {
|
|
if (g_Vars.normmplayerisrunning && (g_MpSetup.options & MPOPTION_ONEHITKILLS)) {
|
|
chr->damage = chr->maxdamage;
|
|
}
|
|
|
|
if (canchoke) {
|
|
chrChoke(chr, choketype);
|
|
}
|
|
|
|
chrFlinchBody(chr);
|
|
|
|
if (chr->damage >= chr->maxdamage) {
|
|
chrDie(chr, aplayernum);
|
|
}
|
|
} else if (explosion) {
|
|
// Chrs die instantly from explosion damage provided they
|
|
// don't have any armour (the chr has armour if their
|
|
// chr->damage is negative). Note that damage has already
|
|
// been applied to the chr above, so a perfectly healthy chr
|
|
// with no armour will already have a damage value > 0 at
|
|
// this point.
|
|
if (chr->damage > 0) {
|
|
chr->damage = chr->maxdamage;
|
|
|
|
if (race == RACE_DRCAROLL || race == RACE_EYESPY || race == RACE_ROBOT) {
|
|
chrBeginDeath(chr, vector, angle, hitpart, gset, false, aplayernum);
|
|
} else {
|
|
chrYeetFromPos(chr, explosionpos, explosionforce);
|
|
}
|
|
|
|
if (canchoke) {
|
|
chrChoke(chr, choketype);
|
|
}
|
|
|
|
if (g_Vars.mplayerisrunning) {
|
|
mpstatsRecordDeath(aplayernum, mpPlayerGetIndex(chr));
|
|
} else if (aprop && aprop->type == PROPTYPE_PLAYER) {
|
|
s32 prevplayernum = g_Vars.currentplayernum;
|
|
setCurrentPlayerNum(playermgrGetPlayerNumByProp(aprop));
|
|
mpstatsRecordPlayerKill();
|
|
setCurrentPlayerNum(prevplayernum);
|
|
}
|
|
|
|
if (chr->chrflags & CHRCFLAG_KILLCOUNTABLE) {
|
|
mpstatsIncrementTotalKillCount();
|
|
}
|
|
|
|
if (chr->aibot == NULL) {
|
|
chrDropConcealedItems(chr);
|
|
}
|
|
|
|
if (chr->aibot == NULL) {
|
|
weapon = chr->weapons_held[HAND_RIGHT];
|
|
|
|
if (weapon && (weapon->obj->flags & OBJFLAG_AIUNDROPPABLE) == 0) {
|
|
objSetDropped(weapon, DROPTYPE_DEFAULT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
}
|
|
|
|
weapon = chr->weapons_held[HAND_LEFT];
|
|
|
|
if (weapon && (weapon->obj->flags & OBJFLAG_AIUNDROPPABLE) == 0) {
|
|
objSetDropped(weapon, DROPTYPE_DEFAULT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// Non-explosion damage to solo mode chr
|
|
if (chr->actiontype != ACT_DRUGGEDKO && canchoke) {
|
|
chrChoke(chr, choketype);
|
|
}
|
|
|
|
if (makedizzy && chr->damage >= chr->maxdamage) {
|
|
chr->damage = chr->maxdamage - 0.1f;
|
|
chrKnockOut(chr, angle, hitpart, gset);
|
|
}
|
|
|
|
// If chr has armour or the weapon doesn't stun
|
|
if (chr->damage < 0 ||
|
|
(gsetHasFunctionFlags(gset, FUNCFLAG_NOSTUN) && chr->damage < chr->maxdamage)) {
|
|
f32 endframe = -1;
|
|
|
|
if (!chrIsAnimPreventingArgh(chr, &endframe)) {
|
|
chrFlinchBody(chr);
|
|
}
|
|
} else if (hitpart != HITPART_HAT) {
|
|
// Cancel current animation and prepare for argh
|
|
f32 endframe = -1;
|
|
|
|
if (chrIsAnimPreventingArgh(chr, &endframe)) {
|
|
if (endframe >= 0) {
|
|
modelSetAnimEndFrame(chr->model, endframe);
|
|
}
|
|
|
|
chr->actiontype = ACT_PREARGH;
|
|
chr->act_preargh.dir.x = vector->x;
|
|
chr->act_preargh.dir.y = vector->y;
|
|
chr->act_preargh.dir.z = vector->z;
|
|
chr->act_preargh.relshotdir = angle;
|
|
chr->act_preargh.hitpart = hitpart;
|
|
chr->act_preargh.aplayernum = aplayernum;
|
|
chr->act_preargh.gset.weaponnum = gset->weaponnum;
|
|
chr->act_preargh.gset.unk0639 = gset->unk0639;
|
|
chr->act_preargh.gset.unk063a = gset->unk063a;
|
|
chr->act_preargh.gset.weaponfunc = gset->weaponfunc;
|
|
|
|
chr->sleep = 0;
|
|
} else {
|
|
chrReactToDamage(chr, vector, angle, hitpart, gset, aplayernum);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sp80 > 0) {
|
|
chr->timeextra = sp80 * 15;
|
|
chr->elapseextra = 0;
|
|
|
|
chr->extraspeed.x = prop2->pos.x - aprop->pos.x;
|
|
chr->extraspeed.y = prop2->pos.y - aprop->pos.y;
|
|
chr->extraspeed.z = prop2->pos.z - aprop->pos.z;
|
|
|
|
guNormalize(&chr->extraspeed.x, &chr->extraspeed.y, &chr->extraspeed.z);
|
|
|
|
chr->extraspeed.x *= sp80;
|
|
chr->extraspeed.y *= sp80;
|
|
chr->extraspeed.z *= sp80;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrDie(struct chrdata *chr, s32 aplayernum)
|
|
{
|
|
if (chr->actiontype != ACT_DIE) {
|
|
chrStopFiring(chr);
|
|
chrUncloak(chr, true);
|
|
|
|
chr->actiontype = ACT_DIE;
|
|
chr->act_die.notifychrindex = 0;
|
|
chr->sleep = 0;
|
|
chr->blurnumtimesdied++;
|
|
chr->act_die.thudframe1 = -1;
|
|
chr->act_die.thudframe2 = -1;
|
|
chr->act_die.timeextra = 0;
|
|
|
|
chr->ailist = ailistFindById(GAILIST_AIBOT_DEAD);
|
|
chr->aioffset = 0;
|
|
|
|
mpstatsRecordDeath(aplayernum, mpPlayerGetIndex(chr));
|
|
botinvDropAll(chr, chr->aibot->weaponnum);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
chr->aibot->hasbriefcase = false;
|
|
chr->aibot->hascase = false;
|
|
chr->aibot->unk04c_04 = false;
|
|
chr->aibot->unk04c_03 = false;
|
|
chr->aibot->hasuplink = false;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
bool func0f03645c(struct chrdata *chr, struct coord *arg1, s16 *arg2, struct coord *arg3, struct coord *arg4, s32 arg5)
|
|
{
|
|
bool result = false;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
u32 stack[3];
|
|
s16 sp32;
|
|
s16 sp30;
|
|
struct prop *prop = chr->prop;
|
|
|
|
chrGetBbox(prop, &radius, &ymax, &ymin);
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
if (cd0002d840(arg1, arg2, arg3, &sp30, arg5, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) {
|
|
if (cd0002d6ac(arg3, &sp30, arg4, arg5, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) {
|
|
result = true;
|
|
}
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool func0f03654c(struct chrdata *chr, struct coord *pos, s16 *rooms, struct coord *pos2, s16 *rooms2, struct coord *vector, f32 arg6, u32 types)
|
|
{
|
|
struct coord tmp;
|
|
f32 a;
|
|
f32 b;
|
|
struct prop *prop;
|
|
bool result = false;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
struct coord sp5c;
|
|
struct coord sp50;
|
|
s16 sp40[8];
|
|
f32 mult;
|
|
|
|
prop = chr->prop;
|
|
|
|
chrSetPerimEnabled(chr, false);
|
|
chrGetBbox(prop, &radius, &ymax, &ymin);
|
|
|
|
if ((rooms2 && cdTestAToB2(pos, rooms, pos2, rooms2, types, 1, ymax - prop->pos.y, ymin - prop->pos.y))
|
|
|| (rooms2 == NULL && cd0002d6ac(pos, rooms, pos2, types, 1, ymax - prop->pos.y, ymin - prop->pos.y))) {
|
|
if (vector == NULL) {
|
|
vector = &tmp;
|
|
|
|
tmp.x = pos2->x - pos->x;
|
|
tmp.y = 0;
|
|
tmp.z = pos2->z - pos->z;
|
|
|
|
if (tmp.f[0] == 0 && tmp.f[2] == 0) {
|
|
// @bug: Needs to call chrSetPerimEnabled(chr, true)
|
|
// before returning
|
|
return true;
|
|
}
|
|
|
|
mult = 1.0f / sqrtf(tmp.f[0] * tmp.f[0] + tmp.f[2] * tmp.f[2]);
|
|
tmp.x *= mult;
|
|
tmp.z *= mult;
|
|
}
|
|
|
|
a = vector->x * arg6;
|
|
b = vector->z * arg6;
|
|
|
|
sp5c.x = pos->x + b;
|
|
sp5c.y = pos->y;
|
|
sp5c.z = pos->z - a;
|
|
|
|
sp50.x = pos2->x + b;
|
|
sp50.y = pos2->y;
|
|
sp50.z = pos2->z - a;
|
|
|
|
if (cd0002d840(pos, rooms, &sp5c, sp40, types, 1, ymax - prop->pos.y, ymin - prop->pos.y)
|
|
&& cd0002d6ac(&sp5c, sp40, &sp50, types, 1, ymax - prop->pos.y, ymin - prop->pos.y)) {
|
|
sp5c.x = pos->x - b;
|
|
sp5c.y = pos->y;
|
|
sp5c.z = pos->z + a;
|
|
|
|
sp50.x = pos2->x - b;
|
|
sp50.y = pos2->y;
|
|
sp50.z = pos2->z + a;
|
|
|
|
if (cd0002d840(pos, rooms, &sp5c, sp40, types, 1, ymax - prop->pos.y, ymin - prop->pos.y)
|
|
&& cd0002d6ac(&sp5c, sp40, &sp50, types, 1, ymax - prop->pos.y, ymin - prop->pos.y)) {
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool propchrHasClearLineToPos(struct prop *prop, struct coord *dstpos, struct coord *vector)
|
|
{
|
|
return func0f03654c(prop->chr, &prop->pos, prop->rooms, dstpos, NULL, vector, prop->chr->radius * 1.2f, CDTYPE_ALL);
|
|
}
|
|
|
|
bool propchrHasClearLineInVector(struct prop *prop, struct coord *vector, f32 mult)
|
|
{
|
|
struct coord dstpos;
|
|
|
|
dstpos.x = vector->x * mult + prop->pos.x;
|
|
dstpos.y = prop->pos.y;
|
|
dstpos.z = vector->z * mult + prop->pos.z;
|
|
|
|
return propchrHasClearLineToPos(prop, &dstpos, vector);
|
|
}
|
|
|
|
bool func0f036974(struct prop *prop, struct coord *pos)
|
|
{
|
|
return func0f03654c(prop->chr, &prop->pos, prop->rooms, pos, NULL, NULL, prop->chr->radius * 1.2f, CDTYPE_ALL);
|
|
}
|
|
|
|
void chrGetSideVectorToTarget(struct chrdata *chr, bool side, struct coord *vector)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
|
|
vector->x = 0;
|
|
vector->y = 0;
|
|
vector->z = 1;
|
|
|
|
if (target) {
|
|
f32 x = target->pos.x - prop->pos.x;
|
|
f32 z = target->pos.z - prop->pos.z;
|
|
f32 distance = sqrtf(x * x + z * z);
|
|
|
|
if (distance > 0) {
|
|
x = x / distance;
|
|
z = z / distance;
|
|
|
|
if (side) {
|
|
vector->x = z;
|
|
vector->y = 0;
|
|
vector->z = -x;
|
|
} else {
|
|
vector->x = -z;
|
|
vector->y = 0;
|
|
vector->z = x;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool chrCanRollInDirection(struct chrdata *chr, bool side, f32 distance)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct coord vector;
|
|
struct coord dstpos;
|
|
|
|
chrGetSideVectorToTarget(chr, side, &vector);
|
|
|
|
dstpos.x = vector.x * distance + prop->pos.x;
|
|
dstpos.y = prop->pos.y;
|
|
dstpos.z = vector.z * distance + prop->pos.z;
|
|
|
|
return propchrHasClearLineToPos(prop, &dstpos, &vector);
|
|
}
|
|
|
|
void chrGetSideVector(struct chrdata *chr, bool side, struct coord *vector)
|
|
{
|
|
f32 angle = chrGetInverseTheta(chr);
|
|
|
|
if (side) {
|
|
vector->x = cosf(angle);
|
|
vector->y = 0;
|
|
vector->z = -sinf(angle);
|
|
} else {
|
|
vector->x = -cosf(angle);
|
|
vector->y = 0;
|
|
vector->z = sinf(angle);
|
|
}
|
|
}
|
|
|
|
bool chrCanJumpInDirection(struct chrdata *chr, bool side, f32 distance)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct coord vector;
|
|
struct coord dstpos;
|
|
|
|
chrGetSideVector(chr, side, &vector);
|
|
|
|
dstpos.x = vector.x * distance + prop->pos.x;
|
|
dstpos.y = prop->pos.y;
|
|
dstpos.z = vector.z * distance + prop->pos.z;
|
|
|
|
return propchrHasClearLineToPos(prop, &dstpos, &vector);
|
|
}
|
|
|
|
bool chrIsRoomOffScreen(struct chrdata *chr, struct coord *waypos, s16 *wayrooms)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
s16 sp7c[20];
|
|
u32 stack;
|
|
s32 i;
|
|
s16 sp64[8];
|
|
bool offscreen = true;
|
|
s16 sp50[8];
|
|
|
|
if ((chr->hidden & CHRHFLAG_CLOAKED) == 0 || USINGDEVICE(DEVICE_IRSCANNER)) {
|
|
func0f065dfc(&prop->pos, prop->rooms, waypos, sp64, sp7c, 20);
|
|
|
|
if (g_Vars.mplayerisrunning) {
|
|
for (i = 0; sp7c[i] != -1; i++) {
|
|
if (g_MpRoomVisibility[sp7c[i]] & 0x0f) {
|
|
offscreen = false;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
for (i = 0; sp7c[i] != -1; i++) {
|
|
if (g_Rooms[sp7c[i]].flags & ROOMFLAG_ONSCREEN) {
|
|
offscreen = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (offscreen) {
|
|
for (i = 0; i < PLAYERCOUNT(); i++) {
|
|
portal00018148(waypos, &g_Vars.players[i]->prop->pos, wayrooms, sp50, 0, 0);
|
|
|
|
if (arrayIntersects(g_Vars.players[i]->prop->rooms, sp50)) {
|
|
offscreen = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return offscreen;
|
|
}
|
|
|
|
void chrGoPosInitMagic(struct chrdata *chr, struct waydata *waydata, struct coord *padpos, struct coord *chrpos)
|
|
{
|
|
f32 xdiff1 = padpos->x - chr->prop->pos.x;
|
|
f32 zdiff1 = padpos->z - chr->prop->pos.z;
|
|
|
|
f32 angle = atan2f(xdiff1, zdiff1);
|
|
|
|
f32 xdiff2 = padpos->x - chrpos->x;
|
|
f32 zdiff2 = padpos->z - chrpos->z;
|
|
|
|
waydata->mode = WAYMODE_MAGIC;
|
|
|
|
waydata->magictotal = sqrtf(xdiff1 * xdiff1 + zdiff1 * zdiff1);
|
|
waydata->magicdone = waydata->magictotal - sqrtf(xdiff2 * xdiff2 + zdiff2 * zdiff2);
|
|
|
|
chrSetLookAngle(chr, angle);
|
|
}
|
|
|
|
void chrGoPosGetCurWaypointInfoWithFlags(struct chrdata *chr, struct coord *pos, s16 *rooms, u32 *flags)
|
|
{
|
|
struct waypoint *waypoint = chr->act_gopos.waypoints[chr->act_gopos.curindex];
|
|
struct pad pad;
|
|
|
|
if (waypoint) {
|
|
padUnpack(waypoint->padnum, PADFIELD_POS | PADFIELD_ROOM | PADFIELD_FLAGS, &pad);
|
|
|
|
pos->x = pad.pos.x;
|
|
pos->y = pad.pos.y;
|
|
pos->z = pad.pos.z;
|
|
|
|
rooms[0] = pad.room;
|
|
rooms[1] = -1;
|
|
|
|
if (flags) {
|
|
*flags = pad.flags;
|
|
}
|
|
} else {
|
|
pos->x = chr->act_gopos.endpos.x;
|
|
pos->y = chr->act_gopos.endpos.y;
|
|
pos->z = chr->act_gopos.endpos.z;
|
|
|
|
rooms[0] = chr->act_gopos.endrooms[0];
|
|
rooms[1] = -1;
|
|
|
|
if (flags) {
|
|
*flags = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrGoPosGetCurWaypointInfo(struct chrdata *chr, struct coord *pos, s16 *rooms)
|
|
{
|
|
chrGoPosGetCurWaypointInfoWithFlags(chr, pos, rooms, NULL);
|
|
}
|
|
|
|
f32 func0f0370a8(struct chrdata *chr)
|
|
{
|
|
f32 result;
|
|
|
|
if (chr->aibot) {
|
|
result = botCalculateMaxSpeed(chr);
|
|
} else {
|
|
s16 animnum = modelGetAnimNum(chr->model);
|
|
result = func0f02dff0(animnum) * (chr->model->scale * 9.999999f);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
s32 chrGoPosCalculateBaseTtl(struct chrdata *chr)
|
|
{
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
u32 stack;
|
|
struct coord pos;
|
|
s16 rooms[8];
|
|
f32 speed;
|
|
|
|
chrGoPosGetCurWaypointInfo(chr, &pos, rooms);
|
|
|
|
xdiff = pos.x - chr->prop->pos.x;
|
|
zdiff = pos.z - chr->prop->pos.z;
|
|
|
|
if (xdiff < 0) {
|
|
xdiff = -xdiff;
|
|
}
|
|
|
|
if (zdiff < 0) {
|
|
zdiff = -zdiff;
|
|
}
|
|
|
|
speed = func0f0370a8(chr);
|
|
|
|
if (chr->aibot == NULL) {
|
|
speed *= modelGetAbsAnimSpeed(chr->model);
|
|
}
|
|
|
|
if (speed < 0.001f) {
|
|
speed = 0.001f;
|
|
}
|
|
|
|
return (xdiff + zdiff) / speed;
|
|
}
|
|
|
|
void chrGoPosClearRestartTtl(struct chrdata *chr)
|
|
{
|
|
chr->act_gopos.restartttl = 0;
|
|
}
|
|
|
|
void chrGoPosConsiderRestart(struct chrdata *chr)
|
|
{
|
|
if (chr->act_gopos.waydata.mode != WAYMODE_MAGIC
|
|
&& chr->liftaction != LIFTACTION_WAITINGONLIFT
|
|
&& chr->liftaction != LIFTACTION_WAITINGFORLIFT) {
|
|
if (chr->act_gopos.restartttl == 0) {
|
|
#if PAL
|
|
s32 value = (chrGoPosCalculateBaseTtl(chr) * 100 + 15000) / 60;
|
|
#else
|
|
s32 value = chrGoPosCalculateBaseTtl(chr) * 2 + 300;
|
|
#endif
|
|
|
|
if (value > 0xffff) {
|
|
value = 0xffff;
|
|
}
|
|
|
|
chr->act_gopos.restartttl = value;
|
|
} else if (chr->act_gopos.restartttl <= (u16)g_Vars.lvupdate240_60) {
|
|
if (chr->aibot) {
|
|
botCheckFetch(chr);
|
|
} else {
|
|
chrGoToRoomPos(chr, &chr->act_gopos.endpos, chr->act_gopos.endrooms, chr->act_gopos.flags);
|
|
}
|
|
} else {
|
|
chr->act_gopos.restartttl -= (u16)g_Vars.lvupdate240_60;
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrGoPosInitExpensive(struct chrdata *chr)
|
|
{
|
|
struct coord pos;
|
|
s16 rooms[8];
|
|
|
|
chrGoPosGetCurWaypointInfo(chr, &pos, rooms);
|
|
|
|
chr->act_gopos.waydata.mode = WAYMODE_INIT;
|
|
chr->act_gopos.waydata.iter = 0;
|
|
chr->act_gopos.waydata.gotaimpos = false;
|
|
chr->act_gopos.waydata.aimpos.x = pos.x;
|
|
chr->act_gopos.waydata.aimpos.y = pos.y;
|
|
chr->act_gopos.waydata.aimpos.z = pos.z;
|
|
|
|
chrGoPosClearRestartTtl(chr);
|
|
}
|
|
|
|
/**
|
|
* Advance the chr's current waypoint index to the next one in the route.
|
|
*
|
|
* The waypoints array allows 6 waypoints and it's important that they have a
|
|
* couple loaded in front of their current one. So if the index is moving too
|
|
* far into the array, new pathfinding will be done and the array and index will
|
|
* be reset.
|
|
*/
|
|
void chrGoPosAdvanceWaypoint(struct chrdata *chr)
|
|
{
|
|
if (chr->act_gopos.curindex < 3) {
|
|
chr->act_gopos.curindex++;
|
|
} else {
|
|
struct waypoint *from = chr->act_gopos.waypoints[chr->act_gopos.curindex];
|
|
u32 hash;
|
|
chr->act_gopos.curindex = 1;
|
|
|
|
hash = (g_Vars.lvframe60 >> 9) * 0x80 + chr->chrnum * 8;
|
|
|
|
waypointSetHashThing(hash, hash);
|
|
waypointFindRoute(from, chr->act_gopos.target, chr->act_gopos.waypoints, MAX_CHRWAYPOINTS);
|
|
waypointSetHashThing(0, 0);
|
|
}
|
|
|
|
chrGoPosInitExpensive(chr);
|
|
}
|
|
|
|
/**
|
|
* Determines which step index the chr will be at given their current index, the
|
|
* number of steps to take and in which direction (forward or back).
|
|
*
|
|
* Returns the step index and populates *forward with true or false depending on
|
|
* whether the chr will be traversing the path in the forward direction at that
|
|
* point.
|
|
*/
|
|
s32 chrPatrolCalculateStep(struct chrdata *chr, bool *forward, s32 numsteps)
|
|
{
|
|
s32 nextstep = chr->act_patrol.nextstep;
|
|
bool isforward = *forward;
|
|
|
|
if (numsteps < 0) {
|
|
isforward = !isforward;
|
|
numsteps = -numsteps;
|
|
}
|
|
|
|
while (numsteps > 0) {
|
|
numsteps--;
|
|
|
|
if (isforward) {
|
|
nextstep++;
|
|
|
|
if (chr->act_patrol.path->pads[nextstep] < 0) {
|
|
// Reached the end of the list
|
|
if (chr->act_patrol.path->flags & PATHFLAG_CIRCULAR) {
|
|
nextstep = 0;
|
|
} else {
|
|
isforward = false;
|
|
nextstep -= 2;
|
|
|
|
if (nextstep < 0) {
|
|
nextstep = 0;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
nextstep--;
|
|
|
|
if (nextstep < 0) {
|
|
// Reached the start of the list
|
|
if (chr->act_patrol.path->flags & PATHFLAG_CIRCULAR) {
|
|
nextstep = chr->act_patrol.path->len - 1;
|
|
} else {
|
|
isforward = true;
|
|
nextstep = 1;
|
|
|
|
if (chr->act_patrol.path->len - 1 <= 0) {
|
|
nextstep = chr->act_patrol.path->len - 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
*forward = isforward;
|
|
|
|
return nextstep;
|
|
}
|
|
|
|
/**
|
|
* Determines which pad number the chr will be at given their current index and
|
|
* the number of steps to take.
|
|
*/
|
|
s16 chrPatrolCalculatePadNum(struct chrdata *chr, s32 numsteps)
|
|
{
|
|
s32 *padnumptr;
|
|
bool forward = chr->act_patrol.forward;
|
|
s32 step = chrPatrolCalculateStep(chr, &forward, numsteps);
|
|
padnumptr = &chr->act_patrol.path->pads[step];
|
|
|
|
return *padnumptr;
|
|
}
|
|
|
|
void chrPatrolGetCurWaypointInfoWithFlags(struct chrdata *chr, struct coord *pos, s16 *rooms, u32 *flags)
|
|
{
|
|
s32 padnum = chrPatrolCalculatePadNum(chr, 0);
|
|
struct pad pad;
|
|
|
|
padUnpack(padnum, PADFIELD_POS | PADFIELD_ROOM | PADFIELD_FLAGS, &pad);
|
|
|
|
pos->x = pad.pos.x;
|
|
pos->y = pad.pos.y;
|
|
pos->z = pad.pos.z;
|
|
|
|
rooms[0] = pad.room;
|
|
rooms[1] = -1;
|
|
|
|
if (flags) {
|
|
*flags = pad.flags;
|
|
}
|
|
}
|
|
|
|
void chrPatrolGetCurWaypointInfo(struct chrdata *chr, struct coord *pos, s16 *rooms)
|
|
{
|
|
chrPatrolGetCurWaypointInfoWithFlags(chr, pos, rooms, NULL);
|
|
}
|
|
|
|
void func0f037580(struct chrdata *chr)
|
|
{
|
|
s16 rooms[8];
|
|
|
|
chr->act_patrol.waydata.mode = WAYMODE_INIT;
|
|
chr->act_patrol.waydata.iter = 0;
|
|
chr->act_patrol.waydata.gotaimpos = false;
|
|
|
|
chrPatrolGetCurWaypointInfo(chr, &chr->act_patrol.waydata.aimpos, rooms);
|
|
}
|
|
|
|
void func0f0375b0(struct chrdata *chr)
|
|
{
|
|
s32 nextstep = chrPatrolCalculateStep(chr, &chr->act_patrol.forward, 1);
|
|
|
|
chr->act_patrol.nextstep = nextstep;
|
|
chr->patrolnextstep = nextstep;
|
|
|
|
func0f037580(chr);
|
|
}
|
|
|
|
void chrNavTickMagic(struct chrdata *chr, struct waydata *waydata, f32 speed, struct coord *arg3, s16 *rooms)
|
|
{
|
|
s16 sp118[8];
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
f32 ground;
|
|
u16 floorcol;
|
|
u8 floortype;
|
|
s16 floorroom;
|
|
struct coord spf4;
|
|
struct prop *prop = chr->prop;
|
|
union modelrwdata *rwdata;
|
|
struct waypoint *waypoint;
|
|
struct coord spdc;
|
|
s16 spcc[8];
|
|
u32 stack[4];
|
|
struct pad pad;
|
|
struct coord sp5c;
|
|
s16 sp4c[8];
|
|
|
|
chr->invalidmove = 0;
|
|
chr->lastmoveok60 = g_Vars.lvframe60;
|
|
|
|
waydata->magicdone += speed * modelGetAbsAnimSpeed(chr->model) * g_Vars.lvupdate240freal;
|
|
|
|
if (waydata->magicdone >= waydata->magictotal) {
|
|
// Reached end of segment
|
|
chrSetPerimEnabled(chr, false);
|
|
roomsCopy(rooms, sp118);
|
|
chr0f021fa8(chr, arg3, sp118);
|
|
|
|
ground = cdFindGroundY(arg3, chr->radius, sp118, &floorcol, &floortype, 0, &floorroom, NULL, NULL);
|
|
|
|
spf4.x = arg3->x;
|
|
spf4.y = prop->pos.y - chr->ground + ground;
|
|
spf4.z = arg3->z;
|
|
|
|
roomsCopy(rooms, sp118);
|
|
chr0f021fa8(chr, &spf4, sp118);
|
|
chrGetBbox(chr->prop, &radius, &ymax, &ymin);
|
|
|
|
if (cdTestVolume(&spf4, chr->radius, sp118, CDTYPE_ALL, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) {
|
|
// Reached end of segment with no collision
|
|
prop->pos.x = spf4.x;
|
|
prop->pos.y = spf4.y;
|
|
prop->pos.z = spf4.z;
|
|
|
|
chr->ground = ground;
|
|
chr->manground = ground;
|
|
chr->sumground = ground * (PAL ? 8.4175090789795f : 9.999998f);
|
|
|
|
chr->floorcol = floorcol;
|
|
chr->floortype = floortype;
|
|
chr->floorroom = floorroom;
|
|
|
|
propDeregisterRooms(prop);
|
|
roomsCopy(sp118, prop->rooms);
|
|
propRegisterRooms(prop);
|
|
|
|
modelSetRootPosition(chr->model, &prop->pos);
|
|
|
|
rwdata = modelGetNodeRwData(chr->model, chr->model->filedata->rootnode);
|
|
rwdata->chrinfo.ground = ground;
|
|
|
|
chr->chrflags |= CHRCFLAG_00000001;
|
|
|
|
if (chr->actiontype == ACT_PATROL) {
|
|
func0f0375b0(chr);
|
|
chrPatrolGetCurWaypointInfo(chr, &spdc, spcc);
|
|
chrGoPosInitMagic(chr, waydata, &spdc, &prop->pos);
|
|
} else if (chr->actiontype == ACT_GOPOS) {
|
|
if (chr->act_gopos.waypoints[chr->act_gopos.curindex] == NULL) {
|
|
// Reached the end of the route
|
|
if (chr->act_gopos.flags & GOPOSFLAG_FORPATHSTART) {
|
|
chrTryStartPatrol(chr);
|
|
} else {
|
|
if (chr->act_gopos.curindex >= 2) {
|
|
waypoint = chr->act_gopos.waypoints[chr->act_gopos.curindex - 2];
|
|
padUnpack(waypoint->padnum, PADFIELD_POS, &pad);
|
|
chrSetLookAngle(chr, atan2f(prop->pos.x - pad.pos.x, prop->pos.z - pad.pos.z));
|
|
}
|
|
|
|
if (CHRRACE(chr) == RACE_HUMAN || CHRRACE(chr) == RACE_SKEDAR) {
|
|
chrStop(chr);
|
|
}
|
|
}
|
|
} else {
|
|
// Advance to next segment, still using magic
|
|
chrGoPosAdvanceWaypoint(chr);
|
|
chrGoPosGetCurWaypointInfo(chr, &sp5c, sp4c);
|
|
chrGoPosInitMagic(chr, waydata, &sp5c, &prop->pos);
|
|
}
|
|
}
|
|
} else {
|
|
// Collision
|
|
waydata->magicdone = waydata->magictotal;
|
|
|
|
if (chr->actiontype == ACT_PATROL) {
|
|
chr->act_patrol.waydata.lastvisible60 = g_Vars.lvframe60;
|
|
func0f037580(chr);
|
|
} else {
|
|
chr->act_gopos.waydata.lastvisible60 = g_Vars.lvframe60;
|
|
chrGoPosInitExpensive(chr);
|
|
}
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculate the chr's position when using the magic method of navigating.
|
|
*
|
|
* The magic method is used when the chr is off-screen. It measures the distance
|
|
* between two consecutive pads in the route and simply increments a distance
|
|
* value along that segment on each tick, ignoring collisions. Meanwhile, the
|
|
* chr's prop->pos is left as the original location where this segment started.
|
|
*
|
|
* The calculation is finding the fraction of the distance travelled in this
|
|
* segment, then finding the position between the starting pos and the pad's
|
|
* pos.
|
|
*
|
|
* The pos variable is used for both loading the next pad's position and for
|
|
* returning the new position, which means there's less stack usage.
|
|
*/
|
|
void chrCalculatePosition(struct chrdata *chr, struct coord *pos)
|
|
{
|
|
s16 rooms[8];
|
|
f32 frac;
|
|
|
|
if (chr->actiontype == ACT_PATROL && chr->act_patrol.waydata.mode == WAYMODE_MAGIC) {
|
|
chrPatrolGetCurWaypointInfo(chr, pos, rooms);
|
|
|
|
if (!(chr->act_patrol.waydata.magicdone >= chr->act_patrol.waydata.magictotal)
|
|
&& chr->act_patrol.waydata.magictotal > 0) {
|
|
frac = chr->act_patrol.waydata.magicdone / chr->act_patrol.waydata.magictotal;
|
|
pos->x = (pos->x - chr->prop->pos.x) * frac + chr->prop->pos.x;
|
|
pos->y = (pos->y - chr->prop->pos.y) * frac + chr->prop->pos.y;
|
|
pos->z = (pos->z - chr->prop->pos.z) * frac + chr->prop->pos.z;
|
|
}
|
|
} else if (chr->actiontype == ACT_GOPOS && chr->act_gopos.waydata.mode == WAYMODE_MAGIC) {
|
|
chrGoPosGetCurWaypointInfo(chr, pos, rooms);
|
|
|
|
if (!(chr->act_gopos.waydata.magicdone >= chr->act_gopos.waydata.magictotal)
|
|
&& chr->act_gopos.waydata.magictotal > 0) {
|
|
frac = chr->act_gopos.waydata.magicdone / chr->act_gopos.waydata.magictotal;
|
|
pos->x = (pos->x - chr->prop->pos.x) * frac + chr->prop->pos.x;
|
|
pos->y = (pos->y - chr->prop->pos.y) * frac + chr->prop->pos.y;
|
|
pos->z = (pos->z - chr->prop->pos.z) * frac + chr->prop->pos.z;
|
|
}
|
|
} else {
|
|
pos->x = chr->prop->pos.x;
|
|
pos->y = chr->prop->pos.y;
|
|
pos->z = chr->prop->pos.z;
|
|
}
|
|
}
|
|
|
|
void chrGoPosChooseAnimation(struct chrdata *chr)
|
|
{
|
|
s32 gospeed = chr->act_gopos.flags & GOPOSMASK_SPEED;
|
|
s32 male = g_HeadsAndBodies[chr->bodynum].ismale;
|
|
struct prop *gun1 = chrGetHeldProp(chr, 1);
|
|
struct prop *gun2 = chrGetHeldProp(chr, 0);
|
|
s32 flip = false;
|
|
s32 heavy;
|
|
s32 race = CHRRACE(chr);
|
|
s32 anim = -1;
|
|
u32 stack;
|
|
f32 speed = 0.5;
|
|
f32 sp60 = 16;
|
|
f32 animspeed = -1;
|
|
f32 startframe = 16;
|
|
|
|
if (chr->actiontype == ACT_GOPOS) {
|
|
chr->act_gopos.flags &= ~GOPOSFLAG_WAITING;
|
|
}
|
|
|
|
if (race == RACE_EYESPY || chr->aibot) {
|
|
return;
|
|
}
|
|
|
|
if (race == RACE_HUMAN || race == RACE_SKEDAR) {
|
|
if ((gun1 && gun2) || (!gun1 && !gun2)) {
|
|
heavy = false;
|
|
flip = random() % 2;
|
|
} else {
|
|
if (weaponIsOneHanded(gun1) || weaponIsOneHanded(gun2)) {
|
|
heavy = false;
|
|
flip = (bool)gun1 != false;
|
|
} else {
|
|
heavy = true;
|
|
flip = (bool)gun1 != false;
|
|
}
|
|
}
|
|
|
|
if (race == RACE_SKEDAR) {
|
|
if (gospeed == GOPOSFLAG_RUN) {
|
|
anim = ANIM_SKEDAR_RUNNING;
|
|
} else if (gospeed == GOPOSFLAG_JOG) {
|
|
anim = ANIM_0393;
|
|
} else if (gospeed == GOPOSFLAG_WALK) {
|
|
anim = ANIM_0392;
|
|
}
|
|
} else {
|
|
if (heavy) {
|
|
if (gospeed == GOPOSFLAG_RUN) {
|
|
// Human, heavy weapon, running
|
|
if (chr->hitpart == HITPART_LFOOT
|
|
|| chr->hitpart == HITPART_LSHIN
|
|
|| chr->hitpart == HITPART_LTHIGH
|
|
|| chr->hitpart == HITPART_RFOOT
|
|
|| chr->hitpart == HITPART_RSHIN
|
|
|| chr->hitpart == HITPART_RTHIGH) {
|
|
anim = ANIM_020A;
|
|
speed = 0.4;
|
|
} else if (chr->hitpart == HITPART_LHAND
|
|
|| chr->hitpart == HITPART_LFOREARM
|
|
|| chr->hitpart == HITPART_LBICEP
|
|
|| chr->hitpart == HITPART_RHAND
|
|
|| chr->hitpart == HITPART_RFOREARM
|
|
|| chr->hitpart == HITPART_RBICEP) {
|
|
anim = ANIM_020D;
|
|
speed = 0.4;
|
|
} else {
|
|
anim = ANIM_0029;
|
|
speed = 0.25;
|
|
}
|
|
|
|
if (chr->chrflags & CHRCFLAG_RUNFASTER) {
|
|
animspeed = 0.65;
|
|
startframe = 48;
|
|
} else {
|
|
animspeed = 0.5;
|
|
startframe = 48;
|
|
}
|
|
} else if (gospeed == GOPOSFLAG_JOG) {
|
|
// Human, heavy weapon, jogging
|
|
if (chr->hitpart == HITPART_LFOOT
|
|
|| chr->hitpart == HITPART_LSHIN
|
|
|| chr->hitpart == HITPART_LTHIGH
|
|
|| chr->hitpart == HITPART_RFOOT
|
|
|| chr->hitpart == HITPART_RSHIN
|
|
|| chr->hitpart == HITPART_RTHIGH) {
|
|
anim = ANIM_01F9;
|
|
} else if (chr->hitpart == HITPART_LHAND
|
|
|| chr->hitpart == HITPART_LFOREARM
|
|
|| chr->hitpart == HITPART_LBICEP
|
|
|| chr->hitpart == HITPART_RHAND
|
|
|| chr->hitpart == HITPART_RFOREARM
|
|
|| chr->hitpart == HITPART_RBICEP) {
|
|
anim = ANIM_01F8;
|
|
} else {
|
|
anim = ANIM_RUNNING_TWOHANDGUN;
|
|
}
|
|
} else {
|
|
// Human, heavy weapon, walking
|
|
if (chr->hitpart == HITPART_LFOOT
|
|
|| chr->hitpart == HITPART_LSHIN
|
|
|| chr->hitpart == HITPART_LTHIGH
|
|
|| chr->hitpart == HITPART_RFOOT
|
|
|| chr->hitpart == HITPART_RSHIN
|
|
|| chr->hitpart == HITPART_RTHIGH) {
|
|
anim = ANIM_01F9;
|
|
} else if (chr->hitpart == HITPART_LHAND
|
|
|| chr->hitpart == HITPART_LFOREARM
|
|
|| chr->hitpart == HITPART_LBICEP
|
|
|| chr->hitpart == HITPART_RHAND
|
|
|| chr->hitpart == HITPART_RFOREARM
|
|
|| chr->hitpart == HITPART_RBICEP) {
|
|
anim = ANIM_01F8;
|
|
} else {
|
|
if (random() % 2) {
|
|
anim = ANIM_0018;
|
|
} else {
|
|
anim = ANIM_0028;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (gospeed == GOPOSFLAG_RUN) {
|
|
// Human, light weapon, running
|
|
if (chr->hitpart == HITPART_LFOOT
|
|
|| chr->hitpart == HITPART_LSHIN
|
|
|| chr->hitpart == HITPART_LTHIGH) {
|
|
anim = ANIM_020A;
|
|
flip = true;
|
|
speed = 0.4;
|
|
} else if (chr->hitpart == HITPART_RFOOT
|
|
|| chr->hitpart == HITPART_RSHIN
|
|
|| chr->hitpart == HITPART_RTHIGH) {
|
|
anim = ANIM_020A;
|
|
speed = 0.4;
|
|
flip = false;
|
|
} else if (chr->hitpart == HITPART_LHAND
|
|
|| chr->hitpart == HITPART_LFOREARM
|
|
|| chr->hitpart == HITPART_LBICEP) {
|
|
anim = ANIM_020D;
|
|
speed = 0.4;
|
|
flip = true;
|
|
} else if (chr->hitpart == HITPART_RHAND
|
|
|| chr->hitpart == HITPART_RFOREARM
|
|
|| chr->hitpart == HITPART_RBICEP) {
|
|
anim = ANIM_020D;
|
|
speed = 0.4;
|
|
flip = false;
|
|
} else if (male) {
|
|
if (random() % 4 == 0) {
|
|
speed = 0.25;
|
|
anim = ANIM_001E;
|
|
} else {
|
|
speed = 0.25;
|
|
anim = ANIM_005A;
|
|
sp60 = 24;
|
|
}
|
|
} else {
|
|
if (random() % 2) {
|
|
anim = ANIM_005E;
|
|
} else {
|
|
anim = ANIM_005A;
|
|
}
|
|
|
|
speed = 0.25;
|
|
}
|
|
|
|
if (chr->chrflags & CHRCFLAG_RUNFASTER) {
|
|
animspeed = 0.65;
|
|
startframe = 48;
|
|
} else {
|
|
animspeed = 0.5;
|
|
startframe = 48;
|
|
}
|
|
} else if (gospeed == GOPOSFLAG_JOG) {
|
|
// Human, light weapon, jogging
|
|
if (chr->hitpart == HITPART_LFOOT
|
|
|| chr->hitpart == HITPART_LSHIN
|
|
|| chr->hitpart == HITPART_LTHIGH) {
|
|
anim = ANIM_01F9;
|
|
flip = false;
|
|
} else if (chr->hitpart == HITPART_RFOOT
|
|
|| chr->hitpart == HITPART_RSHIN
|
|
|| chr->hitpart == HITPART_RTHIGH) {
|
|
anim = ANIM_01F9;
|
|
flip = true;
|
|
} else if (chr->hitpart == HITPART_LHAND
|
|
|| chr->hitpart == HITPART_LFOREARM
|
|
|| chr->hitpart == HITPART_LBICEP) {
|
|
anim = ANIM_01F8;
|
|
flip = false;
|
|
} else if (chr->hitpart == HITPART_RHAND
|
|
|| chr->hitpart == HITPART_RFOREARM
|
|
|| chr->hitpart == HITPART_RBICEP) {
|
|
anim = ANIM_01F8;
|
|
flip = true;
|
|
} else if (stageGetIndex(g_Vars.stagenum) == STAGEINDEX_CHICAGO) {
|
|
anim = ANIM_005F;
|
|
} else if (male) {
|
|
if (random() % 2) {
|
|
anim = ANIM_001D;
|
|
} else {
|
|
anim = ANIM_RUNNING_ONEHANDGUN;
|
|
}
|
|
} else {
|
|
if (chr->myaction != MA_PANIC) {
|
|
if (random() % 2) {
|
|
anim = ANIM_005D;
|
|
} else {
|
|
anim = ANIM_0073;
|
|
}
|
|
} else {
|
|
anim = ANIM_021D;
|
|
}
|
|
}
|
|
} else {
|
|
// Human, light weapon, walking
|
|
s32 anims[] = {ANIM_006B, ANIM_001B, ANIM_0016};
|
|
|
|
if (chr->hitpart == HITPART_LFOOT
|
|
|| chr->hitpart == HITPART_LSHIN
|
|
|| chr->hitpart == HITPART_LTHIGH) {
|
|
anim = ANIM_01F9;
|
|
flip = false;
|
|
} else if (chr->hitpart == HITPART_RFOOT
|
|
|| chr->hitpart == HITPART_RSHIN
|
|
|| chr->hitpart == HITPART_RTHIGH) {
|
|
anim = ANIM_01F9;
|
|
flip = true;
|
|
} else if (chr->hitpart == HITPART_LHAND
|
|
|| chr->hitpart == HITPART_LFOREARM
|
|
|| chr->hitpart == HITPART_LBICEP) {
|
|
anim = ANIM_01F8;
|
|
flip = false;
|
|
} else if (chr->hitpart == HITPART_RHAND
|
|
|| chr->hitpart == HITPART_RFOREARM
|
|
|| chr->hitpart == HITPART_RBICEP) {
|
|
anim = ANIM_01F8;
|
|
flip = true;
|
|
} else if (male) {
|
|
anim = anims[random() % 3];
|
|
} else {
|
|
if (random() % 2) {
|
|
anim = ANIM_005C;
|
|
} else {
|
|
anim = ANIM_0072;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else if (race == RACE_DRCAROLL) {
|
|
if (gospeed == GOPOSFLAG_RUN) {
|
|
anim = ANIM_0160;
|
|
} else if (gospeed == GOPOSFLAG_WALK) {
|
|
anim = ANIM_015F;
|
|
} else {
|
|
anim = ANIM_015F;
|
|
}
|
|
} else if (race == RACE_ROBOT) {
|
|
anim = ANIM_0238;
|
|
}
|
|
|
|
if (anim >= 0) {
|
|
modelSetAnimation(chr->model, anim, flip, 0, speed, sp60);
|
|
|
|
if (animspeed > 0) {
|
|
modelSetAnimSpeed(chr->model, animspeed, startframe);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool chrGoToRoomPos(struct chrdata *chr, struct coord *pos, s16 *room, u32 goposflags)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct waypoint *nextwaypoint;
|
|
struct waypoint *lastwaypoint;
|
|
struct waypoint *waypoints[MAX_CHRWAYPOINTS];
|
|
s32 i;
|
|
struct coord curwppos;
|
|
s16 curwprooms[8];
|
|
s32 isgopos = chr->actiontype == ACT_GOPOS
|
|
&& (chr->act_gopos.flags & GOPOSMASK_SPEED) == (goposflags & 0xff & GOPOSMASK_SPEED)
|
|
&& !chrGoPosIsWaiting(chr);
|
|
s32 ismagic = isgopos && chr->act_gopos.waydata.mode == WAYMODE_MAGIC;
|
|
struct coord prevpos;
|
|
s32 numwaypoints = 0;
|
|
|
|
for (i = 0; chr->prop->rooms[i] != -1; i++) {
|
|
chr->oldrooms[i] = chr->prop->rooms[i];
|
|
}
|
|
|
|
chr->oldrooms[i] = -1;
|
|
|
|
if (isgopos && ismagic && chr->act_gopos.waypoints[chr->act_gopos.curindex]) {
|
|
nextwaypoint = chr->act_gopos.waypoints[chr->act_gopos.curindex];
|
|
} else {
|
|
nextwaypoint = waypointFindClosestToPos(&prop->pos, prop->rooms);
|
|
}
|
|
|
|
lastwaypoint = waypointFindClosestToPos(pos, room);
|
|
|
|
if (nextwaypoint && lastwaypoint) {
|
|
waypointSetHashThing(
|
|
((g_Vars.lvframe60 >> 9) << 7) + chr->chrnum * 8,
|
|
((g_Vars.lvframe60 >> 9) << 7) + chr->chrnum * 8);
|
|
numwaypoints = waypointFindRoute(nextwaypoint, lastwaypoint, waypoints, MAX_CHRWAYPOINTS);
|
|
waypointSetHashThing(0, 0);
|
|
}
|
|
|
|
if (numwaypoints > 1) {
|
|
if (isgopos && ismagic) {
|
|
chrCalculatePosition(chr, &prevpos);
|
|
} else {
|
|
prevpos.x = prop->pos.x;
|
|
prevpos.y = prop->pos.y;
|
|
prevpos.z = prop->pos.z;
|
|
}
|
|
|
|
chrStopFiring(chr);
|
|
|
|
chr->actiontype = ACT_GOPOS;
|
|
chr->act_gopos.endpos.x = pos->x;
|
|
chr->act_gopos.endpos.y = pos->y;
|
|
chr->act_gopos.endpos.z = pos->z;
|
|
roomsCopy(room, chr->act_gopos.endrooms);
|
|
|
|
chr->act_gopos.target = lastwaypoint;
|
|
chr->act_gopos.curindex = 0;
|
|
chr->act_gopos.flags = goposflags | GOPOSFLAG_INIT;
|
|
chr->act_gopos.turnspeed = 0;
|
|
chr->unk32c_21 = 0;
|
|
chr->act_gopos.waydata.age = random() % 100;
|
|
chr->act_gopos.waydata.gotaimposobj = 0;
|
|
|
|
if (!isgopos) {
|
|
chr->act_gopos.waydata.lastvisible60 = -1;
|
|
}
|
|
|
|
for (i = 0; i < MAX_CHRWAYPOINTS; i++) {
|
|
chr->act_gopos.waypoints[i] = waypoints[i];
|
|
}
|
|
|
|
chrGoPosInitExpensive(chr);
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
chr->goposforce = -1;
|
|
#endif
|
|
chr->sleep = 0;
|
|
chr->liftaction = 0;
|
|
chr->act_gopos.flags &= ~(GOPOSFLAG_WALKDIRECT | GOPOSFLAG_DUCK | GOPOSFLAG_WAITING);
|
|
chrGoPosGetCurWaypointInfo(chr, &curwppos, curwprooms);
|
|
|
|
if ((!isgopos || ismagic)
|
|
&& g_Vars.normmplayerisrunning == false
|
|
&& (prop->flags & (PROPFLAG_ONANYSCREENPREVTICK | PROPFLAG_ONANYSCREENTHISTICK | PROPFLAG_ONTHISSCREENTHISTICK)) == 0
|
|
&& chrIsRoomOffScreen(chr, &curwppos, curwprooms)
|
|
&& chr->inlift == false) {
|
|
chrGoPosInitMagic(chr, &chr->act_gopos.waydata, &curwppos, &prevpos);
|
|
}
|
|
|
|
if (chr->act_gopos.waydata.mode != WAYMODE_MAGIC
|
|
&& modelIsAnimMerging(chr->model) && !chr->aibot) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
return true;
|
|
} else {
|
|
if (!isgopos) {
|
|
chrGoPosChooseAnimation(chr);
|
|
}
|
|
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
struct path *pathFindById(u32 path_id)
|
|
{
|
|
s32 i = 0;
|
|
|
|
for (i = 0; g_StageSetup.paths[i].pads; i++) {
|
|
if (path_id == g_StageSetup.paths[i].id) {
|
|
return &g_StageSetup.paths[i];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void chrPatrolChooseAnimation(struct chrdata *chr)
|
|
{
|
|
struct prop *leftprop = chrGetHeldProp(chr, HAND_LEFT);
|
|
struct prop *rightprop = chrGetHeldProp(chr, HAND_RIGHT);
|
|
s32 flip;
|
|
bool heavy;
|
|
s32 race = CHRRACE(chr);
|
|
s32 ismale = g_HeadsAndBodies[chr->bodynum].ismale;
|
|
f32 speed;
|
|
|
|
if (race == RACE_EYESPY) {
|
|
// empty
|
|
} else if (race == RACE_HUMAN || race == RACE_SKEDAR) {
|
|
if ((leftprop && rightprop) || (!leftprop && !rightprop)) {
|
|
// No weapon, or double weapons
|
|
heavy = false;
|
|
flip = random() % 2;
|
|
} else {
|
|
// Single weapon
|
|
if (weaponIsOneHanded(leftprop) || weaponIsOneHanded(rightprop)) {
|
|
heavy = false;
|
|
flip = ((bool)leftprop != false);
|
|
} else {
|
|
heavy = true;
|
|
flip = ((bool)leftprop != false);
|
|
}
|
|
}
|
|
|
|
if (race == RACE_SKEDAR) {
|
|
modelSetAnimation(chr->model, ANIM_0392, flip, 0, 0.25f, 16);
|
|
} else {
|
|
speed = 0.5f * func0f02dff0(ANIM_0028) / func0f02dff0(ANIM_006B);
|
|
|
|
if (heavy) {
|
|
modelSetAnimation(chr->model, random() % 2 ? ANIM_0018 : ANIM_0028, flip, 0, speed, 16);
|
|
} else if (ismale) {
|
|
s32 anims[] = { ANIM_006B, ANIM_001B, ANIM_0016 };
|
|
modelSetAnimation(chr->model, anims[random() % 3], flip, 0, speed, 16);
|
|
} else {
|
|
modelSetAnimation(chr->model, random() % 2 ? ANIM_005C : ANIM_0072, flip, 0, speed, 16);
|
|
}
|
|
}
|
|
} else if (race == RACE_DRCAROLL) {
|
|
modelSetAnimation(chr->model, ANIM_015F, false, 0, 0.5f, 16);
|
|
} else if (race == RACE_ROBOT) {
|
|
modelSetAnimation(chr->model, ANIM_0238, false, 0, 0.5f, 16);
|
|
}
|
|
}
|
|
|
|
void chrStartPatrol(struct chrdata *chr, struct path *path)
|
|
{
|
|
s32 i;
|
|
f32 dist;
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
s32 *padnumptr;
|
|
struct pad pad;
|
|
struct coord nextpos;
|
|
s16 nextrooms[8];
|
|
s16 rooms[8];
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
f32 bestdistance = 0;
|
|
s32 nextstep = -1;
|
|
struct prop *prop = chr->prop;
|
|
s16 sp60[2];
|
|
|
|
if (CHRRACE(chr) != RACE_EYESPY) {
|
|
// Do some kind of collision test with the pad to resume from...
|
|
// maybe a line of sight check?
|
|
if (chr->patrolnextstep >= 0 && chr->patrolnextstep < path->len) {
|
|
padnumptr = &path->pads[chr->patrolnextstep];
|
|
padUnpack(*padnumptr, PADFIELD_POS | PADFIELD_ROOM, &pad);
|
|
|
|
rooms[0] = pad.room;
|
|
rooms[1] = -1;
|
|
|
|
chrGetBbox(prop, &radius, &ymax, &ymin);
|
|
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
if (cd0002d840(&prop->pos, prop->rooms, &pad.pos, rooms, CDTYPE_BG, 1,
|
|
ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION) {
|
|
nextstep = chr->patrolnextstep;
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
}
|
|
|
|
// If the pad to resume from is not in sight, find the closest pad
|
|
// to the chr's current position and start from there.
|
|
if (nextstep < 0) {
|
|
for (i = 0; path->pads[i] >= 0; i++) {
|
|
padnumptr = &path->pads[i];
|
|
padUnpack(*padnumptr, PADFIELD_POS, &pad);
|
|
|
|
xdiff = pad.pos.x - prop->pos.x;
|
|
zdiff = pad.pos.z - prop->pos.z;
|
|
dist = xdiff * xdiff + zdiff * zdiff;
|
|
|
|
if (nextstep < 0 || dist < bestdistance) {
|
|
bestdistance = dist;
|
|
nextstep = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
padnumptr = &path->pads[nextstep];
|
|
padUnpack(*padnumptr, PADFIELD_POS | PADFIELD_ROOM, &pad);
|
|
|
|
rooms[0] = pad.room;
|
|
rooms[1] = -1;
|
|
|
|
// If chr has line of sight to the pad then begin the patrol,
|
|
// otherwise use gopos to get to the starting pad
|
|
if (func0f03654c(chr, &prop->pos, prop->rooms, &pad.pos, rooms, NULL,
|
|
chr->radius * 1.2f, CDTYPE_PATHBLOCKER | CDTYPE_BG) != CDRESULT_COLLISION) {
|
|
chrStopFiring(chr);
|
|
|
|
chr->actiontype = ACT_PATROL;
|
|
chr->act_patrol.path = path;
|
|
chr->act_patrol.nextstep = nextstep;
|
|
chr->act_patrol.forward = true;
|
|
|
|
chr->act_patrol.waydata.age = random() % 100;
|
|
chr->act_patrol.waydata.gotaimposobj = 0;
|
|
chr->act_patrol.waydata.lastvisible60 = -1;
|
|
|
|
chr->act_patrol.turnspeed = 0;
|
|
|
|
func0f037580(chr);
|
|
|
|
chr->sleep = 0;
|
|
chr->liftaction = LIFTACTION_NOTUSINGLIFT;
|
|
chr->patrolnextstep = chr->act_patrol.nextstep;
|
|
|
|
chrPatrolGetCurWaypointInfo(chr, &nextpos, nextrooms);
|
|
|
|
if (!g_Vars.normmplayerisrunning
|
|
&& (chr->prop->flags & (PROPFLAG_ONTHISSCREENTHISTICK | PROPFLAG_ONANYSCREENTHISTICK | PROPFLAG_ONANYSCREENPREVTICK)) == 0
|
|
&& chrIsRoomOffScreen(chr, &nextpos, nextrooms)
|
|
&& !chr->inlift) {
|
|
chrGoPosInitMagic(chr, &chr->act_patrol.waydata, &nextpos, &prop->pos);
|
|
}
|
|
|
|
// @bug: This should be act_patrol rather than act_gopos.
|
|
// It's actually reading act_patrol.waydata.aimposobj.y which is a
|
|
// float, so it's taking its binary representation and comparing it
|
|
// with integer 6.
|
|
if (chr->act_gopos.waydata.mode != WAYMODE_MAGIC && modelIsAnimMerging(chr->model)) {
|
|
chr->hidden |= CHRHFLAG_NEEDANIM;
|
|
} else {
|
|
chrPatrolChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
} else {
|
|
sp60[0] = pad.room;
|
|
sp60[1] = -1;
|
|
|
|
chrGoToRoomPos(chr, &pad.pos, sp60, GOPOSFLAG_FORPATHSTART);
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrRecordLastVisibleTargetTime(struct chrdata *chr)
|
|
{
|
|
chr->lastvisibletarget60 = g_Vars.lvframe60;
|
|
}
|
|
|
|
bool chrCanSeeEntity(struct chrdata *chr, struct coord *chrpos, s16 *chrrooms, bool allowextraheight, u32 attackflags, u32 entityid)
|
|
{
|
|
bool result = false;
|
|
struct coord targetpos;
|
|
s16 targetrooms[8];
|
|
struct prop *targetprop;
|
|
struct chrdata *targetchr;
|
|
u32 types;
|
|
struct prop *weaponprop;
|
|
|
|
if (attackflags & ATTACKFLAG_AIMFORWARD) {
|
|
result = true;
|
|
} else {
|
|
types = CDTYPE_DOORSWITHOUTFLAG | CDTYPE_ALL;
|
|
weaponprop = chrGetHeldProp(chr, HAND_RIGHT);
|
|
|
|
if (weaponprop == NULL) {
|
|
weaponprop = chrGetHeldProp(chr, HAND_LEFT);
|
|
}
|
|
|
|
if (weaponprop) {
|
|
struct weaponobj *weapon = weaponprop->weapon;
|
|
|
|
if (weapon->weaponnum == WEAPON_ROCKETLAUNCHER
|
|
|| weapon->weaponnum == WEAPON_SLAYER
|
|
|| weapon->weaponnum == WEAPON_ROCKETLAUNCHER_34) {
|
|
types = CDTYPE_DOORSWITHOUTFLAG | CDTYPE_OBJSWITHFLAG2 | CDTYPE_ALL;
|
|
} else {
|
|
types = CDTYPE_DOORSWITHOUTFLAG | CDTYPE_OBJSWITHFLAG | CDTYPE_ALL;
|
|
}
|
|
}
|
|
|
|
chrGetAttackEntityPos(chr, attackflags, entityid, &targetpos, targetrooms);
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
if ((attackflags & ATTACKFLAG_AIMATTARGET)) {
|
|
targetprop = chrGetTargetProp(chr);
|
|
|
|
if (targetprop->type != PROPTYPE_PLAYER || g_Vars.bondvisible) {
|
|
propSetPerimEnabled(targetprop, false);
|
|
|
|
if (allowextraheight && (chr->chrflags & CHRCFLAG_LOSEXTRAHEIGHT)) {
|
|
struct coord frompos;
|
|
s16 fromrooms[8];
|
|
|
|
frompos.x = chrpos->x;
|
|
frompos.y = chrpos->y + 70;
|
|
frompos.z = chrpos->z;
|
|
|
|
func0f065dd8(chrpos, chrrooms, &frompos, fromrooms);
|
|
|
|
if (cdHasLineOfSight(&frompos, fromrooms, &targetpos, targetrooms, types, 0x10)) {
|
|
chrRecordLastVisibleTargetTime(chr);
|
|
result = true;
|
|
}
|
|
} else {
|
|
if (cdHasLineOfSight(chrpos, chrrooms, &targetpos, targetrooms, types, 0x10)) {
|
|
chrRecordLastVisibleTargetTime(chr);
|
|
result = true;
|
|
}
|
|
}
|
|
|
|
propSetPerimEnabled(targetprop, true);
|
|
}
|
|
} else if (attackflags & ATTACKFLAG_AIMATCHR) {
|
|
targetchr = chrFindById(chr, entityid);
|
|
|
|
if (!targetchr || !targetchr->prop) {
|
|
targetchr = chr;
|
|
}
|
|
|
|
chrSetPerimEnabled(targetchr, false);
|
|
|
|
if (cdHasLineOfSight(chrpos, chrrooms, &targetpos, targetrooms, types, 0x10)) {
|
|
result = true;
|
|
}
|
|
|
|
chrSetPerimEnabled(targetchr, true);
|
|
} else if (attackflags & ATTACKFLAG_AIMATPAD) {
|
|
if (cdHasLineOfSight(chrpos, chrrooms, &targetpos, targetrooms, types, 0x10)) {
|
|
result = true;
|
|
}
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool chrCanSeeAttackTarget(struct chrdata *chr, struct coord *pos, s16 *rooms, bool allowextraheight)
|
|
{
|
|
u32 attackflags = ATTACKFLAG_AIMATTARGET;
|
|
u32 entityid = 0;
|
|
|
|
if (chr->actiontype == ACT_ATTACK) {
|
|
attackflags = chr->act_attack.flags;
|
|
entityid = chr->act_attack.entityid;
|
|
}
|
|
|
|
return chrCanSeeEntity(chr, pos, rooms, allowextraheight, attackflags, entityid);
|
|
}
|
|
|
|
bool chrCanSeeChr(struct chrdata *chr, struct chrdata *target, s16 *room)
|
|
{
|
|
bool cansee = false;
|
|
u32 stack;
|
|
s16 sp88[] = {-1, 0, 0, 0, 0, 0, 0, 0};
|
|
|
|
if (botIsTargetInvisible(chr, target) == 0) {
|
|
struct prop *prop = chr->prop;
|
|
struct coord pos;
|
|
s16 rooms[8];
|
|
|
|
pos.x = prop->pos.x;
|
|
pos.y = chr->ground + chr->height - 20;
|
|
pos.z = prop->pos.z;
|
|
|
|
chrSetPerimEnabled(chr, false);
|
|
chrSetPerimEnabled(target, false);
|
|
|
|
func0f065e74(&prop->pos, prop->rooms, &pos, rooms);
|
|
|
|
if (cd0002dcfc(&pos, rooms, &target->prop->pos, target->prop->rooms, sp88, 307, 8)) {
|
|
cansee = true;
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
chrSetPerimEnabled(target, true);
|
|
}
|
|
|
|
if (room) {
|
|
*room = sp88[0];
|
|
}
|
|
|
|
return cansee;
|
|
}
|
|
|
|
bool chrCanSeeTarget(struct chrdata *chr)
|
|
{
|
|
bool cansee;
|
|
struct prop *prop;
|
|
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cansee = false;
|
|
prop = chrGetTargetProp(chr);
|
|
|
|
if (prop && prop->chr) {
|
|
cansee = chrCanSeeChr(chr, prop->chr, NULL);
|
|
|
|
if (cansee) {
|
|
chrRecordLastVisibleTargetTime(chr);
|
|
}
|
|
}
|
|
#else
|
|
prop = chrGetTargetProp(chr);
|
|
cansee = chrCanSeeChr(chr, prop->chr, NULL);
|
|
|
|
if (cansee) {
|
|
chrRecordLastVisibleTargetTime(chr);
|
|
}
|
|
#endif
|
|
|
|
return cansee;
|
|
}
|
|
|
|
bool chrHasLineOfSightToPos(struct chrdata *viewerchr, struct coord *pos, s16 *rooms)
|
|
{
|
|
struct prop *viewerprop = viewerchr->prop;
|
|
bool result = false;
|
|
struct coord viewerpos;
|
|
s16 viewerrooms[8];
|
|
|
|
viewerpos.x = viewerprop->pos.x;
|
|
viewerpos.y = viewerchr->ground + viewerchr->height - 20;
|
|
viewerpos.z = viewerprop->pos.z;
|
|
|
|
chrSetPerimEnabled(viewerchr, false);
|
|
func0f065e74(&viewerprop->pos, viewerprop->rooms, &viewerpos, viewerrooms);
|
|
|
|
if (cdHasLineOfSight(&viewerpos, viewerrooms, pos, rooms, 307, 8)) {
|
|
result = true;
|
|
}
|
|
|
|
chrSetPerimEnabled(viewerchr, true);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool chrCanSeePos(struct chrdata *chr, struct coord *pos, s16 *rooms)
|
|
{
|
|
f32 facingangle = chrGetInverseTheta(chr);
|
|
f32 posangle = atan2f(pos->x - chr->prop->pos.x, pos->z - chr->prop->pos.z);
|
|
f32 diffangle = posangle - facingangle;
|
|
|
|
if (posangle < facingangle) {
|
|
diffangle += M_BADTAU;
|
|
}
|
|
|
|
// This check is pointless because chrHasLineOfSightToPos is called
|
|
// with the same arguments regardless.
|
|
if ((diffangle < 1.7450513839722f || diffangle > 4.5371336936951f)
|
|
&& chrHasFlag(chr, CHRFLAG1_NOOP_00200000, BANK_1) == false) {
|
|
return chrHasLineOfSightToPos(chr, pos, rooms);
|
|
}
|
|
|
|
return chrHasLineOfSightToPos(chr, pos, rooms);
|
|
}
|
|
|
|
bool chrCanSeeProp(struct chrdata *chr, struct prop *prop)
|
|
{
|
|
bool result;
|
|
|
|
propSetPerimEnabled(prop, false);
|
|
result = chrCanSeePos(chr, &prop->pos, prop->rooms);
|
|
propSetPerimEnabled(prop, true);
|
|
|
|
return result;
|
|
}
|
|
|
|
void chrRecordLastSeeTargetTime(struct chrdata *chr)
|
|
{
|
|
chr->lastseetarget60 = g_Vars.lvframe60;
|
|
}
|
|
|
|
void chrRecordLastHearTargetTime(struct chrdata *chr)
|
|
{
|
|
chr->hidden |= CHRHFLAG_IS_HEARING_TARGET;
|
|
chr->lastheartarget60 = g_Vars.lvframe60;
|
|
}
|
|
|
|
bool chrIsStopped(struct chrdata *chr)
|
|
{
|
|
s16 anim = modelGetAnimNum(chr->model);
|
|
|
|
if (anim == ANIM_SNIPING_GETDOWN || anim == ANIM_SNIPING_GETUP) {
|
|
return false;
|
|
}
|
|
|
|
if (anim == ANIM_SNIPING_ONGROUND && chr->act_attack.numshots >= chr->act_attack.maxshots) {
|
|
chrStopFiring(chr);
|
|
return true;
|
|
}
|
|
|
|
if (chr->actiontype == ACT_ROBOTATTACK && chr->act_robotattack.finished) {
|
|
return true;
|
|
}
|
|
|
|
if (chr->actiontype == ACT_ATTACKAMOUNT && chr->act_attack.numshots >= chr->act_attack.maxshots) {
|
|
return true;
|
|
}
|
|
|
|
if (chr->actiontype == ACT_STAND
|
|
&& !chr->act_stand.prestand
|
|
&& !chr->act_stand.reaim
|
|
&& chr->act_stand.turning != 1) {
|
|
return true;
|
|
}
|
|
|
|
if (chr->actiontype == ACT_ANIM) {
|
|
if (chr->act_anim.completed
|
|
|| (modelGetAnimSpeed(chr->model) >= 0 && modelGetCurAnimFrame(chr->model) >= modelGetAnimEndFrame(chr->model))
|
|
|| (modelGetAnimSpeed(chr->model) < 0 && modelGetCurAnimFrame(chr->model) <= 0)) {
|
|
return true;
|
|
}
|
|
} else if (chr->actiontype == ACT_PATROL) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrCheckTargetInSight(struct chrdata *chr)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 sqdistance;
|
|
f32 fVar5 = chrGetInverseTheta(chr);
|
|
|
|
f32 x = target->pos.x - prop->pos.x;
|
|
f32 y = target->pos.y - prop->pos.y;
|
|
f32 z = target->pos.z - prop->pos.z;
|
|
|
|
f32 fVar6 = atan2f(x, z);
|
|
f32 angle = fVar6 - fVar5;
|
|
bool result = false;
|
|
|
|
if (fVar6 < fVar5) {
|
|
angle += M_BADTAU;
|
|
}
|
|
|
|
sqdistance = x * x + y * y + z * z;
|
|
|
|
if ((sqdistance < chr->visionrange * chr->visionrange * 10000.0f && (angle < 1.9195564985275f || angle > 4.3626284599304f))
|
|
|| (sqdistance < 40000.0f && (angle < 1.9195564985275f || angle > 4.3626284599304f))) {
|
|
result = false;
|
|
|
|
if (sqdistance < env0f1657e4()) {
|
|
f32 tmp;
|
|
s32 iVar8 = (sqrtf(sqdistance) * 0.0018749999580905f);
|
|
s32 tmp2;
|
|
|
|
if (angle > 0.7852731347084f && angle < 5.4969120025635f) {
|
|
tmp = angle;
|
|
|
|
if (tmp > M_PI) {
|
|
tmp = M_BADTAU - angle;
|
|
}
|
|
|
|
tmp -= 0.7852731347084f;
|
|
tmp2 = tmp * 3.8203268051147f;
|
|
iVar8 *= 1 + tmp2;
|
|
}
|
|
|
|
iVar8 = chrGetPercentageOfSlowness(chr, iVar8) + 1;
|
|
result = random() % iVar8 == 0;
|
|
}
|
|
}
|
|
|
|
if (result) {
|
|
result = chrCanSeeTarget(chr);
|
|
}
|
|
|
|
if (result) {
|
|
chrRecordLastSeeTargetTime(chr);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool chrIsReadyForOrders(struct chrdata *chr)
|
|
{
|
|
if (chr->onladder) {
|
|
return false;
|
|
}
|
|
|
|
switch (chr->actiontype) {
|
|
case ACT_DIE:
|
|
case ACT_DEAD:
|
|
case ACT_PREARGH:
|
|
case ACT_DRUGGEDDROP:
|
|
case ACT_DRUGGEDKO:
|
|
case ACT_DRUGGEDCOMINGUP:
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
case ACT_ARGH:
|
|
case 0x200:
|
|
#endif
|
|
return false;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
case ACT_ARGH:
|
|
if ((chr->chrflags & CHRCFLAG_00000200) == 0) {
|
|
return false;
|
|
}
|
|
break;
|
|
#endif
|
|
case ACT_ROBOTATTACK:
|
|
if (!chr->act_robotattack.finished) {
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool chrIsDead(struct chrdata *chr)
|
|
{
|
|
if (!chr || chr->actiontype == ACT_DIE || chr->actiontype == ACT_DEAD) {
|
|
return true;
|
|
}
|
|
|
|
if (chr->prop && chr->prop->type == PROPTYPE_PLAYER) {
|
|
u32 playernum = playermgrGetPlayerNumByProp(chr->prop);
|
|
|
|
if (g_Vars.players[playernum]->isdead) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTrySidestep(struct chrdata *chr)
|
|
{
|
|
u8 race = CHRRACE(chr);
|
|
|
|
if ((race == RACE_HUMAN || race == RACE_SKEDAR)
|
|
&& chrIsReadyForOrders(chr)) {
|
|
struct prop *prop = chr->prop;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 a = chrGetInverseTheta(chr);
|
|
f32 b = atan2f(target->pos.x - prop->pos.x, target->pos.z - prop->pos.z);
|
|
f32 angle = b - a;
|
|
u32 stack[2];
|
|
|
|
if (b < a) {
|
|
angle += M_BADTAU;
|
|
}
|
|
|
|
if (angle < 0.7852731347084f || angle > 5.4969120025635f
|
|
|| (angle > 2.3558194637299f && angle < 3.9263656139374f)) {
|
|
bool side = (random() % 2) == 0;
|
|
|
|
if (chrCanJumpInDirection(chr, side, 100)) {
|
|
chrSidestep(chr, side);
|
|
return true;
|
|
}
|
|
|
|
if (chrCanJumpInDirection(chr, !side, 100)) {
|
|
chrSidestep(chr, !side);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryJumpOut(struct chrdata *chr)
|
|
{
|
|
if (CHRRACE(chr) == RACE_HUMAN && chrIsReadyForOrders(chr)) {
|
|
struct prop *prop = chr->prop;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
|
|
f32 a = chrGetInverseTheta(chr);
|
|
f32 b = atan2f(target->pos.x - prop->pos.x, target->pos.z - prop->pos.z);
|
|
f32 angle = b - a;
|
|
u32 stack[2];
|
|
|
|
if (b < a) {
|
|
angle += M_BADTAU;
|
|
}
|
|
|
|
// This commented code is what the floats represent, but mismatches due
|
|
// to float precision:
|
|
//if (angle < BADDEG2RAD(45) || angle > BADDEG2RAD(315)
|
|
// || (angle > BADDEG2RAD(135) && angle < BADDEG2RAD(225))) {
|
|
if (angle < 0.7852731347084f || angle > 5.4969120025635f
|
|
|| (angle > 2.3558194637299f && angle < BADDEG2RAD(225))) {
|
|
bool side = (random() % 2) == 0;
|
|
|
|
if (chrCanJumpInDirection(chr, side, 200)) {
|
|
chrJumpOut(chr, side);
|
|
return true;
|
|
}
|
|
|
|
if (chrCanJumpInDirection(chr, !side, 200)) {
|
|
chrJumpOut(chr, !side);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryRunSideways(struct chrdata *chr)
|
|
{
|
|
u32 race = CHRRACE(chr);
|
|
|
|
if ((race == RACE_HUMAN || race == RACE_SKEDAR)
|
|
&& chrIsReadyForOrders(chr)
|
|
&& g_Vars.lvframe60 - chr->lastwalk60 > TICKS(180)) {
|
|
struct prop *prop = chr->prop;
|
|
f32 distance = 200.0f + RANDOMFRAC() * 200.0f;
|
|
struct coord vector;
|
|
struct coord dstpos;
|
|
|
|
chrGetSideVectorToTarget(chr, random() % 2 == 0, &vector);
|
|
|
|
dstpos.x = vector.x * distance + prop->pos.x;
|
|
dstpos.y = prop->pos.y;
|
|
dstpos.z = vector.z * distance + prop->pos.z;
|
|
|
|
if (propchrHasClearLineToPos(prop, &dstpos, &vector)) {
|
|
chrRunToPos(chr, &dstpos);
|
|
return true;
|
|
}
|
|
|
|
vector.x = -vector.x;
|
|
vector.z = -vector.z;
|
|
|
|
dstpos.x = vector.x * distance + prop->pos.x;
|
|
dstpos.y = prop->pos.y;
|
|
dstpos.z = vector.z * distance + prop->pos.z;
|
|
|
|
if (propchrHasClearLineToPos(prop, &dstpos, &vector)) {
|
|
chrRunToPos(chr, &dstpos);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryAttackWalk(struct chrdata *chr)
|
|
{
|
|
u32 race = CHRRACE(chr);
|
|
|
|
if (race == RACE_DRCAROLL || race == RACE_EYESPY) {
|
|
return false;
|
|
}
|
|
|
|
if (chrIsReadyForOrders(chr)) {
|
|
struct prop *prop = chr->prop;
|
|
|
|
if (chrCanSeeAttackTarget(chr, &prop->pos, prop->rooms, false)
|
|
&& (chrGetHeldUsableProp(chr, 0) || chrGetHeldUsableProp(chr, 1))
|
|
&& g_Vars.lvframe60 - chr->lastwalk60 > TICKS(120)) {
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 x = target->pos.x - prop->pos.x;
|
|
f32 y = target->pos.y - prop->pos.y;
|
|
f32 z = target->pos.z - prop->pos.z;
|
|
|
|
if (race == RACE_HUMAN && x * x + y * y + z * z >= 1000 * 1000) {
|
|
chrAttackWalk(chr, false);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryAttackRun(struct chrdata *chr)
|
|
{
|
|
u32 race = CHRRACE(chr);
|
|
|
|
if (race == RACE_DRCAROLL || race == RACE_EYESPY) {
|
|
return false;
|
|
}
|
|
|
|
if (chrIsReadyForOrders(chr)) {
|
|
struct prop *prop = chr->prop;
|
|
|
|
if (chrCanSeeAttackTarget(chr, &prop->pos, prop->rooms, false)
|
|
&& (chrGetHeldUsableProp(chr, 0) || chrGetHeldUsableProp(chr, 1))
|
|
&& g_Vars.lvframe60 - chr->lastwalk60 > TICKS(180)) {
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 x = target->pos.x - prop->pos.x;
|
|
f32 y = target->pos.y - prop->pos.y;
|
|
f32 z = target->pos.z - prop->pos.z;
|
|
|
|
if (race == RACE_HUMAN && x * x + y * y + z * z >= 1000 * 1000) {
|
|
chrAttackWalk(chr, true);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryAttackRoll(struct chrdata *chr)
|
|
{
|
|
if (CHRRACE(chr) == RACE_HUMAN && chrIsReadyForOrders(chr)) {
|
|
struct prop *prop = chr->prop;
|
|
|
|
if (chrCanSeeAttackTarget(chr, &prop->pos, prop->rooms, false) &&
|
|
(chrGetHeldUsableProp(chr, 0) || chrGetHeldUsableProp(chr, 1))) {
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 x = target->pos.x - prop->pos.x;
|
|
f32 y = target->pos.y - prop->pos.y;
|
|
f32 z = target->pos.z - prop->pos.z;
|
|
f32 sqdistance = x * x + y * y + z * z;
|
|
|
|
if (sqdistance >= 200 * 200) {
|
|
bool toleft = (random() % 2) == 0;
|
|
|
|
if (chrCanRollInDirection(chr, toleft, 200)) {
|
|
chrAttackRoll(chr, toleft);
|
|
return true;
|
|
}
|
|
|
|
if (chrCanRollInDirection(chr, !toleft, 200)) {
|
|
chrAttackRoll(chr, !toleft);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryAttackAmount(struct chrdata *chr, u32 arg1, u32 arg2, u8 lower, u8 upper)
|
|
{
|
|
u8 race = CHRRACE(chr);
|
|
|
|
if ((race == RACE_HUMAN || race == RACE_SKEDAR)
|
|
&& chrIsReadyForOrders(chr)
|
|
&& chr->weapons_held[0]) {
|
|
s32 quantity;
|
|
f32 percentage;
|
|
struct weaponobj *weapon = chr->weapons_held[0]->weapon;
|
|
struct inventory_ammo *ammo;
|
|
|
|
quantity = 1;
|
|
|
|
if (upper > 100) {
|
|
upper = 100;
|
|
}
|
|
|
|
if (lower < upper) {
|
|
percentage = ((random() % (upper - lower)) + (u32)lower) * 0.01f;
|
|
} else {
|
|
percentage = 0;
|
|
}
|
|
|
|
ammo = weaponGetAmmoByFunction(weapon->weaponnum, 0);
|
|
|
|
if (ammo) {
|
|
quantity = ammo->clipsize * percentage;
|
|
}
|
|
|
|
if (quantity < 1) {
|
|
quantity = 1;
|
|
}
|
|
|
|
chr->aimendrshoulder = 0;
|
|
chr->aimendlshoulder = 0;
|
|
chr->aimendback = 0;
|
|
chr->aimendsideback = 0;
|
|
chr->aimendcount = 10;
|
|
|
|
chrAttackAmount(chr, arg1, arg2, quantity);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryAttackStand(struct chrdata *chr, u32 attackflags, s32 entityid)
|
|
{
|
|
s32 race = CHRRACE(chr);
|
|
|
|
if (race == RACE_DRCAROLL || race == RACE_EYESPY) {
|
|
return false;
|
|
}
|
|
|
|
if (chrIsReadyForOrders(chr)) {
|
|
if (race == RACE_ROBOT) {
|
|
robotAttack(chr);
|
|
return true;
|
|
}
|
|
|
|
if (race == RACE_HUMAN || race == RACE_SKEDAR) {
|
|
if (chrGetHeldUsableProp(chr, 0) ||
|
|
(chrGetHeldUsableProp(chr, 1))) {
|
|
chrAttackStand(chr, attackflags, entityid);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryAttackKneel(struct chrdata *chr, u32 attackflags, s32 entityid)
|
|
{
|
|
s32 race = CHRRACE(chr);
|
|
|
|
if (race == RACE_HUMAN || race == RACE_SKEDAR) {
|
|
if (chrIsReadyForOrders(chr) && (chrGetHeldUsableProp(chr, 0) || chrGetHeldUsableProp(chr, 1))) {
|
|
chrAttackKneel(chr, attackflags, entityid);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryAttackLie(struct chrdata *chr, u32 attackflags, s32 entityid)
|
|
{
|
|
s32 race = CHRRACE(chr);
|
|
|
|
if (race == RACE_HUMAN || race == RACE_SKEDAR) {
|
|
if (chrIsReadyForOrders(chr) && (chrGetHeldUsableProp(chr, 0) || chrGetHeldUsableProp(chr, 1))) {
|
|
chrAttackLie(chr, attackflags, entityid);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryModifyAttack(struct chrdata *chr, u32 attackflags, s32 entityid)
|
|
{
|
|
s32 race = CHRRACE(chr);
|
|
|
|
if (race == RACE_DRCAROLL || race == RACE_EYESPY) {
|
|
return false;
|
|
}
|
|
|
|
if (chr->actiontype == ACT_ATTACK
|
|
&& (chr->act_attack.flags & (ATTACKFLAG_AIMONLY | ATTACKFLAG_DONTTURN))) {
|
|
chr->act_attack.flags = attackflags;
|
|
chr->act_attack.entityid = entityid;
|
|
func0f031254(chr);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrFaceEntity(struct chrdata *chr, u32 attackflags, s32 entityid)
|
|
{
|
|
if (chrIsReadyForOrders(chr)) {
|
|
if (chr->actiontype != ACT_STAND) {
|
|
chrStand(chr);
|
|
}
|
|
|
|
if (attackflags != chr->act_stand.flags || entityid != chr->act_stand.entityid) {
|
|
chr->act_stand.flags = attackflags;
|
|
chr->act_stand.entityid = entityid;
|
|
chr->act_stand.reaim = 0;
|
|
chr->act_stand.checkfacingwall = false;
|
|
|
|
if (attackflags == ATTACKFLAG_AIMATTARGET && entityid == 1) {
|
|
chr->act_stand.playwalkanim = true;
|
|
chr->act_stand.entityid = 0;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrGoToPad(struct chrdata *chr, s32 padnum, u32 goposflags)
|
|
{
|
|
if (padnum >= 0
|
|
&& chrIsReadyForOrders(chr)
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
&& (g_NumChrsSeenPlayerRecently2 <= 8
|
|
|| (chr->hidden & CHRHFLAG_00400000) == 0
|
|
|| (chr->flags & CHRFLAG0_ACTIVATEALARM))
|
|
#else
|
|
&& g_NumChrsSeenPlayerRecently2 <= 9
|
|
#endif
|
|
) {
|
|
padnum = chrResolvePadId(chr, padnum);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (padnum >= 0)
|
|
#endif
|
|
{
|
|
s16 rooms[2];
|
|
struct pad pad;
|
|
|
|
padUnpack(padnum, PADFIELD_ROOM | PADFIELD_POS, &pad);
|
|
|
|
rooms[0] = pad.room;
|
|
rooms[1] = -1;
|
|
|
|
if (chrGoToRoomPos(chr, &pad.pos, rooms, goposflags)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrSetPath(struct chrdata *chr, u32 path_id)
|
|
{
|
|
chr->path = path_id;
|
|
return true;
|
|
}
|
|
|
|
bool chrTryStartPatrol(struct chrdata *chr)
|
|
{
|
|
struct path *path = pathFindById(chr->path);
|
|
|
|
if (path && chrIsReadyForOrders(chr)) {
|
|
chrStartPatrol(chr, path);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTrySurrender(struct chrdata *chr)
|
|
{
|
|
if (CHRRACE(chr) == RACE_HUMAN && chrIsReadyForOrders(chr)) {
|
|
chrSurrender(chr);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrFadeOut(struct chrdata *chr)
|
|
{
|
|
chrBeginDead(chr);
|
|
chrFadeCorpse(chr);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool chrGoToTarget(struct chrdata *chr, u32 goposflags)
|
|
{
|
|
if (chrIsReadyForOrders(chr)) {
|
|
if (
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
g_NumChrsSeenPlayerRecently2 <= 8
|
|
|| (chr->hidden & CHRHFLAG_00400000) == 0
|
|
|| (chr->flags & CHRFLAG0_ACTIVATEALARM)
|
|
#else
|
|
g_NumChrsSeenPlayerRecently2 <= 9
|
|
#endif
|
|
) {
|
|
struct prop *prop = chrGetTargetProp(chr);
|
|
|
|
if (chrGoToRoomPos(chr, &prop->pos, prop->rooms, goposflags)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrGoToChr(struct chrdata *chr, u32 dst_chrnum, u32 goposflags)
|
|
{
|
|
if (chrIsReadyForOrders(chr)) {
|
|
if (
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
g_NumChrsSeenPlayerRecently2 <= 8
|
|
|| (chr->hidden & CHRHFLAG_00400000) == 0
|
|
|| (chr->flags & CHRFLAG0_ACTIVATEALARM)
|
|
#else
|
|
g_NumChrsSeenPlayerRecently2 <= 9
|
|
#endif
|
|
) {
|
|
struct chrdata *dstchr = chrFindById(chr, dst_chrnum);
|
|
|
|
if (dstchr && dstchr->prop && chrGoToRoomPos(chr, &dstchr->prop->pos, dstchr->prop->rooms, goposflags)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrGoToProp(struct chrdata *chr, struct prop *prop, u32 goposflags)
|
|
{
|
|
if (chrIsReadyForOrders(chr) && prop) {
|
|
if (chrGoToRoomPos(chr, &prop->pos, prop->rooms, goposflags)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrGoToPos(struct chrdata *chr, struct coord *pos, u32 goposflags)
|
|
{
|
|
s16 inrooms[21];
|
|
s16 aboverooms[21];
|
|
|
|
if (chrIsReadyForOrders(chr)) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (g_NumChrsSeenPlayerRecently2 < 9
|
|
|| (chr->hidden & CHRHFLAG_00400000) == 0
|
|
|| (chr->flags & CHRCFLAG_00040000))
|
|
#else
|
|
if (g_NumChrsSeenPlayerRecently2 < 10)
|
|
#endif
|
|
{
|
|
s16 *rooms = NULL;
|
|
|
|
bgFindRoomsByPos(pos, inrooms, aboverooms, 20, NULL);
|
|
|
|
if (inrooms[0] != -1) {
|
|
rooms = inrooms;
|
|
} else if (aboverooms[0] != -1) {
|
|
rooms = aboverooms;
|
|
}
|
|
|
|
if (rooms != NULL && chrGoToRoomPos(chr, pos, rooms, goposflags)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
s32 func0f03aca0(struct chrdata *chr, f32 arg1, u8 arg2)
|
|
{
|
|
f32 somefloat;
|
|
|
|
if (!arg2) {
|
|
arg1 -= chrGetDistanceToCoord(chr, &chr->runfrompos);
|
|
}
|
|
|
|
if (arg1 < 0) {
|
|
chrAssignCoverByCriteria(g_Vars.chrdata,
|
|
COVERCRITERIA_FURTHEREST
|
|
| COVERCRITERIA_DISTTOTARGET
|
|
| COVERCRITERIA_ONLYNEIGHBOURINGROOMS
|
|
| COVERCRITERIA_ROOMSFROMME, 0);
|
|
return chrGoToCover(chr, GOPOSFLAG_RUN);
|
|
}
|
|
|
|
somefloat = arg1 - 2000;
|
|
|
|
if (somefloat < 2000) {
|
|
somefloat = 2000;
|
|
}
|
|
|
|
if (!chrAssignCoverAwayFromDanger(chr, somefloat, arg1 + 10000)) {
|
|
chrAssignCoverByCriteria(g_Vars.chrdata,
|
|
COVERCRITERIA_FURTHEREST
|
|
| COVERCRITERIA_DISTTOTARGET
|
|
| COVERCRITERIA_ONLYNEIGHBOURINGROOMS
|
|
| COVERCRITERIA_ROOMSFROMME, 0);
|
|
}
|
|
|
|
return chrGoToCover(chr, GOPOSFLAG_RUN);
|
|
}
|
|
|
|
bool chrTryStop(struct chrdata *chr)
|
|
{
|
|
if (CHRRACE(chr) == RACE_EYESPY) {
|
|
func0f02e9a0(chr, 0);
|
|
return true;
|
|
}
|
|
|
|
if (chrIsReadyForOrders(chr)) {
|
|
chrStop(chr);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTrySurprisedOneHand(struct chrdata *chr)
|
|
{
|
|
if (CHRRACE(chr) == RACE_HUMAN && chrIsReadyForOrders(chr)) {
|
|
chrDoSurprisedOneHand(chr);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTrySurprisedSurrender(struct chrdata *chr)
|
|
{
|
|
if (CHRRACE(chr) == RACE_HUMAN && chrIsReadyForOrders(chr)) {
|
|
chrDoSurprisedSurrender(chr);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTrySurprisedLookAround(struct chrdata *chr)
|
|
{
|
|
if (CHRRACE(chr) == RACE_HUMAN && chrIsReadyForOrders(chr)) {
|
|
chrDoSurprisedLookAround(chr);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryKneel(struct chrdata *chr)
|
|
{
|
|
if (CHRRACE(chr) == RACE_HUMAN && chrIsReadyForOrders(chr)) {
|
|
chrKneel(chr);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryStartAnim(struct chrdata *chr, s32 animfnum, f32 startframe, f32 endframe, u8 chranimflags, s32 merge, f32 speed)
|
|
{
|
|
if (chrIsReadyForOrders(chr)) {
|
|
chrStartAnim(chr, animfnum, startframe, endframe, chranimflags, merge, speed);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryRunFromTarget(struct chrdata *chr)
|
|
{
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
struct prop *prop = chr->prop;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
struct coord dst;
|
|
s16 rooms[8];
|
|
struct coord diff;
|
|
f32 distance;
|
|
|
|
if (chrIsReadyForOrders(chr)) {
|
|
if (!target) {
|
|
return false;
|
|
}
|
|
|
|
diff.x = target->pos.x - prop->pos.x;
|
|
diff.z = target->pos.z - prop->pos.z;
|
|
diff.y = 0;
|
|
|
|
distance = sqrtf(diff.f[0] * diff.f[0] + diff.f[2] * diff.f[2]);
|
|
|
|
// Scale diff into range -1 to +1
|
|
diff.x *= (1 / distance);
|
|
diff.z *= (1 / distance);
|
|
|
|
// Set dst to 1000 units in the opposite direction
|
|
dst.x = prop->pos.x - diff.x * 1000;
|
|
dst.z = prop->pos.z - diff.z * 1000;
|
|
dst.y = prop->pos.y;
|
|
|
|
propGetBbox(prop, &radius, &ymax, &ymin);
|
|
|
|
// If dst runs into a wall, set it to closest valid spot
|
|
if (!cd0002d7c0(&prop->pos, prop->rooms, &dst, 0x33, 1,
|
|
ymax - prop->pos.y, ymin - prop->pos.y)) {
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cdGetPos(&dst, 8796, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_FINAL
|
|
cdGetPos(&dst, 8793, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cdGetPos(&dst, 8788, "chraction.c");
|
|
#else
|
|
cdGetPos(&dst, 8782, "chraction.c");
|
|
#endif
|
|
}
|
|
|
|
// Adjust dst to be two chr widths closer to avoid collision with wall
|
|
dst.x = dst.x + (diff.x * radius + diff.x * radius);
|
|
dst.z = dst.z + (diff.z * radius + diff.z * radius);
|
|
|
|
if (func0f036974(prop, &dst)) {
|
|
u32 speed = GOPOSFLAG_RUN;
|
|
|
|
if (CHRRACE(chr) == RACE_HUMAN) {
|
|
f32 dist = chrGetDistanceToCoord(chr, &dst);
|
|
|
|
if (dist > 100) {
|
|
speed = GOPOSFLAG_RUN;
|
|
} else if (dist < 50) {
|
|
speed = GOPOSFLAG_WALK;
|
|
} else {
|
|
speed = GOPOSFLAG_JOG;
|
|
}
|
|
}
|
|
|
|
func0f065e74(&prop->pos, prop->rooms, &dst, rooms);
|
|
chrGoToRoomPos(chr, &dst, rooms, speed);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
const char var7f1a8ae4[] = "aimadjust=%d";
|
|
|
|
#if VERSION >= VERSION_PAL_FINAL
|
|
const char var7f1a8af4[] = "chr/chraction.c";
|
|
#else
|
|
const char var7f1a8af4[] = "chraction.c";
|
|
#endif
|
|
|
|
const char var7f1a8b00[] = "firing(%d) %d, beam(%d) %s";
|
|
const char var7f1a8b1c[] = "on";
|
|
const char var7f1a8b20[] = "off";
|
|
const char var7f1a8b24[] = "firecount(%d) = %d";
|
|
const char var7f1a8b38[] = "numshots(%d) = %d";
|
|
|
|
/**
|
|
* Attempt to make the chr find a suitable prop in their current room to use as
|
|
* cover and run to it. However, a bug prevents this from working.
|
|
*/
|
|
bool chrGoToCoverProp(struct chrdata *chr)
|
|
{
|
|
struct prop *targetprop = chrGetTargetProp(chr);
|
|
struct prop *chrprop = chr->prop;
|
|
s16 i;
|
|
s16 propnums[258];
|
|
struct defaultobj *obj;
|
|
s16 numprops;
|
|
s16 startindex;
|
|
|
|
if (targetprop == NULL) {
|
|
return false;
|
|
}
|
|
|
|
if (chrIsReadyForOrders(chr)) {
|
|
roomGetProps(chrprop->rooms, propnums, 256);
|
|
|
|
for (numprops = 0; propnums[numprops] >= 0; numprops++);
|
|
|
|
if (numprops > 0) {
|
|
startindex = random() % numprops;
|
|
}
|
|
|
|
for (i = 0; i < numprops; i++) {
|
|
struct prop *prop = &g_Vars.props[propnums[(i + startindex) % numprops]];
|
|
obj = prop->obj;
|
|
|
|
if (prop->type == PROPTYPE_OBJ
|
|
&& (obj->hidden2 & OBJH2FLAG_DESTROYED) == 0
|
|
&& (obj->hidden & OBJHFLAG_00008000) == 0
|
|
&& (obj->hidden & OBJHFLAG_OCCUPIEDCHAIR) == 0) {
|
|
f32 targetdist = propGetDistanceToProp(targetprop, prop);
|
|
f32 chrdist = propGetDistanceToProp(chrprop, prop);
|
|
|
|
// @bug: This condition cannot pass
|
|
// (should be chrdist < targetdist + targetdist)
|
|
if (chrdist < 300 && chrdist > targetdist + targetdist && targetdist > 800) {
|
|
f32 propymax;
|
|
f32 propymin;
|
|
f32 propradius;
|
|
f32 chrymax;
|
|
f32 chrymin;
|
|
f32 chrradius;
|
|
f32 propheight;
|
|
f32 chrheight;
|
|
struct coord dstpos;
|
|
s16 dstrooms[8];
|
|
|
|
propGetBbox(prop, &propradius, &propymax, &propymin);
|
|
propGetBbox(chrprop, &chrradius, &chrymax, &chrymin);
|
|
|
|
propheight = propymax - propymin;
|
|
chrheight = chrymax - chrymin;
|
|
|
|
if (propheight > chrheight * 0.4f && propheight < chrheight * 0.9f) {
|
|
propSetPerimEnabled(prop, false);
|
|
|
|
if (cd0002dc18(&chrprop->pos, chrprop->rooms, &prop->pos, CDTYPE_DOORS | CDTYPE_BG)) {
|
|
propSetPerimEnabled(prop, true);
|
|
|
|
dstpos.x = prop->pos.x - (targetprop->pos.x - prop->pos.x) / targetdist * (propradius * 1.25f + chrradius);
|
|
dstpos.z = prop->pos.z - (targetprop->pos.z - prop->pos.z) / targetdist * (propradius * 1.25f + chrradius);
|
|
dstpos.y = prop->pos.y;
|
|
|
|
if (func0f036974(chrprop, &dstpos)) {
|
|
u32 speed = GOPOSFLAG_JOG;
|
|
|
|
if (CHRRACE(chr) == RACE_HUMAN) {
|
|
if (chrdist > 1500) {
|
|
speed = GOPOSFLAG_RUN;
|
|
} else if (chrdist < 100) {
|
|
speed = GOPOSFLAG_WALK;
|
|
}
|
|
}
|
|
|
|
func0f065e74(&chrprop->pos, chrprop->rooms, &dstpos, dstrooms);
|
|
chrGoToRoomPos(chr, &dstpos, dstrooms, speed);
|
|
|
|
chr->proppreset1 = prop - g_Vars.props;
|
|
obj->hidden |= OBJHFLAG_OCCUPIEDCHAIR;
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
propSetPerimEnabled(prop, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrTryStartAlarm(struct chrdata *chr, s32 pad_id)
|
|
{
|
|
if (CHRRACE(chr) == RACE_HUMAN && chrIsReadyForOrders(chr)) {
|
|
pad_id = chrResolvePadId(chr, pad_id);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (pad_id >= 0)
|
|
#endif
|
|
{
|
|
struct defaultobj *obj = objFindByPadNum(pad_id);
|
|
|
|
if (obj && objIsHealthy(obj)) {
|
|
chrStartAlarm(chr);
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
s32 chrConsiderGrenadeThrow(struct chrdata *chr, u32 attackflags, u32 entityid)
|
|
{
|
|
bool done = false;
|
|
|
|
if (CHRRACE(chr) == RACE_HUMAN &&
|
|
chr->grenadeprob > (random() % 255) &&
|
|
chrGetDistanceToTarget(chr) > 200 &&
|
|
chrIsReadyForOrders(chr)) {
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
struct coord pos;
|
|
|
|
if (target) {
|
|
pos.x = target->pos.x;
|
|
pos.y = target->pos.y;
|
|
pos.z = target->pos.z;
|
|
}
|
|
|
|
if (target && cd0002dc18(&chr->prop->pos, chr->prop->rooms, &pos, 0x33)) {
|
|
struct prop *leftprop = chrGetHeldProp(chr, 1);
|
|
struct prop *rightprop = chrGetHeldProp(chr, 0);
|
|
struct weaponobj *weapon;
|
|
|
|
#if PIRACYCHECKS
|
|
{
|
|
u32 checksum = 0;
|
|
s32 *i = (s32 *)&bgReset;
|
|
s32 *end = (s32 *)&bgBuildTables;
|
|
u32 stackpadding[1];
|
|
|
|
while (i < end) {
|
|
checksum += *i;
|
|
checksum += (*i >> 1);
|
|
i++;
|
|
}
|
|
|
|
if (checksum != CHECKSUM_PLACEHOLDER) {
|
|
// Make player explode continuously
|
|
g_Vars.currentplayer->bondexploding = true;
|
|
g_Vars.currentplayer->bondnextexplode = g_Vars.lvframe60 + 120;
|
|
g_Vars.currentplayer->bondcurexplode = 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// If grenade is equipped in either hand, use it
|
|
if (rightprop) {
|
|
weapon = rightprop->weapon;
|
|
|
|
if (weapon->weaponnum == WEAPON_GRENADE || weapon->weaponnum == WEAPON_NBOMB) {
|
|
chrThrowGrenade(chr, 0, false);
|
|
chr->act_throwgrenade.flags = attackflags;
|
|
chr->act_throwgrenade.entityid = entityid;
|
|
done = true;
|
|
}
|
|
}
|
|
|
|
if (!done && leftprop) {
|
|
weapon = leftprop->weapon;
|
|
|
|
if (weapon->weaponnum == WEAPON_GRENADE || weapon->weaponnum == WEAPON_NBOMB) {
|
|
chrThrowGrenade(chr, 1, false);
|
|
chr->act_throwgrenade.flags = attackflags;
|
|
chr->act_throwgrenade.entityid = entityid;
|
|
done = true;
|
|
}
|
|
}
|
|
|
|
// Grenade not equipped, and using a single weapon
|
|
if (!done && (leftprop == NULL || rightprop == NULL)) {
|
|
struct prop *prop;
|
|
u32 flags = 0;
|
|
u32 stackpadding2[2];
|
|
|
|
if (rightprop) {
|
|
flags = OBJFLAG_WEAPON_LEFTHANDED;
|
|
}
|
|
|
|
if (stageGetIndex(g_Vars.stagenum) == STAGEINDEX_MBR) {
|
|
prop = chrGiveWeapon(chr, MODEL_CHRGRENADE, WEAPON_NBOMB, flags);
|
|
} else {
|
|
prop = chrGiveWeapon(chr, MODEL_CHRGRENADE, WEAPON_GRENADE, flags);
|
|
}
|
|
|
|
if (prop) {
|
|
weapon = prop->weapon;
|
|
weapon->base.hidden |= OBJHFLAG_00000800;
|
|
chrThrowGrenade(chr, rightprop == NULL ? 0 : 1, true);
|
|
chr->act_throwgrenade.flags = attackflags;
|
|
chr->act_throwgrenade.entityid = entityid;
|
|
done = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return done;
|
|
}
|
|
|
|
bool chrDropItem(struct chrdata *chr, u32 modelnum, u32 weaponnum)
|
|
{
|
|
struct weaponobj *weapon;
|
|
u8 race = CHRRACE(chr);
|
|
|
|
if (race == RACE_DRCAROLL || race == RACE_ROBOT) {
|
|
return false;
|
|
}
|
|
|
|
weapon = weaponCreateProjectileFromWeaponNum(modelnum, (u8)weaponnum, chr);
|
|
|
|
if (weapon && weapon->base.prop) {
|
|
modelSetScale(weapon->base.model, weapon->base.model->scale);
|
|
propReparent(weapon->base.prop, chr->prop);
|
|
weapon->timer240 = TICKS(720);
|
|
objSetDropped(weapon->base.prop, DROPTYPE_DEFAULT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void chrPunchInflictDamage(struct chrdata *chr, s32 damage, s32 range, u8 reverse)
|
|
{
|
|
struct prop *targetprop = chrGetTargetProp(chr);
|
|
struct gset gset = {WEAPON_UNARMED, 0, 0, FUNC_PRIMARY};
|
|
struct coord vector;
|
|
|
|
if (chr->aibot) {
|
|
gset.weaponnum = chr->aibot->weaponnum;
|
|
gset.weaponfunc = chr->aibot->gunfunc;
|
|
}
|
|
|
|
if (chrIsTargetInFov(chr, 20, reverse)
|
|
&& chrGetDistanceToTarget(chr) < range
|
|
&& cd0002dc18(&chr->prop->pos, chr->prop->rooms, &targetprop->pos, 0x33)) {
|
|
vector.x = targetprop->pos.x - chr->prop->pos.x;
|
|
vector.y = 0;
|
|
vector.z = targetprop->pos.z - chr->prop->pos.z;
|
|
|
|
guNormalize(&vector.x, &vector.y, &vector.z);
|
|
|
|
bgunPlayPropHitSound(&gset, targetprop, -1);
|
|
|
|
if (targetprop->type == PROPTYPE_PLAYER || targetprop->type == PROPTYPE_CHR) {
|
|
chrDamageByImpact(targetprop->chr, gsetGetDamage(&gset) * damage, &vector, &gset, chr->prop, 200);
|
|
}
|
|
}
|
|
|
|
weaponPlayWhooshSound(gset.weaponnum, chr->prop);
|
|
}
|
|
|
|
struct punchanim {
|
|
s32 animnum;
|
|
u32 damage;
|
|
s16 hitframe;
|
|
f32 endframe;
|
|
};
|
|
|
|
struct punchanim g_HumanPunchAnims[] = {
|
|
{ 0x027c, 5, 20, 60 },
|
|
{ 0x027d, 5, 20, 31 },
|
|
{ 0x027e, 5, 20, 48 },
|
|
{ 0x027f, 5, 20, 69 },
|
|
{ 0x0212, 5, 20, 64 },
|
|
{ 0x0213, 5, 20, 52 },
|
|
{ 0x0214, 5, 20, 51 },
|
|
{ 0x020e, 5, 20, 53 },
|
|
{ 0x020f, 5, 20, 89 },
|
|
{ 0x0210, 5, 20, 71 },
|
|
{ 0x0215, 5, 20, 62 },
|
|
{ 0x0211, 5, 20, 72 },
|
|
};
|
|
|
|
struct punchanim g_SkedarPunchAnims[] = {
|
|
{ 0x034c, 15, 25, 100 },
|
|
{ 0x034d, 15, 25, -1 },
|
|
{ 0x0395, 15, 25, -1 },
|
|
{ 0x0346, 15, 25, -1 },
|
|
{ 0x0347, 15, 25, -1 },
|
|
{ 0x034f, 15, 25, -1 },
|
|
};
|
|
|
|
/**
|
|
* Make the chr try to punch or kick.
|
|
*
|
|
* The function is only ever called with reverse = 0. If non-zero, it would
|
|
* cause Skedar to kick behind them.
|
|
*
|
|
* Note that the final human anim can't be used because the modulus value is too
|
|
* short by one.
|
|
*/
|
|
bool chrTryPunch(struct chrdata *chr, u8 reverse)
|
|
{
|
|
struct punchanim *anims = NULL;
|
|
s32 race = CHRRACE(chr);
|
|
s32 animindex;
|
|
u32 chranimflags = (random() % 256 > 128) ? CHRANIMFLAG_FLIP : 0;
|
|
s32 chrhitradius;
|
|
s32 playerhitradius;
|
|
f32 startframe;
|
|
bool ok;
|
|
|
|
if (race == RACE_HUMAN) {
|
|
anims = g_HumanPunchAnims;
|
|
startframe = 10;
|
|
chrhitradius = 120;
|
|
playerhitradius = 120;
|
|
animindex = random() % 11;
|
|
} else if (race == RACE_SKEDAR) {
|
|
anims = g_SkedarPunchAnims;
|
|
chrhitradius = 200;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
playerhitradius = 200;
|
|
#else
|
|
playerhitradius = 350;
|
|
#endif
|
|
startframe = 20;
|
|
|
|
if (reverse) {
|
|
// Skedar kick behind
|
|
animindex = 5;
|
|
} else if (!chr->weapons_held[HAND_RIGHT] && !chr->weapons_held[HAND_LEFT]) {
|
|
// Unarmed: Only use indexes 0 or 1
|
|
animindex = random() % 2;
|
|
} else {
|
|
// Allow indexes 0-4, but if 3 or 4 then flip the anim based on
|
|
// which hand is holding the gun
|
|
animindex = random() % 5;
|
|
|
|
if (animindex >= 3) {
|
|
if (!chr->weapons_held[HAND_RIGHT] || !chr->weapons_held[HAND_LEFT]) {
|
|
if (chr->weapons_held[HAND_RIGHT]) {
|
|
chranimflags = 0;
|
|
} else if (chr->weapons_held[HAND_LEFT]) {
|
|
chranimflags = CHRANIMFLAG_FLIP;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (chrHasFlag(chr, CHRFLAG1_ADJUSTPUNCHSPEED, BANK_1)) {
|
|
if (chrHasFlag(chr, CHRFLAG0_CHUCKNORRIS, BANK_0)) {
|
|
// Fast punch
|
|
ok = chrTryStartAnim(chr, anims[animindex].animnum, startframe, anims[animindex].endframe, chranimflags, 16, 1.5f);
|
|
} else {
|
|
// Slow punch
|
|
ok = chrTryStartAnim(chr, anims[animindex].animnum, startframe, anims[animindex].endframe - 25, chranimflags, 16, 0.5f);
|
|
}
|
|
|
|
chr->dodgerating = 0;
|
|
} else {
|
|
// Normal punch
|
|
ok = chrTryStartAnim(chr, anims[animindex].animnum, startframe, anims[animindex].endframe, chranimflags, 16, 0.85f);
|
|
chr->dodgerating = 0;
|
|
}
|
|
|
|
if (ok) {
|
|
struct prop *targetprop = chrGetTargetProp(chr);
|
|
|
|
if (targetprop->type == PROPTYPE_EYESPY || targetprop->type == PROPTYPE_PLAYER) {
|
|
chr->act_anim.hitradius = playerhitradius;
|
|
} else {
|
|
chr->act_anim.hitradius = chrhitradius;
|
|
}
|
|
|
|
chr->act_anim.ishitanim = true;
|
|
chr->act_anim.hitframe = anims[animindex].hitframe;
|
|
|
|
if (g_Vars.normmplayerisrunning) {
|
|
chr->act_anim.hitdamage = 1;
|
|
} else if (chrHasFlag(chr, CHRFLAG1_ADJUSTPUNCHSPEED, BANK_1) && chrHasFlag(chr, CHRFLAG0_CHUCKNORRIS, BANK_0)) {
|
|
chr->act_anim.hitdamage = (u16)anims[animindex].damage * (f32)chr->morale + (u16)anims[animindex].damage * (f32)chr->morale;
|
|
} else if (chrHasFlag(chr, CHRFLAG1_PUNCHHARDER, BANK_1)) {
|
|
chr->act_anim.hitdamage = (u16)anims[animindex].damage * 6;
|
|
} else {
|
|
chr->act_anim.hitdamage = anims[animindex].damage;
|
|
}
|
|
|
|
chr->act_anim.reverse = reverse;
|
|
chr->chrflags &= ~CHRCFLAG_INJUREDTARGET;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void func0f03c03c(void)
|
|
{
|
|
// empty
|
|
}
|
|
|
|
/**
|
|
* Verifies that the given chr struct is actually an eyespy and returns the
|
|
* eyespy struct.
|
|
*
|
|
* Eyespys have their own chr struct, even though they aren't a chr. Iterating
|
|
* the player list is required because the only pointer to an eyespy is via the
|
|
* player struct.
|
|
*/
|
|
struct eyespy *chrToEyespy(struct chrdata *chr)
|
|
{
|
|
if (chr && chr->prop) {
|
|
if (CHRRACE(chr) == RACE_EYESPY) {
|
|
s32 playercount = PLAYERCOUNT();
|
|
s32 i;
|
|
|
|
for (i = 0; i < playercount; i++) {
|
|
if (g_Vars.players[i]->eyespy && chr->prop == g_Vars.players[i]->eyespy->prop) {
|
|
return g_Vars.players[i]->eyespy;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void chrTickStand(struct chrdata *chr)
|
|
{
|
|
s32 race;
|
|
s32 i;
|
|
s32 j;
|
|
s32 stack2;
|
|
struct prop *leftgun;
|
|
struct prop *rightgun;
|
|
u32 stack[2];
|
|
f32 angle;
|
|
f32 sp74[8];
|
|
f32 sp70;
|
|
f32 sp6c;
|
|
s32 tmp;
|
|
s32 index;
|
|
s32 sp44[8];
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrChooseStandAnimation(chr, chr->act_stand.mergetime);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
if (modelGetAnimNum(chr->model) == ANIM_SNIPING_GETUP) {
|
|
if (modelGetCurAnimFrame(chr->model) >= modelGetAnimEndFrame(chr->model)) {
|
|
chrChooseStandAnimation(chr, 8);
|
|
chr->act_stand.prestand = 0;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
if (chr->sleep > 0) {
|
|
return;
|
|
}
|
|
|
|
race = CHRRACE(chr);
|
|
|
|
if (race == RACE_EYESPY) {
|
|
return;
|
|
}
|
|
|
|
if (chr->act_stand.prestand) {
|
|
if (modelGetCurAnimFrame(chr->model) >= modelGetAnimEndFrame(chr->model)) {
|
|
chrChooseStandAnimation(chr, 8);
|
|
chr->act_stand.prestand = 0;
|
|
}
|
|
|
|
chr->sleep = 0;
|
|
return;
|
|
}
|
|
|
|
if (!chr->aibot && (race == RACE_HUMAN || race == RACE_SKEDAR) && chr->act_stand.flags > 0) {
|
|
if (chr->act_stand.reaim) {
|
|
chr->act_stand.turning = chrTurn(chr, chr->act_stand.turning, modelGetNumAnimFrames(chr->model) - 1, 1, 0);
|
|
|
|
if (chr->act_stand.turning != TURNSTATE_TURNING) {
|
|
chrChooseStandAnimation(chr, 8);
|
|
chr->act_stand.reaim = false;
|
|
|
|
if (chr->act_stand.flags & ATTACKFLAG_AIMATDIRECTION) {
|
|
chr->act_stand.flags = 0;
|
|
}
|
|
}
|
|
} else {
|
|
f32 relangle = chrGetAttackEntityRelativeAngle(chr, chr->act_stand.flags, chr->act_stand.entityid);
|
|
|
|
if ((relangle > 0.34901028871536f && relangle < 5.9331746101379f)
|
|
|| (relangle > 0.17450514435768f && relangle < 6.1076798439026f && !chr->act_stand.playwalkanim)) {
|
|
leftgun = chrGetHeldProp(chr, HAND_LEFT);
|
|
rightgun = chrGetHeldProp(chr, HAND_RIGHT);
|
|
|
|
chr->act_stand.reaim = true;
|
|
chr->act_stand.turning = TURNSTATE_TURNING;
|
|
|
|
if (race == RACE_HUMAN) {
|
|
if ((leftgun && rightgun)
|
|
|| (!leftgun && !rightgun)
|
|
|| weaponIsOneHanded(leftgun)
|
|
|| weaponIsOneHanded(rightgun)) {
|
|
modelSetAnimation(chr->model, ANIM_006B, random() % 2, 0, 0.5f, 16);
|
|
modelSetAnimEndFrame(chr->model, animGetNumFrames(ANIM_006B) - 1);
|
|
} else {
|
|
if (rightgun || leftgun) {
|
|
modelSetAnimation(chr->model, ANIM_0028, leftgun != NULL, 0, 0.5f, 16);
|
|
modelSetAnimEndFrame(chr->model, animGetNumFrames(ANIM_0028) - 1);
|
|
}
|
|
}
|
|
} else if (race == RACE_SKEDAR) {
|
|
modelSetAnimation(chr->model, ANIM_0392, random() % 2, 0, 0.5f, 16);
|
|
modelSetAnimEndFrame(chr->model, animGetNumFrames(ANIM_0392) - 1);
|
|
}
|
|
} else if (chr->act_stand.flags & ATTACKFLAG_AIMATDIRECTION) {
|
|
chr->act_stand.flags = 0;
|
|
}
|
|
}
|
|
|
|
chr->sleep = 0;
|
|
return;
|
|
}
|
|
|
|
if (chr->aibot) {
|
|
return;
|
|
}
|
|
|
|
if (chr->prop->flags & PROPFLAG_ONANYSCREENPREVTICK) {
|
|
chr->sleep = 0;
|
|
} else {
|
|
chr->sleep = 14 + (random() % 5);
|
|
}
|
|
|
|
if (chr->act_stand.checkfacingwall == false) {
|
|
return;
|
|
}
|
|
|
|
if (chr->chrflags & CHRCFLAG_CANFACEWALL) {
|
|
chr->act_stand.checkfacingwall = false;
|
|
return;
|
|
}
|
|
|
|
chr->act_stand.wallcount -= chr->sleep;
|
|
|
|
if (chr->act_stand.wallcount >= 0) {
|
|
return;
|
|
}
|
|
|
|
sp6c = sp70 = chrGetInverseTheta(chr);
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
sp6c += 0.7852731347084f;
|
|
|
|
if (sp6c >= M_BADTAU) {
|
|
sp6c -= M_BADTAU;
|
|
}
|
|
|
|
sp74[i] = func0f02e550(chr->prop, sp6c, 1000, CDTYPE_BG, 0, 1);
|
|
}
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
sp44[i] = i;
|
|
}
|
|
|
|
for (i = 0; i < 7; i++) {
|
|
index = i;
|
|
|
|
for (j = index + 1; j < 8; j++) {
|
|
if (sp74[sp44[j]] < sp74[sp44[index]]) {
|
|
index = j;
|
|
}
|
|
}
|
|
|
|
j = sp44[i];
|
|
sp44[i] = sp44[index];
|
|
sp44[index] = j;
|
|
}
|
|
|
|
index = -1;
|
|
|
|
if (sp74[0] < 490) {
|
|
if (sp74[sp44[4]] < 200) {
|
|
index = 7;
|
|
} else if (sp44[0] == 0 || sp44[1] == 0 || sp44[2] == 0) {
|
|
if ((sp44[3] == 4 || sp44[4] == 4) && (random() % 3) == 0) {
|
|
if (sp44[3] == 4) {
|
|
index = 3;
|
|
} else {
|
|
index = 4;
|
|
}
|
|
} else {
|
|
index = 5 + random() % 3;
|
|
}
|
|
} else if ((sp44[0] == 1 || sp44[0] == 7) && sp44[5] && sp44[6] && sp44[7]) {
|
|
index = 5 + random() % 3;
|
|
}
|
|
}
|
|
|
|
if (index >= 0) {
|
|
i = sp44[index];
|
|
angle = sp70 + i * 0.7852731347084f;
|
|
|
|
if (angle >= M_BADTAU) {
|
|
angle -= M_BADTAU;
|
|
}
|
|
|
|
chrFaceEntity(chr, ATTACKFLAG_AIMATDIRECTION, angle * 10432.0390625f);
|
|
} else {
|
|
chr->act_stand.checkfacingwall = false;
|
|
}
|
|
}
|
|
|
|
void chrTickKneel(struct chrdata *chr)
|
|
{
|
|
chr->sleep = 0;
|
|
|
|
if ((chr->hidden & CHRHFLAG_NEEDANIM) && !modelIsAnimMerging(chr->model)) {
|
|
chrKneelChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
}
|
|
|
|
void chrTickAnim(struct chrdata *chr)
|
|
{
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
modelSetAnimation(chr->model, chr->act_anim.animnum, chr->act_anim.flip,
|
|
chr->act_anim.startframe, chr->act_anim.speed, chr->act_anim.blend);
|
|
|
|
if (chr->act_anim.endframe >= 0) {
|
|
modelSetAnimEndFrame(chr->model, chr->act_anim.endframe);
|
|
}
|
|
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
if (!chr->act_anim.pauseatend && modelGetCurAnimFrame(chr->model) >= modelGetAnimEndFrame(chr->model)) {
|
|
chrStand(chr);
|
|
}
|
|
|
|
if (chr->act_anim.ishitanim && modelGetCurAnimFrame(chr->model) >= (s32)chr->act_anim.hitframe) {
|
|
chr->act_anim.ishitanim = false;
|
|
chrPunchInflictDamage(chr, chr->act_anim.hitdamage, chr->act_anim.hitradius, chr->act_anim.reverse);
|
|
}
|
|
|
|
// Play sneezing sound
|
|
if (CHRRACE(chr) == RACE_HUMAN
|
|
&& modelGetAnimNum(chr->model) == ANIM_SNEEZE
|
|
&& modelGetCurAnimFrame(chr->model) >= 42
|
|
&& (g_Vars.lvframenum % 2) == 0
|
|
&& chrGetDistanceToCurrentPlayer(chr) < 800) {
|
|
propsnd0f0939f8(NULL, chr->prop, SFX_0037, -1,
|
|
-1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
}
|
|
|
|
if (chr->sleep <= 0 && chr->act_anim.slowupdate) {
|
|
chr->sleep = 14 + (random() % 5);
|
|
}
|
|
|
|
if (modelGetAnimNum(chr->model) == ANIM_RELOAD_0209) {
|
|
chrSetFiring(chr, HAND_RIGHT, false);
|
|
chrSetFiring(chr, HAND_LEFT, false);
|
|
}
|
|
}
|
|
|
|
void chrTickSurrender(struct chrdata *chr)
|
|
{
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrSurrenderChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
if (chr->sleep <= 0) {
|
|
if (CHRRACE(chr) == RACE_HUMAN) {
|
|
struct model *model = chr->model;
|
|
chr->sleep = 16;
|
|
|
|
if (modelGetAnimNum(model) == ANIM_SURRENDER_002F && modelGetCurAnimFrame(model) >= 80.0f) {
|
|
struct coord coord = {0, 0, 0};
|
|
f32 value = chrGetInverseTheta(chr);
|
|
coord.x = -sinf(value);
|
|
coord.z = -cosf(value);
|
|
|
|
if (!propchrHasClearLineInVector(chr->prop, &coord, 20)) {
|
|
modelSetAnimation(chr->model, ANIM_SURRENDER_002E, random() & 1, 30, 0.5, 16);
|
|
modelSetAnimLooping(chr->model, 30, 16);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrFadeCorpse(struct chrdata *chr)
|
|
{
|
|
if (chr->actiontype == ACT_DEAD || chr->actiontype == ACT_DRUGGEDKO) {
|
|
chr->act_dead.fadenow = true;
|
|
}
|
|
}
|
|
|
|
void chrFadeCorpseWhenOffScreen(struct chrdata *chr)
|
|
{
|
|
if (chr->actiontype == ACT_DEAD) {
|
|
chr->act_dead.fadewheninvis = true;
|
|
}
|
|
}
|
|
|
|
void chrTickDead(struct chrdata *chr)
|
|
{
|
|
struct aibot *aibot = chr->aibot;
|
|
|
|
// If fade is active, handle it
|
|
if (chr->act_dead.fadetimer60 >= 0) {
|
|
chr->act_dead.fadetimer60 += g_Vars.lvupdate240_60;
|
|
|
|
if (chr->act_dead.fadetimer60 >= TICKS(90)) {
|
|
// Fade finished
|
|
chr->fadealpha = 0;
|
|
|
|
if (aibot) {
|
|
botSpawn(chr, true);
|
|
} else {
|
|
chr->hidden |= CHRHFLAG_REAPED;
|
|
}
|
|
} else {
|
|
// Still fading
|
|
chr->fadealpha = (TICKS(90) - chr->act_dead.fadetimer60) * 255 / TICKS(90);
|
|
}
|
|
} else {
|
|
// If fade has been triggered (this can happen when the corpse is on
|
|
// screen and there's lots of other chrs around)
|
|
if (chr->act_dead.fadenow) {
|
|
chr->act_dead.fadetimer60 = 0;
|
|
chrDropItemsForOwnerReap(chr);
|
|
}
|
|
|
|
if (chr->prop->flags & PROPFLAG_ONANYSCREENPREVTICK) {
|
|
// Keep corpse for now
|
|
chr->act_dead.invistimer60 = 0;
|
|
} else {
|
|
chr->act_dead.invistimer60 += g_Vars.lvupdate240_60;
|
|
}
|
|
|
|
if (chr->act_dead.fadewheninvis && chr->act_dead.invistimer60 >= TICKS(120)) {
|
|
// Remove corpse (off-screen)
|
|
if (aibot == NULL) {
|
|
chr->hidden |= CHRHFLAG_REAPED;
|
|
}
|
|
|
|
chr->fadealpha = 0;
|
|
|
|
chrDropItemsForOwnerReap(chr);
|
|
}
|
|
}
|
|
|
|
if (aibot == NULL) {
|
|
chr->ailist = NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function is called when a chr is injured or killed. It iterates other
|
|
* chrs within 2000 units who can see the chr and updates their chrseeshot or
|
|
* chrseedie properties.
|
|
*
|
|
* The search stops once 7 chrs have been found in range, regardless of whether
|
|
* they can see the chr, presumably to avoid doing too many expensive line of
|
|
* sight checks in one tick. The last iterated chr index is stored and continued
|
|
* from there next time the function is called. The function is called on
|
|
* subsequent ticks while the chr is still in their injured or dying action.
|
|
*/
|
|
void chrAlertOthersOfInjury(struct chrdata *chr, bool dying)
|
|
{
|
|
s32 index = 0;
|
|
s32 numinrange = 0;
|
|
s32 numchrs = chrsGetNumSlots();
|
|
|
|
if (g_Vars.antiplayernum >= 0 && chr->prop == g_Vars.anti->prop) {
|
|
return;
|
|
}
|
|
|
|
if (chr->actiontype == ACT_ARGH) {
|
|
index = chr->act_argh.notifychrindex;
|
|
} else if (chr->actiontype == ACT_DIE || chr->actiontype == ACT_DRUGGEDDROP) {
|
|
index = chr->act_die.notifychrindex;
|
|
} else if (chr->actiontype == ACT_DEAD) {
|
|
index = chr->act_dead.notifychrindex;
|
|
}
|
|
|
|
for (; index < numchrs && numinrange < 7; index++) {
|
|
struct chrdata *loopchr = &g_ChrSlots[index];
|
|
|
|
if (loopchr->model && loopchr->prop && (loopchr->prop->flags & PROPFLAG_ENABLED)) {
|
|
f32 xdiff = loopchr->prop->pos.x - chr->prop->pos.x;
|
|
f32 ydiff = loopchr->prop->pos.y - chr->prop->pos.y;
|
|
f32 zdiff = loopchr->prop->pos.z - chr->prop->pos.z;
|
|
|
|
if (xdiff * xdiff + ydiff * ydiff + zdiff * zdiff < 4000000.0f) {
|
|
numinrange++;
|
|
|
|
if (chrCanSeePos(loopchr, &chr->prop->pos, chr->prop->rooms)) {
|
|
if (dying == false) {
|
|
loopchr->chrseeshot = chr->chrnum;
|
|
} else {
|
|
loopchr->chrseedie = chr->chrnum;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (chr->actiontype == ACT_ARGH) {
|
|
chr->act_argh.notifychrindex = index;
|
|
} else if (chr->actiontype == ACT_DIE || chr->actiontype == ACT_DRUGGEDDROP) {
|
|
chr->act_die.notifychrindex = index;
|
|
} else if (chr->actiontype == ACT_DEAD) {
|
|
chr->act_dead.notifychrindex = index;
|
|
}
|
|
}
|
|
|
|
void chrTickDie(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
u32 race = CHRRACE(chr);
|
|
|
|
u16 thuds[] = {
|
|
SFX_THUD_808D,
|
|
SFX_THUD_808E,
|
|
SFX_THUD_808F,
|
|
SFX_THUD_8090,
|
|
SFX_THUD_8091,
|
|
SFX_THUD_8092,
|
|
SFX_THUD_8093,
|
|
SFX_THUD_8094,
|
|
SFX_THUD_8095,
|
|
SFX_THUD_8096,
|
|
SFX_THUD_8097,
|
|
};
|
|
|
|
u16 specialdiesounds[] = {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
SFX_M1_NOOO, // "Noooo!"
|
|
SFX_M1_SCREAM, // Death scream
|
|
SFX_M2_NOOO, // "Noooo!"
|
|
SFX_M2_NOOO, // "Noooo!"
|
|
SFX_M1_SCREAM, // Death scream
|
|
#else
|
|
SFX_0313,
|
|
SFX_034C,
|
|
SFX_0411,
|
|
SFX_0411,
|
|
SFX_034C,
|
|
#endif
|
|
SFX_THUD_8092,
|
|
SFX_THUD_8093,
|
|
SFX_THUD_8094,
|
|
SFX_THUD_8095,
|
|
SFX_THUD_8096,
|
|
SFX_THUD_8097,
|
|
};
|
|
|
|
static s32 thudindex = 0;
|
|
|
|
if (race == RACE_EYESPY) {
|
|
return;
|
|
}
|
|
|
|
if (race == RACE_ROBOT) {
|
|
struct prop *prop = chr->prop;
|
|
func0f0926bc(prop, 1, 0xffff);
|
|
explosionCreateSimple(prop, &prop->pos, prop->rooms, EXPLOSIONTYPE_8, g_Vars.currentplayernum);
|
|
chr->hidden |= CHRHFLAG_REAPED;
|
|
return;
|
|
}
|
|
|
|
if (race == RACE_DRCAROLL) {
|
|
struct prop *prop = chr->prop;
|
|
|
|
if (g_DrCarollDyingTimer > TICKS(120) && chr->voicebox) {
|
|
// Play speech
|
|
u16 phrases[] = {
|
|
SFX_DRCAROLL_SYSTEMS_FAILURE,
|
|
SFX_DRCAROLL_YOU_GO_ON,
|
|
SFX_DRCAROLL_I_CANT_MAKE_IT,
|
|
SFX_DRCAROLL_IM_DYING,
|
|
SFX_DRCAROLL_GOODBYE,
|
|
SFX_DRCAROLL_YOU_WERE_SUPPOSED,
|
|
};
|
|
|
|
propsnd0f0939f8(NULL, chr->prop, phrases[random() % 5], -1,
|
|
-1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
chr->voicebox = 0;
|
|
}
|
|
|
|
// Change images randomly
|
|
if (chr->act_die.drcarollimagedelay > 0) {
|
|
chr->act_die.drcarollimagedelay -= g_Vars.lvupdate240_60;
|
|
} else {
|
|
chr->act_die.drcarollimagedelay = (random() % TICKS(1000)) * 0.01f + 5.0f;
|
|
chr->drcarollimage_left = 1 + (s32)((random() % 400) * 0.01f);
|
|
chr->drcarollimage_right = 1 + (s32)((random() % 400) * 0.01f);
|
|
}
|
|
|
|
if (g_DrCarollDyingTimer > TICKS(310)) {
|
|
// Explode
|
|
func0f0926bc(prop, 1, 0xffff);
|
|
explosionCreateSimple(prop, &prop->pos, prop->rooms, EXPLOSIONTYPE_8, g_Vars.currentplayernum);
|
|
chrBeginDead(chr);
|
|
} else if (chr->soundtimer > (s32)var80068080) {
|
|
// Play shield damage sound
|
|
chr->soundtimer = 0;
|
|
var80068080 -= 5;
|
|
propsnd0f0939f8(NULL, prop, SFX_SHIELD_DAMAGE, -1,
|
|
-1, 1024, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
sparksCreate(prop->rooms[0], prop, &prop->pos, NULL, 0, SPARKTYPE_ELECTRICAL);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
// Human or Skedar
|
|
// If due, play thud 1 sound
|
|
if (chr->act_die.thudframe1 >= 0 && modelGetCurAnimFrame(model) >= chr->act_die.thudframe1) {
|
|
if (chr->specialdie == 0) {
|
|
propsnd0f0939f8(NULL, chr->prop, thuds[thudindex], -1,
|
|
-1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
} else if (chr->specialdie != SPECIALDIE_OVERRAILING) {
|
|
propsnd0f0939f8(NULL, chr->prop, specialdiesounds[chr->specialdie - 1], -1,
|
|
-1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
}
|
|
|
|
thudindex++;
|
|
|
|
if (thudindex > 10) {
|
|
thudindex = 0;
|
|
}
|
|
|
|
chr->act_die.thudframe1 = -1;
|
|
}
|
|
|
|
// If due, play thud 2 sound
|
|
if (chr->act_die.thudframe2 >= 0 && modelGetCurAnimFrame(model) >= chr->act_die.thudframe2) {
|
|
if (chr->specialdie < 5) {
|
|
propsnd0f0939f8(NULL, chr->prop, SFX_THUD_808E, -1,
|
|
-1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
} else {
|
|
propsnd0f0939f8(NULL, chr->prop, thuds[thudindex], -1,
|
|
-1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
}
|
|
|
|
thudindex++;
|
|
|
|
if (thudindex > 10) {
|
|
thudindex = 0;
|
|
}
|
|
|
|
chr->act_die.thudframe2 = -1;
|
|
}
|
|
|
|
// Check for end of death animation and switch to ACT_DEAD
|
|
if (modelGetCurAnimFrame(model) >= modelGetAnimEndFrame(model)) {
|
|
if (CHRRACE(chr) == RACE_HUMAN && modelGetAnimNum(model) == ANIM_DEATH_STOMACH_LONG) {
|
|
modelSetAnimation(model, ANIM_003C, !modelIsFlipped(model), 50, 0.3, animGetNumFrames(ANIM_003C) - 51.0f);
|
|
modelSetAnimSpeed(model, 0.5, animGetNumFrames(ANIM_003C) - 51.0f);
|
|
return;
|
|
}
|
|
|
|
chrBeginDead(chr);
|
|
}
|
|
|
|
chrAlertOthersOfInjury(chr, true);
|
|
}
|
|
|
|
void chrTickDruggedComingUp(struct chrdata *chr)
|
|
{
|
|
u16 thuds[] = {
|
|
SFX_THUD_808D,
|
|
SFX_THUD_808E,
|
|
SFX_THUD_808F,
|
|
SFX_THUD_8090,
|
|
SFX_THUD_8091,
|
|
SFX_THUD_8092,
|
|
SFX_THUD_8093,
|
|
SFX_THUD_8094,
|
|
SFX_THUD_8095,
|
|
SFX_THUD_8096,
|
|
SFX_THUD_8097,
|
|
};
|
|
|
|
chr->act_druggedcomingup.timer60 += g_Vars.lvupdate240_60;
|
|
|
|
if (chr->act_druggedcomingup.timer60 > 0) {
|
|
struct animtablerow *row;
|
|
s32 race = CHRRACE(chr);
|
|
struct model *model = chr->model;
|
|
s32 i = 0;
|
|
bool done = false;
|
|
struct prop *weapon;
|
|
|
|
chrUncloak(chr, true);
|
|
|
|
chr->actiontype = ACT_DRUGGEDDROP;
|
|
|
|
while (!done) {
|
|
if (i >= 0
|
|
&& g_AnimTablesByRace[race][i].deathanims != NULL
|
|
&& g_AnimTablesByRace[race][i].deathanimcount > 0) {
|
|
s32 index = random() % g_AnimTablesByRace[race][i].deathanimcount;
|
|
row = &g_AnimTablesByRace[race][i].deathanims[index];
|
|
|
|
chr->act_die.thudframe1 = row->thudframe1;
|
|
chr->act_die.thudframe2 = row->thudframe2;
|
|
|
|
modelSetAnimationWithMerge(model, row->animnum, row->flip, 0, row->speed, 16, true);
|
|
|
|
if (row->endframe >= 0) {
|
|
modelSetAnimEndFrame(model, row->endframe);
|
|
}
|
|
|
|
done = true;
|
|
}
|
|
|
|
if (!done) {
|
|
i++;
|
|
|
|
if (g_AnimTablesByRace[race][i].hitpart == -1) {
|
|
done = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
weapon = chr->weapons_held[HAND_RIGHT];
|
|
|
|
if (weapon && (weapon->obj->flags & OBJFLAG_AIUNDROPPABLE) == 0) {
|
|
objSetDropped(weapon, DROPTYPE_DEFAULT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
}
|
|
|
|
weapon = chr->weapons_held[HAND_LEFT];
|
|
|
|
if (weapon && (weapon->obj->flags & OBJFLAG_AIUNDROPPABLE) == 0) {
|
|
objSetDropped(weapon, DROPTYPE_DEFAULT);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
}
|
|
|
|
chrDropConcealedItems(chr);
|
|
}
|
|
}
|
|
|
|
void chrTickDruggedDrop(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
|
|
u16 thuds[] = {
|
|
SFX_THUD_808D,
|
|
SFX_THUD_808E,
|
|
SFX_THUD_808F,
|
|
SFX_THUD_8090,
|
|
SFX_THUD_8091,
|
|
SFX_THUD_8092,
|
|
SFX_THUD_8093,
|
|
SFX_THUD_8094,
|
|
SFX_THUD_8095,
|
|
SFX_THUD_8096,
|
|
SFX_THUD_8097,
|
|
};
|
|
|
|
static s32 thudindex = 0;
|
|
|
|
// If due, play thud 1 sound
|
|
if (chr->act_die.thudframe1 >= 0 && modelGetCurAnimFrame(model) >= chr->act_die.thudframe1) {
|
|
propsnd0f0939f8(NULL, chr->prop, thuds[thudindex], -1,
|
|
-1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
|
|
thudindex++;
|
|
|
|
if (thudindex > 10) {
|
|
thudindex = 0;
|
|
}
|
|
|
|
chr->act_die.thudframe1 = -1;
|
|
}
|
|
|
|
// If due, play thud 2 sound
|
|
if (chr->act_die.thudframe2 >= 0 && modelGetCurAnimFrame(model) >= chr->act_die.thudframe2) {
|
|
propsnd0f0939f8(NULL, chr->prop, thuds[thudindex], -1,
|
|
-1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
|
|
thudindex++;
|
|
|
|
if (thudindex > 10) {
|
|
thudindex = 0;
|
|
}
|
|
|
|
chr->act_die.thudframe2 = -1;
|
|
}
|
|
|
|
// If falling animation finished, assign ACT_DRUGGEDKO
|
|
if (modelGetCurAnimFrame(model) >= modelGetAnimEndFrame(model)) {
|
|
chr->actiontype = ACT_DRUGGEDKO;
|
|
chr->act_dead.fadetimer60 = chr->aibot ? 0 : -1;
|
|
chr->act_dead.fadenow = false;
|
|
chr->act_dead.fadewheninvis = false;
|
|
chr->act_dead.invistimer60 = 0;
|
|
chr->act_dead.notifychrindex = 0;
|
|
chr->sleep = 0;
|
|
}
|
|
|
|
chrAlertOthersOfInjury(chr, true);
|
|
}
|
|
|
|
void chrTickDruggedKo(struct chrdata *chr)
|
|
{
|
|
bool reap = false;
|
|
|
|
// If fade is active, handle it
|
|
if (chr->act_dead.fadetimer60 >= 0) {
|
|
chr->act_dead.fadetimer60 += g_Vars.lvupdate240_60;
|
|
|
|
if (chr->act_dead.fadetimer60 >= TICKS(90)) {
|
|
reap = true;
|
|
} else {
|
|
chr->fadealpha = (TICKS(90) - chr->act_dead.fadetimer60) * 255 / TICKS(90);
|
|
}
|
|
} else if ((chr->chrflags & CHRCFLAG_KEEPCORPSEKO) == 0) {
|
|
if (chr->act_dead.fadenow) {
|
|
chr->act_dead.fadetimer60 = 0;
|
|
}
|
|
|
|
if (chr->prop->flags & PROPFLAG_ONANYSCREENPREVTICK) {
|
|
chr->act_dead.invistimer60 = 0;
|
|
} else {
|
|
chr->act_dead.invistimer60 += g_Vars.lvupdate240_60;
|
|
}
|
|
|
|
if (chr->act_dead.fadewheninvis && chr->act_dead.invistimer60 >= TICKS(120)) {
|
|
reap = true;
|
|
}
|
|
}
|
|
|
|
if (reap) {
|
|
chr->fadealpha = 0;
|
|
chr->hidden |= CHRHFLAG_REAPED;
|
|
chrDropItemsForOwnerReap(chr);
|
|
}
|
|
}
|
|
|
|
void chrTickArgh(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
|
|
if (modelGetCurAnimFrame(model) >= modelGetAnimEndFrame(model)) {
|
|
chrRecordLastSeeTargetTime(chr);
|
|
|
|
if (CHRRACE(chr) == RACE_HUMAN && modelGetAnimNum(model) == ANIM_DEATH_STOMACH_LONG) {
|
|
func0f02ed28(chr, 26);
|
|
} else {
|
|
if (chr->race == RACE_DRCAROLL) {
|
|
chr->drcarollimage_left = DRCAROLLIMAGE_EYESDEFAULT;
|
|
chr->drcarollimage_right = DRCAROLLIMAGE_EYESDEFAULT;
|
|
}
|
|
|
|
chrStop(chr);
|
|
}
|
|
}
|
|
|
|
chrAlertOthersOfInjury(chr, false);
|
|
}
|
|
|
|
void chrTickPreArgh(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
|
|
if (modelGetCurAnimFrame(model) >= modelGetAnimEndFrame(model)) {
|
|
struct coord dir;
|
|
dir.x = chr->act_preargh.dir.x;
|
|
dir.y = chr->act_preargh.dir.y;
|
|
dir.z = chr->act_preargh.dir.z;
|
|
|
|
chrReactToDamage(chr, &dir,
|
|
chr->act_preargh.relshotdir,
|
|
chr->act_preargh.hitpart,
|
|
&chr->act_preargh.gset,
|
|
chr->act_preargh.aplayernum);
|
|
}
|
|
}
|
|
|
|
void chrTickSidestep(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrSidestepChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
if (modelGetCurAnimFrame(model) >= modelGetAnimEndFrame(model)) {
|
|
chrRecordLastSeeTargetTime(chr);
|
|
func0f02ed28(chr, 10);
|
|
}
|
|
}
|
|
|
|
void chrTickJumpOut(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrJumpOutChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
if (modelGetCurAnimFrame(model) >= modelGetAnimEndFrame(model)) {
|
|
chrRecordLastSeeTargetTime(chr);
|
|
chrStop(chr);
|
|
}
|
|
}
|
|
|
|
void chrTickTest(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
|
|
if (modelGetCurAnimFrame(model) >= modelGetAnimEndFrame(model)) {
|
|
chrStand(chr);
|
|
}
|
|
}
|
|
|
|
void chrTickStartAlarm(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrStartAlarmChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
if (modelGetCurAnimFrame(model) >= 60) {
|
|
alarmActivate();
|
|
}
|
|
|
|
if (modelGetCurAnimFrame(model) >= modelGetAnimEndFrame(model)) {
|
|
chrStop(chr);
|
|
}
|
|
}
|
|
|
|
void chrTickSurprised(struct chrdata *chr)
|
|
{
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrSurprisedChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
if (CHRRACE(chr) == RACE_HUMAN) {
|
|
struct model *model = chr->model;
|
|
|
|
if (modelGetCurAnimFrame(model) >= modelGetAnimEndFrame(model)) {
|
|
if (modelGetAnimNum(model) == ANIM_SURRENDER_002E) {
|
|
func0f02ed28(chr, 26);
|
|
} else if (modelGetAnimNum(model) == ANIM_003F) {
|
|
func0f02ed28(chr, 26);
|
|
} else {
|
|
chrStop(chr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrCreateFireslot(struct chrdata *chr, s32 handnum, bool withsound, bool withbeam, struct coord *from, struct coord *to)
|
|
{
|
|
struct prop *weaponprop;
|
|
struct weaponobj *weapon;
|
|
s32 weaponnum;
|
|
bool playsound = false;
|
|
u8 duration;
|
|
u16 soundnum;
|
|
|
|
weaponprop = chrGetHeldProp(chr, handnum);
|
|
|
|
if (weaponprop) {
|
|
weapon = weaponprop->weapon;
|
|
weaponnum = weapon->weaponnum;
|
|
duration = gsetGetFireslotDuration(&weapon->gset);
|
|
soundnum = gsetGetSingleShootSound(&weapon->gset);
|
|
|
|
if (chr->fireslots[handnum] < 0) {
|
|
chr->fireslots[handnum] = bgunAllocateFireslot();
|
|
}
|
|
|
|
if (chr->fireslots[handnum] >= 0) {
|
|
struct fireslot *fireslot = &g_Fireslots[chr->fireslots[handnum]];
|
|
|
|
if (withsound) {
|
|
if (duration > 0) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (chr->hidden2 & CHRH2FLAG_0020)
|
|
#else
|
|
if (chr->hidden & CHRHFLAG_00000080)
|
|
#endif
|
|
{
|
|
playsound = false;
|
|
} else {
|
|
if (g_Vars.lvframe60 > fireslot->endlvframe) {
|
|
playsound = true;
|
|
} else {
|
|
playsound = false;
|
|
}
|
|
}
|
|
} else {
|
|
playsound = true;
|
|
}
|
|
}
|
|
|
|
if (playsound) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
propsnd0f0939f8(NULL, chr->prop, soundnum, -1, -1, 0x400, 4, 0x11, NULL, -1, NULL, -1, -1, -1, -1);
|
|
fireslot->endlvframe = (u32)g_Vars.lvframe60 + duration;
|
|
chr->hidden2 |= CHRH2FLAG_0020;
|
|
#else
|
|
propsnd0f0939f8(NULL, chr->prop, soundnum, -1, -1, 0x400, 4, 0, NULL, -1, NULL, -1, -1, -1, -1);
|
|
fireslot->endlvframe = (u32)g_Vars.lvframe60 + duration;
|
|
chr->hidden |= CHRHFLAG_00000080;
|
|
|
|
if (chr);
|
|
#endif
|
|
}
|
|
|
|
if (withbeam) {
|
|
beamCreate(&fireslot->beam, weaponnum, from, to);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the chr's turn angle difference to 360 degrees, in radians.
|
|
*/
|
|
f32 chrGetInverseTheta(struct chrdata *chr)
|
|
{
|
|
if (chr->aibot) {
|
|
return chr->aibot->unk0b0;
|
|
}
|
|
|
|
if (chr->model == NULL && chr->prop && chr->prop->type == PROPTYPE_PLAYER) {
|
|
struct player *player = g_Vars.players[playermgrGetPlayerNumByProp(chr->prop)];
|
|
f32 angle = (360.0f - player->vv_theta) * 0.017450513318181f;
|
|
|
|
if (angle >= M_BADTAU) {
|
|
angle -= M_BADTAU;
|
|
} else if (angle < 0) {
|
|
angle += M_BADTAU;
|
|
}
|
|
|
|
return angle;
|
|
}
|
|
|
|
return model0001ae44(chr->model);
|
|
}
|
|
|
|
void chrSetLookAngle(struct chrdata *chr, f32 angle)
|
|
{
|
|
if (chr->aibot) {
|
|
chr->aibot->unk0b0 = angle;
|
|
} else {
|
|
model0001ae90(chr->model, angle);
|
|
}
|
|
}
|
|
|
|
f32 func0f03e578(struct chrdata *chr)
|
|
{
|
|
if (chr->aibot) {
|
|
return chr->aibot->unk0a4;
|
|
}
|
|
|
|
return model0001ae44(chr->model);
|
|
}
|
|
|
|
void func0f03e5b0(struct chrdata *chr, f32 arg1)
|
|
{
|
|
if (chr->aibot) {
|
|
chr->aibot->unk0a4 = arg1;
|
|
} else {
|
|
model0001ae90(chr->model, arg1);
|
|
}
|
|
}
|
|
|
|
f32 chrGetAimAngle(struct chrdata *chr)
|
|
{
|
|
f32 angle = chrGetInverseTheta(chr) + chr->aimsideback;
|
|
f32 offset = 0;
|
|
|
|
if (angle >= M_BADTAU) {
|
|
angle -= M_BADTAU;
|
|
} else if (angle < 0) {
|
|
angle += M_BADTAU;
|
|
}
|
|
|
|
if (chr->aibot) {
|
|
if (chr->aibot->unk068) {
|
|
// empty
|
|
}
|
|
} else if (chr->actiontype == ACT_ATTACK
|
|
|| chr->actiontype == ACT_ATTACKROLL
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTAND
|
|
|| chr->actiontype == ACT_BOT_ATTACKKNEEL
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTRAFE) {
|
|
offset = chr->act_attack.animcfg->unk0c;
|
|
} else if (chr->prop->type == PROPTYPE_PLAYER) {
|
|
offset += g_Vars.players[playermgrGetPlayerNumByProp(chr->prop)]->angleoffset;
|
|
}
|
|
|
|
if (offset) {
|
|
if (chr->model->anim->flip) {
|
|
offset = M_BADTAU - offset;
|
|
}
|
|
|
|
angle += offset;
|
|
|
|
if (angle >= M_BADTAU) {
|
|
angle -= M_BADTAU;
|
|
} else if (angle < M_BADTAU) {
|
|
angle += M_BADTAU;
|
|
}
|
|
}
|
|
|
|
return angle;
|
|
}
|
|
|
|
f32 func0f03e754(struct chrdata *chr)
|
|
{
|
|
f32 sum = chr->aimuprshoulder + chr->aimupback;
|
|
|
|
if (sum < 0) {
|
|
sum += M_BADTAU;
|
|
}
|
|
|
|
return sum;
|
|
}
|
|
|
|
/**
|
|
* Turn the chr slightly towards their target.
|
|
*/
|
|
s32 chrTurn(struct chrdata *chr, s32 turning, f32 endanimframe, f32 speed, f32 toleranceangle)
|
|
{
|
|
if (turning != TURNSTATE_OFF) {
|
|
struct model *model = chr->model;
|
|
f32 curframe = modelGetCurAnimFrame(model);
|
|
u32 stack;
|
|
f32 finalangle = chrGetInverseTheta(chr);
|
|
f32 remainingangle;
|
|
f32 increment = M_BADTAU / 100.0f * speed * g_Vars.lvupdate240f * model->anim->playspeed;
|
|
|
|
if (chr->aibot) {
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
remainingangle = chrGetAngleToPos(chr, &target->pos);
|
|
} else if (chr->actiontype == ACT_ATTACK
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTAND
|
|
|| chr->actiontype == ACT_BOT_ATTACKKNEEL
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTRAFE) {
|
|
remainingangle = chrGetAttackEntityRelativeAngle(chr, chr->act_attack.flags, chr->act_attack.entityid);
|
|
} else if (chr->actiontype == ACT_STAND) {
|
|
remainingangle = chrGetAttackEntityRelativeAngle(chr, chr->act_stand.flags, chr->act_stand.entityid);
|
|
} else if (chr->actiontype == ACT_THROWGRENADE) {
|
|
remainingangle = chrGetAttackEntityRelativeAngle(chr, chr->act_throwgrenade.flags, chr->act_throwgrenade.entityid);
|
|
} else {
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
remainingangle = chrGetAngleToPos(chr, &target->pos);
|
|
}
|
|
|
|
remainingangle -= toleranceangle;
|
|
|
|
if (remainingangle < 0) {
|
|
remainingangle += M_BADTAU;
|
|
}
|
|
|
|
if (increment > remainingangle || M_BADTAU - increment < remainingangle) {
|
|
// Close enough to stop
|
|
finalangle += remainingangle;
|
|
|
|
if (finalangle >= M_BADTAU) {
|
|
finalangle -= M_BADTAU;
|
|
}
|
|
|
|
chrSetLookAngle(chr, finalangle);
|
|
turning = TURNSTATE_ONTARGET;
|
|
} else if (remainingangle < M_PI) {
|
|
// Turning in one direction
|
|
finalangle += increment;
|
|
|
|
if (finalangle >= M_BADTAU) {
|
|
finalangle -= M_BADTAU;
|
|
}
|
|
|
|
chrSetLookAngle(chr, finalangle);
|
|
} else {
|
|
// Turning in the other direction
|
|
finalangle -= increment;
|
|
|
|
if (finalangle < 0) {
|
|
finalangle += M_BADTAU;
|
|
}
|
|
|
|
chrSetLookAngle(chr, finalangle);
|
|
}
|
|
|
|
if (curframe >= endanimframe) {
|
|
turning = TURNSTATE_OFF;
|
|
}
|
|
}
|
|
|
|
return turning;
|
|
}
|
|
|
|
bool func0f03e9f4(struct chrdata *chr, struct attackanimconfig *animcfg, bool firingleft, bool firingright, f32 arg4)
|
|
{
|
|
f32 shootrotx = 0.0f;
|
|
f32 aimendsideback = 0.0f;
|
|
u32 flags = ATTACKFLAG_AIMATTARGET;
|
|
s32 entityid = 0;
|
|
bool result = true;
|
|
|
|
if (!chr->aibot) {
|
|
if (chr->actiontype == ACT_ATTACK
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTAND
|
|
|| chr->actiontype == ACT_BOT_ATTACKKNEEL
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTRAFE) {
|
|
flags = chr->act_attack.flags;
|
|
entityid = chr->act_attack.entityid;
|
|
} else if (chr->actiontype == ACT_STAND) {
|
|
flags = chr->act_stand.flags;
|
|
entityid = chr->act_stand.entityid;
|
|
}
|
|
}
|
|
|
|
if ((flags & ATTACKFLAG_AIMFORWARD) == 0) {
|
|
f32 sp178;
|
|
f32 sp174;
|
|
f32 sp170;
|
|
struct prop *chrprop = chr->prop;
|
|
struct prop *targetprop = chrGetTargetProp(chr);
|
|
f32 sqdist;
|
|
bool holdturn;
|
|
struct coord targetpos;
|
|
s16 targetrooms[8];
|
|
|
|
sp178 = targetprop->pos.x - chrprop->pos.x;
|
|
sp174 = targetprop->pos.y - chrprop->pos.y;
|
|
sp170 = targetprop->pos.z - chrprop->pos.z;
|
|
|
|
sqdist = sp178 * sp178 + sp174 * sp174 + sp170 * sp170;
|
|
|
|
if (chr->aibot) {
|
|
holdturn = false;
|
|
} else if (flags & ATTACKFLAG_AIMATTARGET) {
|
|
if (flags & ATTACKFLAG_DONTTURN) {
|
|
holdturn = true;
|
|
} else {
|
|
holdturn = chrCanSeeTarget(chr);
|
|
}
|
|
} else {
|
|
holdturn = true;
|
|
}
|
|
|
|
if ((flags & ATTACKFLAG_AIMATTARGET) && targetprop->type == PROPTYPE_PLAYER) {
|
|
f32 eyeheight = g_Vars.players[playermgrGetPlayerNumByProp(targetprop)]->vv_eyeheight;
|
|
|
|
targetpos.x = targetprop->pos.x;
|
|
targetpos.y = targetprop->pos.y;
|
|
targetpos.z = targetprop->pos.z;
|
|
|
|
if (chr->aibot) {
|
|
sp174 -= eyeheight * (0.4f + (0.05f * RANDOMFRAC() * arg4));
|
|
} else if (chr->chrflags & CHRCFLAG_LOSEXTRAHEIGHT) {
|
|
if (sqdist < 400.0f * 400.0f) {
|
|
if (chrprop->pos.y < targetpos.y - 2.0f * eyeheight) {
|
|
sp174 -= eyeheight * (0.55f + 0.1f * RANDOMFRAC() * arg4);
|
|
} else if (chrprop->pos.y > targetpos.y - eyeheight * 0.5f) {
|
|
sp174 -= eyeheight * (0.15f + 0.1f * RANDOMFRAC() * arg4);
|
|
} else {
|
|
sp174 = (RANDOMFRAC() * 0.1f * arg4 + 1.0f) * 40.0f;
|
|
}
|
|
} else {
|
|
sp174 += eyeheight * (0.025f - 0.05f * RANDOMFRAC() * arg4);
|
|
}
|
|
} else if (sqdist > 1000.0f * 1000.0f) {
|
|
if ((random() % 3) == 0) {
|
|
sp174 += eyeheight * (0.05f + 0.1f * RANDOMFRAC() * arg4);
|
|
} else {
|
|
sp174 -= eyeheight * (0.05f + 0.55f * RANDOMFRAC() * arg4);
|
|
}
|
|
} else {
|
|
if (chrprop->pos.y < targetpos.y - eyeheight) {
|
|
sp174 -= eyeheight * (0.55f + 0.1f * RANDOMFRAC() * arg4);
|
|
} else if (chrprop->pos.y > targetpos.y - eyeheight * 0.5f) {
|
|
sp174 -= eyeheight * (0.15f + 0.1f * RANDOMFRAC() * arg4);
|
|
} else {
|
|
sp174 = (RANDOMFRAC() * 0.1f * arg4 - 0.05f) * eyeheight;
|
|
}
|
|
}
|
|
} else {
|
|
struct coord chrpos;
|
|
|
|
modelGetRootPosition(chr->model, &chrpos);
|
|
chrGetAttackEntityPos(chr, flags, entityid, &targetpos, targetrooms);
|
|
|
|
sp178 = targetpos.x - chrpos.x;
|
|
sp174 = targetpos.y - chrpos.y;
|
|
sp170 = targetpos.z - chrpos.z;
|
|
}
|
|
|
|
if ((flags & ATTACKFLAG_NOVERTICAL) == 0) {
|
|
shootrotx = atan2f(sp174, sqrtf(sp178 * sp178 + sp170 * sp170));
|
|
|
|
if (shootrotx >= M_PI) {
|
|
shootrotx -= M_BADTAU;
|
|
}
|
|
}
|
|
|
|
if (holdturn) {
|
|
f32 aimangle = chrGetAimAngle(chr);
|
|
struct prop *gunprop;
|
|
struct modelnode *posnode;
|
|
struct model *gunmodel;
|
|
struct coord sp118;
|
|
s32 sp114;
|
|
struct modelnode *burstnode;
|
|
struct modelrwdata_chrinfo *chrrwdata;
|
|
Mtxf *sp108;
|
|
Mtxf spc8;
|
|
struct modelrodata_chrgunfire *burstrodata;
|
|
struct coord spb8;
|
|
Mtxf *spb4;
|
|
Mtxf *spb0;
|
|
Mtxf sp70;
|
|
Mtxf *sp6c;
|
|
struct coord sp60;
|
|
struct coord sp54;
|
|
struct coord sp48;
|
|
f32 anglev;
|
|
|
|
if (flags & ATTACKFLAG_AIMATTARGET) {
|
|
if (firingright) {
|
|
gunprop = chrGetHeldProp(chr, HAND_RIGHT);
|
|
} else {
|
|
gunprop = chrGetHeldProp(chr, HAND_LEFT);
|
|
}
|
|
|
|
if (PLAYERCOUNT() == 1
|
|
&& gunprop
|
|
&& (gunprop->flags & PROPFLAG_ONANYSCREENPREVTICK)
|
|
&& sqdist < 1000.0f * 1000.0f) {
|
|
struct defaultobj *gun = gunprop->obj;
|
|
gunmodel = gun->model;
|
|
sp114 = 0;
|
|
burstnode = modelGetPart(gunmodel->filedata, MODELPART_CHRGUN_GUNFIRE);
|
|
|
|
if (burstnode) {
|
|
sp108 = model0001a5cc(gunmodel, burstnode, 0);
|
|
burstrodata = &burstnode->rodata->chrgunfire;
|
|
spb4 = cam0f0b53a4((u8 *)sp108);
|
|
|
|
if (spb4) {
|
|
mtx00016798(sp108, &spc8);
|
|
mtx00015be0(spb4, &spc8);
|
|
|
|
spb8.x = burstrodata->pos.x;
|
|
spb8.y = burstrodata->pos.y;
|
|
spb8.z = burstrodata->pos.z;
|
|
|
|
mtx4TransformVecInPlace(&spc8, &spb8);
|
|
|
|
sp114 = 1;
|
|
sp118.x = spb8.x;
|
|
sp118.y = spb8.y;
|
|
sp118.z = spb8.z;
|
|
}
|
|
} else {
|
|
posnode = modelGetPart(gunmodel->filedata, MODELPART_CHRGUN_0001);
|
|
|
|
if (posnode) {
|
|
spb0 = model0001a5cc(gunmodel, posnode, 0);
|
|
sp6c = cam0f0b53a4((u8 *)spb0);
|
|
|
|
if (sp6c) {
|
|
mtx00016798(spb0, &sp70);
|
|
mtx00015be0(sp6c, &sp70);
|
|
|
|
sp114 = 1;
|
|
sp118.x = sp70.m[3][0];
|
|
sp118.y = sp70.m[3][1];
|
|
sp118.z = sp70.m[3][2];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (sp114) {
|
|
sp54.x = sinf(aimangle);
|
|
sp54.y = 0.0f;
|
|
sp54.z = cosf(aimangle);
|
|
|
|
sp48.x = chrprop->pos.x - sp170;
|
|
sp48.y = chrprop->pos.y;
|
|
sp48.z = chrprop->pos.z + sp178;
|
|
|
|
func0f02e3dc(&chrprop->pos, &sp48, &sp118, &sp54, &sp60);
|
|
|
|
sp178 = targetpos.x - sp60.x;
|
|
sp170 = targetpos.z - sp60.z;
|
|
}
|
|
}
|
|
}
|
|
|
|
anglev = atan2f(sp178, sp170);
|
|
aimendsideback = anglev - aimangle;
|
|
|
|
if (anglev < aimangle) {
|
|
aimendsideback += M_BADTAU;
|
|
}
|
|
|
|
chrrwdata = modelGetNodeRwData(chr->model, chr->model->filedata->rootnode);
|
|
|
|
if (chrrwdata->unk5c > 0.0f) {
|
|
aimendsideback -= chrrwdata->unk5c * chrrwdata->unk58;
|
|
|
|
if (aimendsideback < 0.0f) {
|
|
aimendsideback += M_BADTAU;
|
|
}
|
|
|
|
if (aimendsideback >= M_BADTAU) {
|
|
aimendsideback -= M_BADTAU;
|
|
}
|
|
}
|
|
|
|
if (!chr->aibot
|
|
&& (flags & ATTACKFLAG_AIMATTARGET)
|
|
&& ((flags & (ATTACKFLAG_AIMONLY | ATTACKFLAG_DONTTURN)) == 0)
|
|
&& targetprop->type == PROPTYPE_PLAYER) {
|
|
if (1);
|
|
aimendsideback += chrGetAimLimitAngle(sqdist) * 0.5f * sinf((((s32) (g_Vars.lvframe60 * chr->model->anim->playspeed) + chr->chrnum) % 60) * 0.10470308f);
|
|
|
|
if (aimendsideback < 0.0f) {
|
|
aimendsideback += M_BADTAU;
|
|
}
|
|
|
|
if (aimendsideback >= M_BADTAU) {
|
|
aimendsideback -= M_BADTAU;
|
|
}
|
|
}
|
|
|
|
if (aimendsideback >= M_PI) {
|
|
aimendsideback -= M_BADTAU;
|
|
}
|
|
|
|
aimendsideback += chr->aimsideback;
|
|
|
|
if (animcfg) {
|
|
if (chr->model->anim->flip) {
|
|
if (aimendsideback < -animcfg->unk38) {
|
|
aimendsideback = -animcfg->unk38;
|
|
result = false;
|
|
} else if (aimendsideback > -animcfg->unk3c) {
|
|
aimendsideback = -animcfg->unk3c;
|
|
result = false;
|
|
}
|
|
} else {
|
|
if (aimendsideback > animcfg->unk38) {
|
|
aimendsideback = animcfg->unk38;
|
|
result = false;
|
|
} else if (aimendsideback < animcfg->unk3c) {
|
|
aimendsideback = animcfg->unk3c;
|
|
result = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
chrCalculateAimEndProperties(chr, animcfg, firingleft, firingright, shootrotx);
|
|
|
|
chr->aimendsideback = aimendsideback;
|
|
chr->aimendcount = 10;
|
|
|
|
return result;
|
|
}
|
|
|
|
void chrCalculateAimEndProperties(struct chrdata *chr, struct attackanimconfig *animcfg, bool firingleft, bool firingright, f32 shootrotx)
|
|
{
|
|
f32 aimfreeshoulder = 0;
|
|
f32 aimendback = 0;
|
|
f32 aimgunshoulder = shootrotx;
|
|
|
|
if (animcfg != NULL) {
|
|
if (shootrotx > animcfg->unk30) {
|
|
aimendback = shootrotx - animcfg->unk30;
|
|
aimgunshoulder = animcfg->unk30;
|
|
} else if (shootrotx < animcfg->unk34) {
|
|
aimendback = shootrotx - animcfg->unk34;
|
|
aimgunshoulder = animcfg->unk34;
|
|
}
|
|
|
|
if (aimgunshoulder > 0) {
|
|
aimfreeshoulder = animcfg->unk40 * aimgunshoulder;
|
|
} else {
|
|
aimfreeshoulder = animcfg->unk44 * aimgunshoulder;
|
|
}
|
|
}
|
|
|
|
if (firingright) {
|
|
chr->aimendrshoulder = aimgunshoulder;
|
|
|
|
if (firingleft) {
|
|
chr->aimendlshoulder = aimgunshoulder;
|
|
} else {
|
|
chr->aimendlshoulder = aimfreeshoulder;
|
|
}
|
|
} else {
|
|
chr->aimendrshoulder = aimfreeshoulder;
|
|
chr->aimendlshoulder = aimgunshoulder;
|
|
}
|
|
|
|
chr->aimendback = aimendback;
|
|
}
|
|
|
|
void chrResetAimEndProperties(struct chrdata *chr)
|
|
{
|
|
chr->aimendcount = 10;
|
|
chr->aimendrshoulder = 0;
|
|
chr->aimendlshoulder = 0;
|
|
chr->aimendback = 0;
|
|
chr->aimendsideback = 0;
|
|
}
|
|
|
|
void chrSetFiring(struct chrdata *chr, s32 hand, bool firing)
|
|
{
|
|
struct prop *prop = chrGetHeldProp(chr, hand);
|
|
|
|
chr->prop->forcetick = firing ? true : false;
|
|
|
|
if (prop) {
|
|
weaponSetGunfireVisible(prop, firing, chr->prop->rooms[0]);
|
|
}
|
|
}
|
|
|
|
bool chrIsGunfireVisible(struct chrdata *chr, s32 hand)
|
|
{
|
|
struct prop *prop = chrGetHeldProp(chr, hand);
|
|
|
|
if (prop) {
|
|
return weaponIsGunfireVisible(prop);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void chrStopFiring(struct chrdata *chr)
|
|
{
|
|
u8 race = CHRRACE(chr);
|
|
|
|
if (race != RACE_DRCAROLL && race != RACE_EYESPY && chr->aibot == NULL) {
|
|
chrSetFiring(chr, HAND_RIGHT, false);
|
|
chrSetFiring(chr, HAND_LEFT, false);
|
|
|
|
chrResetAimEndProperties(chr);
|
|
|
|
chr->fireslots[0] = bgunFreeFireslot(chr->fireslots[0]);
|
|
chr->fireslots[1] = bgunFreeFireslot(chr->fireslots[1]);
|
|
}
|
|
}
|
|
|
|
void chrSetHandFiring(struct chrdata *chr, s32 hand, bool firing)
|
|
{
|
|
if (firing) {
|
|
if (hand == HAND_LEFT) {
|
|
chr->hidden |= CHRHFLAG_FIRINGLEFT;
|
|
} else {
|
|
chr->hidden |= CHRHFLAG_FIRINGRIGHT;
|
|
}
|
|
} else {
|
|
if (hand == HAND_LEFT) {
|
|
chr->hidden &= ~CHRHFLAG_FIRINGLEFT;
|
|
} else {
|
|
chr->hidden &= ~CHRHFLAG_FIRINGRIGHT;
|
|
}
|
|
}
|
|
|
|
if (!firing) {
|
|
chrSetFiring(chr, hand, false);
|
|
}
|
|
}
|
|
|
|
f32 chrGetAimLimitAngle(f32 sqdist)
|
|
{
|
|
if (sqdist > 1600 * 1600) {
|
|
return 0.018752790987492f;
|
|
}
|
|
|
|
if (sqdist > 800 * 800) {
|
|
return 0.03761787340045f;
|
|
}
|
|
|
|
if (sqdist > 400 * 400) {
|
|
return 0.07478791475296f;
|
|
}
|
|
|
|
if (sqdist > 200 * 200) {
|
|
return 0.14957582950592f;
|
|
}
|
|
|
|
return 0.2512874007225f;
|
|
}
|
|
|
|
/**
|
|
* Calculate whether a chr's shot hits their target on this tick.
|
|
*
|
|
* Each chr maintains a shotbondsum property which is a float ranging from
|
|
* 0 to 1. Each time this function is called, the value is increased slightly
|
|
* based on the chr's accuracy and other factors. Once it reaches 1, the target
|
|
* is considered to be hit and the value is reset to 0.
|
|
*
|
|
* The function writes to the angleokptr argument if the angle to their target
|
|
* is within range, and writes to the hit argument to indicate if the target is
|
|
* being hit or not.
|
|
*/
|
|
void chrCalculateHit(struct chrdata *chr, bool *angleokptr, bool *hit, struct gset *gset)
|
|
{
|
|
struct prop *prop;
|
|
struct prop *target;
|
|
f32 xdist;
|
|
f32 ydist;
|
|
f32 zdist;
|
|
f32 angletotarget;
|
|
f32 angleaiming;
|
|
f32 anglediff;
|
|
f32 limitangle;
|
|
bool angleok;
|
|
u32 stack;
|
|
f32 taperdist;
|
|
f32 sqdist;
|
|
|
|
taperdist = 300;
|
|
|
|
// Check that the chr's aim angle is within an acceptable range to their
|
|
// target.
|
|
prop = chr->prop;
|
|
target = chrGetTargetProp(chr);
|
|
|
|
xdist = target->pos.x - prop->pos.x;
|
|
ydist = target->pos.y - prop->pos.y;
|
|
zdist = target->pos.z - prop->pos.z;
|
|
|
|
angletotarget = atan2f(xdist, zdist);
|
|
angleaiming = chrGetAimAngle(chr);
|
|
anglediff = angletotarget - angleaiming;
|
|
|
|
sqdist = xdist * xdist + ydist * ydist + zdist * zdist;
|
|
limitangle = chrGetAimLimitAngle(sqdist);
|
|
|
|
if (anglediff < 0) {
|
|
anglediff += M_BADTAU;
|
|
}
|
|
|
|
angleok = anglediff < limitangle || anglediff > M_BADTAU - limitangle;
|
|
|
|
*angleokptr = angleok;
|
|
*hit = false;
|
|
|
|
// Determine the distance at which accuracy starts to taper off
|
|
switch (gset->weaponnum) {
|
|
case WEAPON_FALCON2:
|
|
case WEAPON_FALCON2_SILENCER:
|
|
case WEAPON_MAULER:
|
|
case WEAPON_PHOENIX:
|
|
case WEAPON_DY357MAGNUM:
|
|
case WEAPON_DY357LX:
|
|
case WEAPON_CMP150:
|
|
case WEAPON_CYCLONE:
|
|
case WEAPON_CALLISTO:
|
|
case WEAPON_RCP120:
|
|
case WEAPON_LAPTOPGUN:
|
|
case WEAPON_DRAGON:
|
|
case WEAPON_K7AVENGER:
|
|
case WEAPON_AR34:
|
|
case WEAPON_SUPERDRAGON:
|
|
case WEAPON_SHOTGUN:
|
|
case WEAPON_REAPER:
|
|
case WEAPON_DEVASTATOR:
|
|
case WEAPON_ROCKETLAUNCHER:
|
|
case WEAPON_SLAYER:
|
|
case WEAPON_COMBATKNIFE:
|
|
case WEAPON_CROSSBOW:
|
|
case WEAPON_TRANQUILIZER:
|
|
case WEAPON_LASER:
|
|
case WEAPON_GRENADE:
|
|
case WEAPON_NBOMB:
|
|
case WEAPON_TIMEDMINE:
|
|
case WEAPON_PROXIMITYMINE:
|
|
case WEAPON_REMOTEMINE:
|
|
case WEAPON_COMBATBOOST:
|
|
case WEAPON_PP9I:
|
|
case WEAPON_CC13:
|
|
case WEAPON_KL01313:
|
|
case WEAPON_KF7SPECIAL:
|
|
case WEAPON_ZZT:
|
|
case WEAPON_DMC:
|
|
case WEAPON_AR53:
|
|
case WEAPON_RCP45:
|
|
case WEAPON_PSYCHOSISGUN:
|
|
default:
|
|
// Use default distance (300)
|
|
break;
|
|
case WEAPON_FALCON2_SCOPE:
|
|
case WEAPON_MAGSEC4:
|
|
taperdist = 600;
|
|
break;
|
|
case WEAPON_SNIPERRIFLE:
|
|
case WEAPON_FARSIGHT:
|
|
taperdist = 1200;
|
|
break;
|
|
}
|
|
|
|
if (angleok) {
|
|
f32 dist = sqrtf(xdist * xdist + ydist * ydist + zdist * zdist);
|
|
f32 accuracy = 0.16f;
|
|
|
|
// Decrease accuracy if further than taperdist
|
|
if (dist > taperdist) {
|
|
accuracy *= taperdist / dist;
|
|
}
|
|
|
|
// Scale accuracy up or down based on chr's accuracyrating
|
|
if (chr->accuracyrating > 0) {
|
|
accuracy *= 1 + chr->accuracyrating * 0.1f;
|
|
} else if (chr->accuracyrating < 0) {
|
|
if (chr->accuracyrating <= -100) {
|
|
accuracy = 0;
|
|
} else {
|
|
accuracy *= (chr->accuracyrating + 100) * 0.01f;
|
|
}
|
|
}
|
|
|
|
// Apply PD mode enemy accuracy setting (default 1 which is no op)
|
|
if (pdmodeGetEnemyAccuracy() <= 1) {
|
|
accuracy *= pdmodeGetEnemyAccuracy();
|
|
} else {
|
|
accuracy *= 9 / (10.001f - pdmodeGetEnemyAccuracy());
|
|
}
|
|
|
|
// Apply difficulty multiplier (solo A = 0.6, SA = 0.8, PA = 1.175)
|
|
accuracy *= g_EnemyAccuracyScale;
|
|
|
|
// If the weapon fires more than once per tick, double the value to
|
|
// account for it. No weapons meet this criteria, however.
|
|
if (weaponGetNumTicksPerShot(gset->weaponnum, gset->weaponfunc) <= 0) {
|
|
accuracy += accuracy;
|
|
}
|
|
|
|
// Shotgun doubles the value due to more bullets
|
|
if (gset->weaponnum == WEAPON_SHOTGUN) {
|
|
accuracy += accuracy;
|
|
}
|
|
|
|
chr->shotbondsum += accuracy;
|
|
|
|
if (chr->hidden & CHRHFLAG_PERFECTACCURACY) {
|
|
chr->shotbondsum += 1.1f;
|
|
}
|
|
|
|
if (chr->shotbondsum >= 1) {
|
|
*hit = true;
|
|
chr->shotbondsum = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* If the chr's gun is on screen, populate gunpos with the world coordinates of
|
|
* their gun and return true.
|
|
*
|
|
* If the chr's gun is off screen, return false without populating gunpos.
|
|
*/
|
|
bool chrGetGunPos(struct chrdata *chr, s32 handnum, struct coord *gunpos)
|
|
{
|
|
struct prop *weaponprop = chrGetHeldProp(chr, handnum);
|
|
struct defaultobj *obj;
|
|
struct model *model;
|
|
bool result = false;
|
|
struct modelnode *part0;
|
|
struct modelnode *part1;
|
|
Mtxf *spac;
|
|
Mtxf sp6c;
|
|
struct modelrodata_chrgunfire *rodata;
|
|
Mtxf *sp64;
|
|
Mtxf sp24;
|
|
|
|
if (weaponprop) {
|
|
obj = weaponprop->obj;
|
|
model = obj->model;
|
|
|
|
if ((chr->prop->flags & PROPFLAG_ONTHISSCREENTHISTICK) && (weaponprop->flags & PROPFLAG_ONTHISSCREENTHISTICK)) {
|
|
if ((part0 = modelGetPart(model->filedata, MODELPART_0000))) {
|
|
spac = model0001a5cc(model, part0, 0);
|
|
rodata = &part0->rodata->chrgunfire;
|
|
|
|
gunpos->x = rodata->pos.x;
|
|
gunpos->y = rodata->pos.y;
|
|
gunpos->z = rodata->pos.z;
|
|
|
|
mtx00015be4(camGetProjectionMtxF(), spac, &sp6c);
|
|
mtx4TransformVecInPlace(&sp6c, gunpos);
|
|
result = true;
|
|
} else if ((part1 = modelGetPart(model->filedata, MODELPART_0001))) {
|
|
sp64 = model0001a5cc(model, part1, 0);
|
|
|
|
mtx00015be4(camGetProjectionMtxF(), sp64, &sp24);
|
|
|
|
gunpos->x = sp24.m[3][0];
|
|
gunpos->y = sp24.m[3][1];
|
|
gunpos->z = sp24.m[3][2];
|
|
|
|
result = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* For a shielded chr, determine which model node has been shot and populate the
|
|
* last 4 pointer arguments with information about the hit.
|
|
*
|
|
* Shield hits are calculated using the bounding box of each body part.
|
|
* This gives a bit of padding around the chr which can register as a hit.
|
|
*
|
|
* nodeptr - will be populated with a pointer to the bbox model node.
|
|
* hitpartptr - will be populated with the HITPART constant value.
|
|
* modelptr - will be populated with a pointer to the chr's model.
|
|
* sideptr - will be populated with an index in the range 0-5 which
|
|
* represents which side of the node's bounding box was hit.
|
|
*/
|
|
void chrCalculateShieldHit(struct chrdata *chr, struct coord *pos, struct coord *vector,
|
|
struct modelnode **nodeptr, s32 *hitpartptr, struct model **modelptr, s32 *sideptr)
|
|
{
|
|
u32 stack1;
|
|
struct prop *prop = chr->prop;
|
|
bool done = false;
|
|
bool isdifferentmtx;
|
|
struct coord sp124;
|
|
struct coord sp118;
|
|
s32 i;
|
|
struct modelnode *bestnode;
|
|
u32 stack2[2];
|
|
Mtxf spc8;
|
|
f32 bestvolume;
|
|
Mtxf *worldtoscreenmtx;
|
|
struct modelnode *node;
|
|
f32 x;
|
|
f32 y;
|
|
f32 z;
|
|
f32 volume;
|
|
Mtxf *mtxptr1;
|
|
Mtxf *mtxptr2;
|
|
f32 sides[6];
|
|
u32 stack3;
|
|
|
|
if (prop->type != PROPTYPE_PLAYER || g_Vars.normmplayerisrunning || chrGetShield(chr) > 0) {
|
|
if (prop->flags & (PROPFLAG_ONTHISSCREENTHISTICK | PROPFLAG_ONANYSCREENTHISTICK | PROPFLAG_ONANYSCREENPREVTICK)) {
|
|
bestnode = NULL;
|
|
bestvolume = MAXFLOAT;
|
|
worldtoscreenmtx = cam0f0b5050((u8 *)chr->model->matrices);
|
|
|
|
if (worldtoscreenmtx) {
|
|
mtx4TransformVec(worldtoscreenmtx, pos, &sp124);
|
|
mtx4RotateVec(worldtoscreenmtx, vector, &sp118);
|
|
|
|
isdifferentmtx = (camGetWorldToScreenMtxf() != worldtoscreenmtx);
|
|
node = chr->model->filedata->rootnode;
|
|
|
|
while (node) {
|
|
if ((node->type & 0xff) == MODELNODETYPE_BBOX) {
|
|
mtxptr1 = model0001a5cc(chr->model, node, 0);
|
|
|
|
if (isdifferentmtx) {
|
|
mtx00016798(mtxptr1, &spc8);
|
|
mtxptr1 = &spc8;
|
|
}
|
|
|
|
x = mtxptr1->m[3][0] - sp124.f[0];
|
|
y = mtxptr1->m[3][1] - sp124.f[1];
|
|
z = mtxptr1->m[3][2] - sp124.f[2];
|
|
|
|
volume = x * x + y * y + z * z;
|
|
|
|
if (volume < bestvolume) {
|
|
bestvolume = volume;
|
|
bestnode = node;
|
|
}
|
|
}
|
|
|
|
// Iterate all nodes recursively except headspot's chidlren
|
|
if (node->child && (node->type & 0xff) != MODELNODETYPE_HEADSPOT) {
|
|
node = node->child;
|
|
} else {
|
|
while (node) {
|
|
if (node->next) {
|
|
node = node->next;
|
|
break;
|
|
}
|
|
|
|
node = node->parent;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bestvolume);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (bestnode != NULL)
|
|
#endif
|
|
{
|
|
Mtxf sp48;
|
|
struct modelrodata_bbox *rodata = &bestnode->rodata->bbox;
|
|
|
|
*hitpartptr = rodata->hitpart;
|
|
*nodeptr = bestnode;
|
|
*modelptr = chr->model;
|
|
*sideptr = 0;
|
|
|
|
mtxptr2 = model0001a5cc(chr->model, bestnode, 0);
|
|
|
|
if (isdifferentmtx) {
|
|
mtx00016798(mtxptr2, &sp48);
|
|
mtxptr2 = &sp48;
|
|
}
|
|
|
|
bestvolume = -2;
|
|
|
|
x = (sp118.f[0] * mtxptr2->m[0][0]) + (sp118.f[1] * mtxptr2->m[0][1]) + (sp118.f[2] * mtxptr2->m[0][2]);
|
|
y = (sp118.f[0] * mtxptr2->m[1][0]) + (sp118.f[1] * mtxptr2->m[1][1]) + (sp118.f[2] * mtxptr2->m[1][2]);
|
|
z = (sp118.f[0] * mtxptr2->m[2][0]) + (sp118.f[1] * mtxptr2->m[2][1]) + (sp118.f[2] * mtxptr2->m[2][2]);
|
|
|
|
sides[0] = x;
|
|
sides[1] = -x;
|
|
sides[2] = y;
|
|
sides[3] = -y;
|
|
sides[4] = z;
|
|
sides[5] = -z;
|
|
|
|
for (i = 0; i < 6; i++) {
|
|
if (sides[i] > bestvolume) {
|
|
bestvolume = sides[i];
|
|
*sideptr = i;
|
|
}
|
|
}
|
|
|
|
done = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If no node was found above, search the model for the torso bbox
|
|
// and return that.
|
|
if (!done) {
|
|
node = chr->model->filedata->rootnode;
|
|
|
|
while (node) {
|
|
|
|
if ((node->type & 0xff) == MODELNODETYPE_BBOX) {
|
|
struct modelrodata_bbox *rodata = &node->rodata->bbox;
|
|
|
|
if (rodata->hitpart == HITPART_TORSO) {
|
|
*hitpartptr = rodata->hitpart;
|
|
*nodeptr = node;
|
|
*modelptr = chr->model;
|
|
*sideptr = 0;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (node->child) {
|
|
node = node->child;
|
|
} else {
|
|
while (node) {
|
|
if (node->next) {
|
|
node = node->next;
|
|
break;
|
|
}
|
|
|
|
node = node->parent;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Calculates the trajectory for thrown items.
|
|
*/
|
|
void chrCalculateTrajectory(struct coord *frompos, f32 arg1, struct coord *aimpos, struct coord *arg3)
|
|
{
|
|
f32 xvel;
|
|
f32 yvel;
|
|
f32 zvel;
|
|
f32 latvel;
|
|
f32 vel;
|
|
f32 sp40;
|
|
f32 sp3c;
|
|
f32 sp38;
|
|
f32 sp30;
|
|
f32 sp2c;
|
|
f32 sp24;
|
|
f32 sp28;
|
|
f32 sp20;
|
|
|
|
arg1 *= 0.59999999f;
|
|
|
|
xvel = (aimpos->x - frompos->x) * 0.01f;
|
|
yvel = (aimpos->y - frompos->y) * 0.01f;
|
|
zvel = (aimpos->z - frompos->z) * 0.01f;
|
|
|
|
vel = sqrtf(xvel * xvel + yvel * yvel + zvel * zvel);
|
|
latvel = sqrtf(xvel * xvel + zvel * zvel);
|
|
sp38 = latvel / vel;
|
|
sp40 = acosf(sp38);
|
|
|
|
if (yvel < 0) {
|
|
sp40 = -sp40;
|
|
}
|
|
|
|
sp2c = (vel * 9.81f * sp38 * sp38) / (arg1 * arg1) + yvel / vel;
|
|
|
|
if (sp2c < -1) {
|
|
sp2c = -1;
|
|
} else if (sp2c > 1) {
|
|
sp2c = 1;
|
|
}
|
|
|
|
sp3c = (asinf(sp2c) - sp40) * 0.5f + sp40;
|
|
sp28 = cosf(sp3c);
|
|
sp30 = sinf(sp3c);
|
|
|
|
arg3->x = xvel / latvel * sp28;
|
|
arg3->y = sp30;
|
|
arg3->z = zvel / latvel * sp28;
|
|
}
|
|
|
|
#if MATCHING
|
|
#if VERSION == VERSION_JPN_FINAL
|
|
GLOBAL_ASM(
|
|
glabel chrShoot
|
|
.late_rodata
|
|
glabel var7f1a90c8
|
|
.word 0x3d638e39
|
|
glabel var7f1a90cc
|
|
.word 0x481c4000
|
|
glabel var7f1a90d0
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d4
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d8
|
|
.word 0x3fd55555
|
|
glabel var7f1a90dc
|
|
.word 0x461c4000
|
|
glabel var7f1a90e0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.text
|
|
/* f0404d4: 27bdfd88 */ addiu $sp,$sp,-632
|
|
/* f0404d8: afbf0044 */ sw $ra,0x44($sp)
|
|
/* f0404dc: afa5027c */ sw $a1,0x27c($sp)
|
|
/* f0404e0: 8c8e001c */ lw $t6,0x1c($a0)
|
|
/* f0404e4: 240f0001 */ addiu $t7,$zero,0x1
|
|
/* f0404e8: a3af026e */ sb $t7,0x26e($sp)
|
|
/* f0404ec: afae0274 */ sw $t6,0x274($sp)
|
|
/* f0404f0: 8c9802d4 */ lw $t8,0x2d4($a0)
|
|
/* f0404f4: 00001025 */ or $v0,$zero,$zero
|
|
/* f0404f8: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f0404fc: 53000003 */ beqzl $t8,.L0f04050c
|
|
/* f040500: a3a2026f */ sb $v0,0x26f($sp)
|
|
/* f040504: 24020001 */ addiu $v0,$zero,0x1
|
|
/* f040508: a3a2026f */ sb $v0,0x26f($sp)
|
|
.L0f04050c:
|
|
/* f04050c: 0fc0a209 */ jal chrGetHeldProp
|
|
/* f040510: afa40278 */ sw $a0,0x278($sp)
|
|
/* f040514: 50400554 */ beqzl $v0,.L0f041a68
|
|
/* f040518: 8fbf0044 */ lw $ra,0x44($sp)
|
|
/* f04051c: afa00268 */ sw $zero,0x268($sp)
|
|
/* f040520: 8c590004 */ lw $t9,0x4($v0)
|
|
/* f040524: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040528: 0fc0a221 */ jal chrGetTargetProp
|
|
/* f04052c: afb90264 */ sw $t9,0x264($sp)
|
|
/* f040530: 8fab0264 */ lw $t3,0x264($sp)
|
|
/* f040534: afa2025c */ sw $v0,0x25c($sp)
|
|
/* f040538: 8fa70278 */ lw $a3,0x278($sp)
|
|
/* f04053c: 8961005c */ lwl $at,0x5c($t3)
|
|
/* f040540: 9961005f */ lwr $at,0x5f($t3)
|
|
/* f040544: 27aa0260 */ addiu $t2,$sp,0x260
|
|
/* f040548: 24080200 */ addiu $t0,$zero,0x200
|
|
/* f04054c: ad410000 */ sw $at,0x0($t2)
|
|
/* f040550: 80e30007 */ lb $v1,0x7($a3)
|
|
/* f040554: 24010008 */ addiu $at,$zero,0x8
|
|
/* f040558: 10610007 */ beq $v1,$at,.L0f040578
|
|
/* f04055c: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f040560: 10610005 */ beq $v1,$at,.L0f040578
|
|
/* f040564: 2401001c */ addiu $at,$zero,0x1c
|
|
/* f040568: 10610003 */ beq $v1,$at,.L0f040578
|
|
/* f04056c: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f040570: 54610003 */ bnel $v1,$at,.L0f040580
|
|
/* f040574: afa00250 */ sw $zero,0x250($sp)
|
|
.L0f040578:
|
|
/* f040578: 8ce8004c */ lw $t0,0x4c($a3)
|
|
/* f04057c: afa00250 */ sw $zero,0x250($sp)
|
|
.L0f040580:
|
|
/* f040580: afa00224 */ sw $zero,0x224($sp)
|
|
/* f040584: afa00210 */ sw $zero,0x210($sp)
|
|
/* f040588: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f04058c: 93a50263 */ lbu $a1,0x263($sp)
|
|
/* f040590: afa00254 */ sw $zero,0x254($sp)
|
|
/* f040594: 0fc2c7ba */ jal weaponGetNumTicksPerShot
|
|
/* f040598: afa80258 */ sw $t0,0x258($sp)
|
|
/* f04059c: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f0405a0: 1c400005 */ bgtz $v0,.L0f0405b8
|
|
/* f0405a4: 00402025 */ or $a0,$v0,$zero
|
|
/* f0405a8: 240f0001 */ addiu $t7,$zero,0x1
|
|
/* f0405ac: 24060001 */ addiu $a2,$zero,0x1
|
|
/* f0405b0: 10000055 */ b .L0f040708
|
|
/* f0405b4: afaf0250 */ sw $t7,0x250($sp)
|
|
.L0f0405b8:
|
|
/* f0405b8: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f0405bc: 8f0302d4 */ lw $v1,0x2d4($t8)
|
|
/* f0405c0: 5060001d */ beqzl $v1,.L0f040638
|
|
/* f0405c4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f0405c8: 8c790020 */ lw $t9,0x20($v1)
|
|
/* f0405cc: 24010014 */ addiu $at,$zero,0x14
|
|
/* f0405d0: 57210019 */ bnel $t9,$at,.L0f040638
|
|
/* f0405d4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f0405d8: 8c6d004c */ lw $t5,0x4c($v1)
|
|
/* f0405dc: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f0405e0: 000d5080 */ sll $t2,$t5,0x2
|
|
/* f0405e4: 05400013 */ bltz $t2,.L0f040634
|
|
/* f0405e8: 000b7040 */ sll $t6,$t3,0x1
|
|
/* f0405ec: 006e7821 */ addu $t7,$v1,$t6
|
|
/* f0405f0: 85f800e0 */ lh $t8,0xe0($t7)
|
|
/* f0405f4: 2419005a */ addiu $t9,$zero,0x5a
|
|
/* f0405f8: 3c017f1b */ lui $at,%hi(var7f1a90c8)
|
|
/* f0405fc: 03386823 */ subu $t5,$t9,$t8
|
|
/* f040600: 448d2000 */ mtc1 $t5,$f4
|
|
/* f040604: c42890c8 */ lwc1 $f8,%lo(var7f1a90c8)($at)
|
|
/* f040608: 44825000 */ mtc1 $v0,$f10
|
|
/* f04060c: 468021a0 */ cvt.s.w $f6,$f4
|
|
/* f040610: 3c013f80 */ lui $at,0x3f80
|
|
/* f040614: 44819000 */ mtc1 $at,$f18
|
|
/* f040618: 46805420 */ cvt.s.w $f16,$f10
|
|
/* f04061c: 46083002 */ mul.s $f0,$f6,$f8
|
|
/* f040620: 46009100 */ add.s $f4,$f18,$f0
|
|
/* f040624: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f040628: 4600320d */ trunc.w.s $f8,$f6
|
|
/* f04062c: 44044000 */ mfc1 $a0,$f8
|
|
/* f040630: 00000000 */ nop
|
|
.L0f040634:
|
|
/* f040634: 8faa0278 */ lw $t2,0x278($sp)
|
|
.L0f040638:
|
|
/* f040638: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f04063c: 3c0f800a */ lui $t7,%hi(g_Vars+0x38)
|
|
/* f040640: 8def9ff8 */ lw $t7,%lo(g_Vars+0x38)($t7)
|
|
/* f040644: 014b1821 */ addu $v1,$t2,$t3
|
|
/* f040648: 906e0004 */ lbu $t6,0x4($v1)
|
|
/* f04064c: 01cfc821 */ addu $t9,$t6,$t7
|
|
/* f040650: 333800ff */ andi $t8,$t9,0xff
|
|
/* f040654: 0304082a */ slt $at,$t8,$a0
|
|
/* f040658: 1420002b */ bnez $at,.L0f040708
|
|
/* f04065c: a0790004 */ sb $t9,0x4($v1)
|
|
/* f040660: a0600004 */ sb $zero,0x4($v1)
|
|
/* f040664: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f040668: 8fad027c */ lw $t5,0x27c($sp)
|
|
/* f04066c: 240c0001 */ addiu $t4,$zero,0x1
|
|
/* f040670: 8d4b032c */ lw $t3,0x32c($t2)
|
|
/* f040674: 01ac1004 */ sllv $v0,$t4,$t5
|
|
/* f040678: 24060001 */ addiu $a2,$zero,0x1
|
|
/* f04067c: 000b7300 */ sll $t6,$t3,0xc
|
|
/* f040680: 914b032d */ lbu $t3,0x32d($t2)
|
|
/* f040684: 000e7f82 */ srl $t7,$t6,0x1e
|
|
/* f040688: 01e2c026 */ xor $t8,$t7,$v0
|
|
/* f04068c: 00186080 */ sll $t4,$t8,0x2
|
|
/* f040690: 318d000c */ andi $t5,$t4,0xc
|
|
/* f040694: 316efff3 */ andi $t6,$t3,0xfff3
|
|
/* f040698: 01ae7825 */ or $t7,$t5,$t6
|
|
/* f04069c: a14f032d */ sb $t7,0x32d($t2)
|
|
/* f0406a0: 8d59032c */ lw $t9,0x32c($t2)
|
|
/* f0406a4: 93ad0260 */ lbu $t5,0x260($sp)
|
|
/* f0406a8: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f0406ac: 0019c300 */ sll $t8,$t9,0xc
|
|
/* f0406b0: 00186782 */ srl $t4,$t8,0x1e
|
|
/* f0406b4: 01825824 */ and $t3,$t4,$v0
|
|
/* f0406b8: 15600003 */ bnez $t3,.L0f0406c8
|
|
/* f0406bc: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f0406c0: 55a10003 */ bnel $t5,$at,.L0f0406d0
|
|
/* f0406c4: 8faf0278 */ lw $t7,0x278($sp)
|
|
.L0f0406c8:
|
|
/* f0406c8: afae0250 */ sw $t6,0x250($sp)
|
|
/* f0406cc: 8faf0278 */ lw $t7,0x278($sp)
|
|
.L0f0406d0:
|
|
/* f0406d0: 24010008 */ addiu $at,$zero,0x8
|
|
/* f0406d4: 81ea0007 */ lb $t2,0x7($t7)
|
|
/* f0406d8: 1541000b */ bne $t2,$at,.L0f040708
|
|
/* f0406dc: 00000000 */ nop
|
|
/* f0406e0: 8de40020 */ lw $a0,0x20($t7)
|
|
/* f0406e4: 0c00744f */ jal modelGetAnimNum
|
|
/* f0406e8: afa60254 */ sw $a2,0x254($sp)
|
|
/* f0406ec: 2401026a */ addiu $at,$zero,0x26a
|
|
/* f0406f0: 14410005 */ bne $v0,$at,.L0f040708
|
|
/* f0406f4: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f0406f8: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f0406fc: 83380033 */ lb $t8,0x33($t9)
|
|
/* f040700: 270c0001 */ addiu $t4,$t8,0x1
|
|
/* f040704: a32c0033 */ sb $t4,0x33($t9)
|
|
.L0f040708:
|
|
/* f040708: 50c0049b */ beqzl $a2,.L0f041978
|
|
/* f04070c: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f040710: 0fc0f97c */ jal chrGetAimAngle
|
|
/* f040714: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040718: e7a00204 */ swc1 $f0,0x204($sp)
|
|
/* f04071c: 0fc0f9d5 */ jal func0f03e754
|
|
/* f040720: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040724: 93ab026f */ lbu $t3,0x26f($sp)
|
|
/* f040728: e7a00200 */ swc1 $f0,0x200($sp)
|
|
/* f04072c: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f040730: 11600004 */ beqz $t3,.L0f040744
|
|
/* f040734: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f040738: 240d0004 */ addiu $t5,$zero,0x4
|
|
/* f04073c: 10000002 */ b .L0f040748
|
|
/* f040740: afad01fc */ sw $t5,0x1fc($sp)
|
|
.L0f040744:
|
|
/* f040744: afa001fc */ sw $zero,0x1fc($sp)
|
|
.L0f040748:
|
|
/* f040748: afae0268 */ sw $t6,0x268($sp)
|
|
/* f04074c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040750: 0fc0ff79 */ jal chrGetGunPos
|
|
/* f040754: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f040758: 54400032 */ bnezl $v0,.L0f040824
|
|
/* f04075c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040760: 8fa20274 */ lw $v0,0x274($sp)
|
|
/* f040764: 3c0141f0 */ lui $at,0x41f0
|
|
/* f040768: 44818000 */ mtc1 $at,$f16
|
|
/* f04076c: c44a0008 */ lwc1 $f10,0x8($v0)
|
|
/* f040770: 8faa027c */ lw $t2,0x27c($sp)
|
|
/* f040774: 24010001 */ addiu $at,$zero,0x1
|
|
/* f040778: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f04077c: c452000c */ lwc1 $f18,0xc($v0)
|
|
/* f040780: 46109100 */ add.s $f4,$f18,$f16
|
|
/* f040784: e7a40248 */ swc1 $f4,0x248($sp)
|
|
/* f040788: c4460010 */ lwc1 $f6,0x10($v0)
|
|
/* f04078c: 15410013 */ bne $t2,$at,.L0f0407dc
|
|
/* f040790: e7a6024c */ swc1 $f6,0x24c($sp)
|
|
/* f040794: 0c0068f4 */ jal cosf
|
|
/* f040798: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f04079c: 3c014120 */ lui $at,0x4120
|
|
/* f0407a0: 44815000 */ mtc1 $at,$f10
|
|
/* f0407a4: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f0407a8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0407ac: 460a0482 */ mul.s $f18,$f0,$f10
|
|
/* f0407b0: 46124400 */ add.s $f16,$f8,$f18
|
|
/* f0407b4: 0c0068f7 */ jal sinf
|
|
/* f0407b8: e7b00244 */ swc1 $f16,0x244($sp)
|
|
/* f0407bc: 3c014120 */ lui $at,0x4120
|
|
/* f0407c0: 44813000 */ mtc1 $at,$f6
|
|
/* f0407c4: 46000107 */ neg.s $f4,$f0
|
|
/* f0407c8: c7a8024c */ lwc1 $f8,0x24c($sp)
|
|
/* f0407cc: 46062282 */ mul.s $f10,$f4,$f6
|
|
/* f0407d0: 460a4480 */ add.s $f18,$f8,$f10
|
|
/* f0407d4: 10000012 */ b .L0f040820
|
|
/* f0407d8: e7b2024c */ swc1 $f18,0x24c($sp)
|
|
.L0f0407dc:
|
|
/* f0407dc: 0c0068f4 */ jal cosf
|
|
/* f0407e0: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0407e4: 3c014120 */ lui $at,0x4120
|
|
/* f0407e8: 44812000 */ mtc1 $at,$f4
|
|
/* f0407ec: 46000407 */ neg.s $f16,$f0
|
|
/* f0407f0: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f0407f4: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f0407f8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0407fc: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040800: 0c0068f7 */ jal sinf
|
|
/* f040804: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f040808: 3c014120 */ lui $at,0x4120
|
|
/* f04080c: 44818000 */ mtc1 $at,$f16
|
|
/* f040810: c7b2024c */ lwc1 $f18,0x24c($sp)
|
|
/* f040814: 46100102 */ mul.s $f4,$f0,$f16
|
|
/* f040818: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f04081c: e7a8024c */ swc1 $f8,0x24c($sp)
|
|
.L0f040820:
|
|
/* f040820: 8fa40278 */ lw $a0,0x278($sp)
|
|
.L0f040824:
|
|
/* f040824: 0fc079ef */ jal chrSetPerimEnabled
|
|
/* f040828: 00002825 */ or $a1,$zero,$zero
|
|
/* f04082c: 8fb801fc */ lw $t8,0x1fc($sp)
|
|
/* f040830: 8faf0274 */ lw $t7,0x274($sp)
|
|
/* f040834: 24190010 */ addiu $t9,$zero,0x10
|
|
/* f040838: 370c082a */ ori $t4,$t8,0x82a
|
|
/* f04083c: afac0010 */ sw $t4,0x10($sp)
|
|
/* f040840: afb90014 */ sw $t9,0x14($sp)
|
|
/* f040844: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f040848: 27a70234 */ addiu $a3,$sp,0x234
|
|
/* f04084c: 25e40008 */ addiu $a0,$t7,0x8
|
|
/* f040850: 0c00b78d */ jal cd0002de34
|
|
/* f040854: 25e50028 */ addiu $a1,$t7,0x28
|
|
/* f040858: 14400002 */ bnez $v0,.L0f040864
|
|
/* f04085c: 24050001 */ addiu $a1,$zero,0x1
|
|
/* f040860: afa00268 */ sw $zero,0x268($sp)
|
|
.L0f040864:
|
|
/* f040864: 0fc079ef */ jal chrSetPerimEnabled
|
|
/* f040868: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f04086c: 8fab0268 */ lw $t3,0x268($sp)
|
|
/* f040870: 240d0001 */ addiu $t5,$zero,0x1
|
|
/* f040874: 51600440 */ beqzl $t3,.L0f041978
|
|
/* f040878: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f04087c: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f040880: afa001f8 */ sw $zero,0x1f8($sp)
|
|
/* f040884: afa001f4 */ sw $zero,0x1f4($sp)
|
|
/* f040888: afad01f0 */ sw $t5,0x1f0($sp)
|
|
/* f04088c: 11c00004 */ beqz $t6,.L0f0408a0
|
|
/* f040890: afa001cc */ sw $zero,0x1cc($sp)
|
|
/* f040894: 240a083f */ addiu $t2,$zero,0x83f
|
|
/* f040898: 10000003 */ b .L0f0408a8
|
|
/* f04089c: afaa01c8 */ sw $t2,0x1c8($sp)
|
|
.L0f0408a0:
|
|
/* f0408a0: 240f083b */ addiu $t7,$zero,0x83b
|
|
/* f0408a4: afaf01c8 */ sw $t7,0x1c8($sp)
|
|
.L0f0408a8:
|
|
/* f0408a8: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f0408ac: 8ce20004 */ lw $v0,0x4($a3)
|
|
/* f0408b0: 50400004 */ beqzl $v0,.L0f0408c4
|
|
/* f0408b4: 00004825 */ or $t1,$zero,$zero
|
|
/* f0408b8: 10000002 */ b .L0f0408c4
|
|
/* f0408bc: 904902fe */ lbu $t1,0x2fe($v0)
|
|
/* f0408c0: 00004825 */ or $t1,$zero,$zero
|
|
.L0f0408c4:
|
|
/* f0408c4: 39220003 */ xori $v0,$t1,0x3
|
|
/* f0408c8: 2c420001 */ sltiu $v0,$v0,0x1
|
|
/* f0408cc: 1040000f */ beqz $v0,.L0f04090c
|
|
/* f0408d0: 00401825 */ or $v1,$v0,$zero
|
|
/* f0408d4: afa2005c */ sw $v0,0x5c($sp)
|
|
/* f0408d8: 0fc12472 */ jal chrGetDistanceToTarget
|
|
/* f0408dc: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0408e0: 3c014316 */ lui $at,0x4316
|
|
/* f0408e4: 44813000 */ mtc1 $at,$f6
|
|
/* f0408e8: 0000c025 */ or $t8,$zero,$zero
|
|
/* f0408ec: 4600303c */ c.lt.s $f6,$f0
|
|
/* f0408f0: 00000000 */ nop
|
|
/* f0408f4: 45020003 */ bc1fl .L0f040904
|
|
/* f0408f8: afb8005c */ sw $t8,0x5c($sp)
|
|
/* f0408fc: 24180001 */ addiu $t8,$zero,0x1
|
|
/* f040900: afb8005c */ sw $t8,0x5c($sp)
|
|
.L0f040904:
|
|
/* f040904: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f040908: 03001825 */ or $v1,$t8,$zero
|
|
.L0f04090c:
|
|
/* f04090c: afa301c0 */ sw $v1,0x1c0($sp)
|
|
/* f040910: 10600016 */ beqz $v1,.L0f04096c
|
|
/* f040914: afa001bc */ sw $zero,0x1bc($sp)
|
|
/* f040918: c4ea0008 */ lwc1 $f10,0x8($a3)
|
|
/* f04091c: c7b00244 */ lwc1 $f16,0x244($sp)
|
|
/* f040920: c7a80248 */ lwc1 $f8,0x248($sp)
|
|
/* f040924: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040928: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f04092c: c7b0024c */ lwc1 $f16,0x24c($sp)
|
|
/* f040930: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040934: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040938: e7b201e0 */ swc1 $f18,0x1e0($sp)
|
|
/* f04093c: c4e4000c */ lwc1 $f4,0xc($a3)
|
|
/* f040940: 46082181 */ sub.s $f6,$f4,$f8
|
|
/* f040944: e7a601e4 */ swc1 $f6,0x1e4($sp)
|
|
/* f040948: c4ea0010 */ lwc1 $f10,0x10($a3)
|
|
/* f04094c: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f040950: 0c0011e4 */ jal guNormalize
|
|
/* f040954: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
/* f040958: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f04095c: 0fc1905e */ jal propSetPerimEnabled
|
|
/* f040960: 24050001 */ addiu $a1,$zero,0x1
|
|
/* f040964: 1000002f */ b .L0f040a24
|
|
/* f040968: 8fab0278 */ lw $t3,0x278($sp)
|
|
.L0f04096c:
|
|
/* f04096c: 0c0068f4 */ jal cosf
|
|
/* f040970: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040974: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f040978: 0c0068f7 */ jal sinf
|
|
/* f04097c: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040980: c7a40060 */ lwc1 $f4,0x60($sp)
|
|
/* f040984: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040988: 46040202 */ mul.s $f8,$f0,$f4
|
|
/* f04098c: 0c0068f7 */ jal sinf
|
|
/* f040990: e7a801e0 */ swc1 $f8,0x1e0($sp)
|
|
/* f040994: e7a001e4 */ swc1 $f0,0x1e4($sp)
|
|
/* f040998: 0c0068f4 */ jal cosf
|
|
/* f04099c: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f0409a0: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f0409a4: 0c0068f4 */ jal cosf
|
|
/* f0409a8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0409ac: c7a60060 */ lwc1 $f6,0x60($sp)
|
|
/* f0409b0: 93ac026f */ lbu $t4,0x26f($sp)
|
|
/* f0409b4: 46060282 */ mul.s $f10,$f0,$f6
|
|
/* f0409b8: 11800019 */ beqz $t4,.L0f040a20
|
|
/* f0409bc: e7aa01e8 */ swc1 $f10,0x1e8($sp)
|
|
/* f0409c0: 0fc644fe */ jal botGuessCrouchPos
|
|
/* f0409c4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0409c8: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f0409cc: 00404825 */ or $t1,$v0,$zero
|
|
/* f0409d0: 8fae0278 */ lw $t6,0x278($sp)
|
|
/* f0409d4: 8f280170 */ lw $t0,0x170($t9)
|
|
/* f0409d8: 0008582b */ sltu $t3,$zero,$t0
|
|
/* f0409dc: 11600004 */ beqz $t3,.L0f0409f0
|
|
/* f0409e0: 01604025 */ or $t0,$t3,$zero
|
|
/* f0409e4: 8f280174 */ lw $t0,0x174($t9)
|
|
/* f0409e8: 0008682b */ sltu $t5,$zero,$t0
|
|
/* f0409ec: 01a04025 */ or $t0,$t5,$zero
|
|
.L0f0409f0:
|
|
/* f0409f0: 8dc302d4 */ lw $v1,0x2d4($t6)
|
|
/* f0409f4: 8fb8027c */ lw $t8,0x27c($sp)
|
|
/* f0409f8: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f0409fc: 8c66004c */ lw $a2,0x4c($v1)
|
|
/* f040a00: 00786021 */ addu $t4,$v1,$t8
|
|
/* f040a04: 9187004d */ lbu $a3,0x4d($t4)
|
|
/* f040a08: 8c650020 */ lw $a1,0x20($v1)
|
|
/* f040a0c: 00065080 */ sll $t2,$a2,0x2
|
|
/* f040a10: 000a37c2 */ srl $a2,$t2,0x1f
|
|
/* f040a14: afa80014 */ sw $t0,0x14($sp)
|
|
/* f040a18: 0fc283eb */ jal bgunCalculateBotShotSpread
|
|
/* f040a1c: afa90010 */ sw $t1,0x10($sp)
|
|
.L0f040a20:
|
|
/* f040a20: 8fab0278 */ lw $t3,0x278($sp)
|
|
.L0f040a24:
|
|
/* f040a24: 93b90260 */ lbu $t9,0x260($sp)
|
|
/* f040a28: 24010016 */ addiu $at,$zero,0x16
|
|
/* f040a2c: 8d6302d4 */ lw $v1,0x2d4($t3)
|
|
/* f040a30: 50600018 */ beqzl $v1,.L0f040a94
|
|
/* f040a34: 3c014780 */ lui $at,0x4780
|
|
/* f040a38: 57210016 */ bnel $t9,$at,.L0f040a94
|
|
/* f040a3c: 3c014780 */ lui $at,0x4780
|
|
/* f040a40: 8c6d0128 */ lw $t5,0x128($v1)
|
|
/* f040a44: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f040a48: 01602025 */ or $a0,$t3,$zero
|
|
/* f040a4c: 15a00010 */ bnez $t5,.L0f040a90
|
|
/* f040a50: 00002825 */ or $a1,$zero,$zero
|
|
/* f040a54: afae0250 */ sw $t6,0x250($sp)
|
|
/* f040a58: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f040a5c: 0fc667e1 */ jal botactShootFarsight
|
|
/* f040a60: 27a70244 */ addiu $a3,$sp,0x244
|
|
/* f040a64: 24010002 */ addiu $at,$zero,0x2
|
|
/* f040a68: 5441000a */ bnel $v0,$at,.L0f040a94
|
|
/* f040a6c: 3c014780 */ lui $at,0x4780
|
|
/* f040a70: 0c004b70 */ jal random
|
|
/* f040a74: 00000000 */ nop
|
|
/* f040a78: 240100ff */ addiu $at,$zero,0xff
|
|
/* f040a7c: 0041001b */ divu $zero,$v0,$at
|
|
/* f040a80: 00005010 */ mfhi $t2
|
|
/* f040a84: 2d4f00c9 */ sltiu $t7,$t2,0xc9
|
|
/* f040a88: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f040a8c: a3af026e */ sb $t7,0x26e($sp)
|
|
.L0f040a90:
|
|
/* f040a90: 3c014780 */ lui $at,0x4780
|
|
.L0f040a94:
|
|
/* f040a94: 44810000 */ mtc1 $at,$f0
|
|
/* f040a98: c7b001e0 */ lwc1 $f16,0x1e0($sp)
|
|
/* f040a9c: c7a40244 */ lwc1 $f4,0x244($sp)
|
|
/* f040aa0: c7a601e4 */ lwc1 $f6,0x1e4($sp)
|
|
/* f040aa4: 46008482 */ mul.s $f18,$f16,$f0
|
|
/* f040aa8: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f040aac: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040ab0: 46003282 */ mul.s $f10,$f6,$f0
|
|
/* f040ab4: c7a6024c */ lwc1 $f6,0x24c($sp)
|
|
/* f040ab8: 00002825 */ or $a1,$zero,$zero
|
|
/* f040abc: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f040ac0: c7a401e8 */ lwc1 $f4,0x1e8($sp)
|
|
/* f040ac4: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f040ac8: e7a80228 */ swc1 $f8,0x228($sp)
|
|
/* f040acc: 46002202 */ mul.s $f8,$f4,$f0
|
|
/* f040ad0: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f040ad4: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040ad8: 0fc079ef */ jal chrSetPerimEnabled
|
|
/* f040adc: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f040ae0: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040ae4: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040ae8: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f040aec: 13000004 */ beqz $t8,.L0f040b00
|
|
/* f040af0: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f040af4: 240c0001 */ addiu $t4,$zero,0x1
|
|
/* f040af8: 3c01800a */ lui $at,%hi(g_Vars+0x48c)
|
|
/* f040afc: ac2ca44c */ sw $t4,%lo(g_Vars+0x48c)($at)
|
|
.L0f040b00:
|
|
/* f040b00: 24190010 */ addiu $t9,$zero,0x10
|
|
/* f040b04: afb90010 */ sw $t9,0x10($sp)
|
|
/* f040b08: 0c00b764 */ jal cdTestAToB4
|
|
/* f040b0c: 8fa701c8 */ lw $a3,0x1c8($sp)
|
|
/* f040b10: 1440000a */ bnez $v0,.L0f040b3c
|
|
/* f040b14: 240d0001 */ addiu $t5,$zero,0x1
|
|
/* f040b18: 3c067f1b */ lui $a2,%hi(var7f1a8af4)
|
|
/* f040b1c: afad0224 */ sw $t5,0x224($sp)
|
|
/* f040b20: 24c68af4 */ addiu $a2,$a2,%lo(var7f1a8af4)
|
|
/* f040b24: 27a40228 */ addiu $a0,$sp,0x228
|
|
/* f040b28: 0c0093af */ jal cdGetPos
|
|
/* f040b2c: 24052f30 */ addiu $a1,$zero,0x2f30
|
|
/* f040b30: 0c0093ac */ jal cdGetObstacle
|
|
/* f040b34: 00000000 */ nop
|
|
/* f040b38: afa201cc */ sw $v0,0x1cc($sp)
|
|
.L0f040b3c:
|
|
/* f040b3c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040b40: 0fc079ef */ jal chrSetPerimEnabled
|
|
/* f040b44: 24050001 */ addiu $a1,$zero,0x1
|
|
/* f040b48: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f040b4c: 3c01800a */ lui $at,%hi(g_Vars+0x48c)
|
|
/* f040b50: 51c00003 */ beqzl $t6,.L0f040b60
|
|
/* f040b54: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
/* f040b58: ac20a44c */ sw $zero,%lo(g_Vars+0x48c)($at)
|
|
/* f040b5c: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
.L0f040b60:
|
|
/* f040b60: 8faa01c0 */ lw $t2,0x1c0($sp)
|
|
/* f040b64: 55600015 */ bnezl $t3,.L0f040bbc
|
|
/* f040b68: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f040b6c: 51400013 */ beqzl $t2,.L0f040bbc
|
|
/* f040b70: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f040b74: 0c004b70 */ jal random
|
|
/* f040b78: 00000000 */ nop
|
|
/* f040b7c: 24010064 */ addiu $at,$zero,0x64
|
|
/* f040b80: 0041001b */ divu $zero,$v0,$at
|
|
/* f040b84: 00001810 */ mfhi $v1
|
|
/* f040b88: 2c6f0033 */ sltiu $t7,$v1,0x33
|
|
/* f040b8c: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f040b90: 11e00009 */ beqz $t7,.L0f040bb8
|
|
/* f040b94: afaf01bc */ sw $t7,0x1bc($sp)
|
|
/* f040b98: 8fb8025c */ lw $t8,0x25c($sp)
|
|
/* f040b9c: afb801cc */ sw $t8,0x1cc($sp)
|
|
/* f040ba0: c7100008 */ lwc1 $f16,0x8($t8)
|
|
/* f040ba4: e7b00228 */ swc1 $f16,0x228($sp)
|
|
/* f040ba8: c712000c */ lwc1 $f18,0xc($t8)
|
|
/* f040bac: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f040bb0: c7040010 */ lwc1 $f4,0x10($t8)
|
|
/* f040bb4: e7a40230 */ swc1 $f4,0x230($sp)
|
|
.L0f040bb8:
|
|
/* f040bb8: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
.L0f040bbc:
|
|
/* f040bbc: c7a60244 */ lwc1 $f6,0x244($sp)
|
|
/* f040bc0: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f040bc4: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f040bc8: 46064001 */ sub.s $f0,$f8,$f6
|
|
/* f040bcc: c7b20230 */ lwc1 $f18,0x230($sp)
|
|
/* f040bd0: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f040bd4: 46105081 */ sub.s $f2,$f10,$f16
|
|
/* f040bd8: 46000202 */ mul.s $f8,$f0,$f0
|
|
/* f040bdc: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040be0: 46049301 */ sub.s $f12,$f18,$f4
|
|
/* f040be4: 46021182 */ mul.s $f6,$f2,$f2
|
|
/* f040be8: 24010018 */ addiu $at,$zero,0x18
|
|
/* f040bec: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f040bf0: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040bf4: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f040bf8: 1081000f */ beq $a0,$at,.L0f040c38
|
|
/* f040bfc: e7b201d0 */ swc1 $f18,0x1d0($sp)
|
|
/* f040c00: 24010019 */ addiu $at,$zero,0x19
|
|
/* f040c04: 1081000c */ beq $a0,$at,.L0f040c38
|
|
/* f040c08: 24010012 */ addiu $at,$zero,0x12
|
|
/* f040c0c: 14810003 */ bne $a0,$at,.L0f040c1c
|
|
/* f040c10: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f040c14: 24010001 */ addiu $at,$zero,0x1
|
|
/* f040c18: 11810007 */ beq $t4,$at,.L0f040c38
|
|
.L0f040c1c:
|
|
/* f040c1c: 24010017 */ addiu $at,$zero,0x17
|
|
/* f040c20: 10810005 */ beq $a0,$at,.L0f040c38
|
|
/* f040c24: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f040c28: 10810003 */ beq $a0,$at,.L0f040c38
|
|
/* f040c2c: 24010034 */ addiu $at,$zero,0x34
|
|
/* f040c30: 54810171 */ bnel $a0,$at,.L0f0411f8
|
|
/* f040c34: 24010006 */ addiu $at,$zero,0x6
|
|
.L0f040c38:
|
|
/* f040c38: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f040c3c: afa00250 */ sw $zero,0x250($sp)
|
|
/* f040c40: 3c017f1b */ lui $at,%hi(var7f1a90cc)
|
|
/* f040c44: 17200006 */ bnez $t9,.L0f040c60
|
|
/* f040c48: c7a801d0 */ lwc1 $f8,0x1d0($sp)
|
|
/* f040c4c: c42490cc */ lwc1 $f4,%lo(var7f1a90cc)($at)
|
|
/* f040c50: 4608203c */ c.lt.s $f4,$f8
|
|
/* f040c54: 00000000 */ nop
|
|
/* f040c58: 45020164 */ bc1fl .L0f0411ec
|
|
/* f040c5c: afa00268 */ sw $zero,0x268($sp)
|
|
.L0f040c60:
|
|
/* f040c60: 0fc2c3f4 */ jal weaponFindById
|
|
/* f040c64: 00000000 */ nop
|
|
/* f040c68: 93ad0263 */ lbu $t5,0x263($sp)
|
|
/* f040c6c: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040c70: 24010018 */ addiu $at,$zero,0x18
|
|
/* f040c74: 000d7080 */ sll $t6,$t5,0x2
|
|
/* f040c78: 004e5821 */ addu $t3,$v0,$t6
|
|
/* f040c7c: 10810006 */ beq $a0,$at,.L0f040c98
|
|
/* f040c80: 8d630014 */ lw $v1,0x14($t3)
|
|
/* f040c84: 24010034 */ addiu $at,$zero,0x34
|
|
/* f040c88: 10810003 */ beq $a0,$at,.L0f040c98
|
|
/* f040c8c: 24010019 */ addiu $at,$zero,0x19
|
|
/* f040c90: 5481000e */ bnel $a0,$at,.L0f040ccc
|
|
/* f040c94: 2401001b */ addiu $at,$zero,0x1b
|
|
.L0f040c98:
|
|
/* f040c98: 8c6a0010 */ lw $t2,0x10($v1)
|
|
/* f040c9c: 24050053 */ addiu $a1,$zero,0x53
|
|
/* f040ca0: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040ca4: 000a7840 */ sll $t7,$t2,0x1
|
|
/* f040ca8: 05e30003 */ bgezl $t7,.L0f040cb8
|
|
/* f040cac: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040cb0: 24050054 */ addiu $a1,$zero,0x54
|
|
/* f040cb4: 8c640040 */ lw $a0,0x40($v1)
|
|
.L0f040cb8:
|
|
/* f040cb8: 0fc22e20 */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040cbc: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040cc0: 1000002e */ b .L0f040d7c
|
|
/* f040cc4: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040cc8: 2401001b */ addiu $at,$zero,0x1b
|
|
.L0f040ccc:
|
|
/* f040ccc: 1481000a */ bne $a0,$at,.L0f040cf8
|
|
/* f040cd0: 24050056 */ addiu $a1,$zero,0x56
|
|
/* f040cd4: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040cd8: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040cdc: 0fc22e20 */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040ce0: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040ce4: 10400025 */ beqz $v0,.L0f040d7c
|
|
/* f040ce8: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040cec: 93b80263 */ lbu $t8,0x263($sp)
|
|
/* f040cf0: 10000022 */ b .L0f040d7c
|
|
/* f040cf4: a058005f */ sb $t8,0x5f($v0)
|
|
.L0f040cf8:
|
|
/* f040cf8: 24010017 */ addiu $at,$zero,0x17
|
|
/* f040cfc: 1481000a */ bne $a0,$at,.L0f040d28
|
|
/* f040d00: 24050055 */ addiu $a1,$zero,0x55
|
|
/* f040d04: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040d08: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040d0c: 0fc22e20 */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040d10: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040d14: 10400019 */ beqz $v0,.L0f040d7c
|
|
/* f040d18: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040d1c: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f040d20: 10000016 */ b .L0f040d7c
|
|
/* f040d24: a04c005f */ sb $t4,0x5f($v0)
|
|
.L0f040d28:
|
|
/* f040d28: 24010012 */ addiu $at,$zero,0x12
|
|
/* f040d2c: 1481000b */ bne $a0,$at,.L0f040d5c
|
|
/* f040d30: 3c0d800a */ lui $t5,%hi(g_Vars+0x284)
|
|
/* f040d34: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040d38: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040d3c: 24050055 */ addiu $a1,$zero,0x55
|
|
/* f040d40: 0fc22e20 */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040d44: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040d48: 1040000c */ beqz $v0,.L0f040d7c
|
|
/* f040d4c: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040d50: 24190002 */ addiu $t9,$zero,0x2
|
|
/* f040d54: 10000009 */ b .L0f040d7c
|
|
/* f040d58: a059005f */ sb $t9,0x5f($v0)
|
|
.L0f040d5c:
|
|
/* f040d5c: 8dada244 */ lw $t5,%lo(g_Vars+0x284)($t5)
|
|
/* f040d60: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040d64: 27a50260 */ addiu $a1,$sp,0x260
|
|
/* f040d68: 8dae00bc */ lw $t6,0xbc($t5)
|
|
/* f040d6c: 8dc60004 */ lw $a2,0x4($t6)
|
|
/* f040d70: 0fc22d96 */ jal weaponCreateProjectileFromGset
|
|
/* f040d74: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040d78: afa201b8 */ sw $v0,0x1b8($sp)
|
|
.L0f040d7c:
|
|
/* f040d7c: 1040011b */ beqz $v0,.L0f0411ec
|
|
/* f040d80: 8fab00d4 */ lw $t3,0xd4($sp)
|
|
/* f040d84: 8d6a004c */ lw $t2,0x4c($t3)
|
|
/* f040d88: 3c017f1b */ lui $at,%hi(var7f1a90d0)
|
|
/* f040d8c: c43090d0 */ lwc1 $f16,%lo(var7f1a90d0)($at)
|
|
/* f040d90: 448a3000 */ mtc1 $t2,$f6
|
|
/* f040d94: 3c014270 */ lui $at,0x4270
|
|
/* f040d98: 44812000 */ mtc1 $at,$f4
|
|
/* f040d9c: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f040da0: 3c017f1b */ lui $at,%hi(var7f1a90d4)
|
|
/* f040da4: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040da8: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040dac: 2405001e */ addiu $a1,$zero,0x1e
|
|
/* f040db0: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f040db4: c43090d4 */ lwc1 $f16,%lo(var7f1a90d4)($at)
|
|
/* f040db8: 46049203 */ div.s $f8,$f18,$f4
|
|
/* f040dbc: e7a80168 */ swc1 $f8,0x168($sp)
|
|
/* f040dc0: 8d6f0054 */ lw $t7,0x54($t3)
|
|
/* f040dc4: 448f3000 */ mtc1 $t7,$f6
|
|
/* f040dc8: 00000000 */ nop
|
|
/* f040dcc: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f040dd0: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f040dd4: 13000080 */ beqz $t8,.L0f040fd8
|
|
/* f040dd8: e7b200cc */ swc1 $f18,0xcc($sp)
|
|
/* f040ddc: 0fc1241a */ jal chrIsTargetInFov
|
|
/* f040de0: 00003025 */ or $a2,$zero,$zero
|
|
/* f040de4: 1040007c */ beqz $v0,.L0f040fd8
|
|
/* f040de8: 00000000 */ nop
|
|
/* f040dec: 93a20263 */ lbu $v0,0x263($sp)
|
|
/* f040df0: 00001825 */ or $v1,$zero,$zero
|
|
/* f040df4: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040df8: 14400025 */ bnez $v0,.L0f040e90
|
|
/* f040dfc: 24010018 */ addiu $at,$zero,0x18
|
|
/* f040e00: 10810006 */ beq $a0,$at,.L0f040e1c
|
|
/* f040e04: 8fac025c */ lw $t4,0x25c($sp)
|
|
/* f040e08: 24010034 */ addiu $at,$zero,0x34
|
|
/* f040e0c: 10810003 */ beq $a0,$at,.L0f040e1c
|
|
/* f040e10: 24010019 */ addiu $at,$zero,0x19
|
|
/* f040e14: 5481001f */ bnel $a0,$at,.L0f040e94
|
|
/* f040e18: 93a40260 */ lbu $a0,0x260($sp)
|
|
.L0f040e1c:
|
|
/* f040e1c: 91820000 */ lbu $v0,0x0($t4)
|
|
/* f040e20: 24010003 */ addiu $at,$zero,0x3
|
|
/* f040e24: 8fb9025c */ lw $t9,0x25c($sp)
|
|
/* f040e28: 10410003 */ beq $v0,$at,.L0f040e38
|
|
/* f040e2c: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040e30: 14410051 */ bne $v0,$at,.L0f040f78
|
|
/* f040e34: 00000000 */ nop
|
|
.L0f040e38:
|
|
/* f040e38: c7240008 */ lwc1 $f4,0x8($t9)
|
|
/* f040e3c: c7aa0244 */ lwc1 $f10,0x244($sp)
|
|
/* f040e40: c7b20248 */ lwc1 $f18,0x248($sp)
|
|
/* f040e44: e7a400b8 */ swc1 $f4,0xb8($sp)
|
|
/* f040e48: 8f2d0004 */ lw $t5,0x4($t9)
|
|
/* f040e4c: 460a2401 */ sub.s $f16,$f4,$f10
|
|
/* f040e50: c7aa024c */ lwc1 $f10,0x24c($sp)
|
|
/* f040e54: c5a800b4 */ lwc1 $f8,0xb4($t5)
|
|
/* f040e58: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040e5c: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040e60: e7a800bc */ swc1 $f8,0xbc($sp)
|
|
/* f040e64: c7260010 */ lwc1 $f6,0x10($t9)
|
|
/* f040e68: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f040e6c: 46124101 */ sub.s $f4,$f8,$f18
|
|
/* f040e70: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040e74: e7a600c0 */ swc1 $f6,0xc0($sp)
|
|
/* f040e78: 460a3401 */ sub.s $f16,$f6,$f10
|
|
/* f040e7c: e7a401e4 */ swc1 $f4,0x1e4($sp)
|
|
/* f040e80: 0c0011e4 */ jal guNormalize
|
|
/* f040e84: e7b001e8 */ swc1 $f16,0x1e8($sp)
|
|
/* f040e88: 1000003b */ b .L0f040f78
|
|
/* f040e8c: 24030001 */ addiu $v1,$zero,0x1
|
|
.L0f040e90:
|
|
/* f040e90: 93a40260 */ lbu $a0,0x260($sp)
|
|
.L0f040e94:
|
|
/* f040e94: 24050017 */ addiu $a1,$zero,0x17
|
|
/* f040e98: 24010012 */ addiu $at,$zero,0x12
|
|
/* f040e9c: 14a40003 */ bne $a1,$a0,.L0f040eac
|
|
/* f040ea0: 00000000 */ nop
|
|
/* f040ea4: 50400004 */ beqzl $v0,.L0f040eb8
|
|
/* f040ea8: 8fae025c */ lw $t6,0x25c($sp)
|
|
.L0f040eac:
|
|
/* f040eac: 14810017 */ bne $a0,$at,.L0f040f0c
|
|
/* f040eb0: 00000000 */ nop
|
|
/* f040eb4: 8fae025c */ lw $t6,0x25c($sp)
|
|
.L0f040eb8:
|
|
/* f040eb8: 24010003 */ addiu $at,$zero,0x3
|
|
/* f040ebc: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f040ec0: 91c20000 */ lbu $v0,0x0($t6)
|
|
/* f040ec4: 10410003 */ beq $v0,$at,.L0f040ed4
|
|
/* f040ec8: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040ecc: 1441002a */ bne $v0,$at,.L0f040f78
|
|
/* f040ed0: 00000000 */ nop
|
|
.L0f040ed4:
|
|
/* f040ed4: c5480008 */ lwc1 $f8,0x8($t2)
|
|
/* f040ed8: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040edc: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f040ee0: e7a800b8 */ swc1 $f8,0xb8($sp)
|
|
/* f040ee4: 8d4b0004 */ lw $t3,0x4($t2)
|
|
/* f040ee8: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f040eec: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f040ef0: c57200b4 */ lwc1 $f18,0xb4($t3)
|
|
/* f040ef4: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
/* f040ef8: c5440010 */ lwc1 $f4,0x10($t2)
|
|
/* f040efc: 0fc100c7 */ jal chrCalculateTrajectory
|
|
/* f040f00: e7a400c0 */ swc1 $f4,0xc0($sp)
|
|
/* f040f04: 1000001c */ b .L0f040f78
|
|
/* f040f08: 24030001 */ addiu $v1,$zero,0x1
|
|
.L0f040f0c:
|
|
/* f040f0c: 14a40002 */ bne $a1,$a0,.L0f040f18
|
|
/* f040f10: 24010001 */ addiu $at,$zero,0x1
|
|
/* f040f14: 10410003 */ beq $v0,$at,.L0f040f24
|
|
.L0f040f18:
|
|
/* f040f18: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f040f1c: 14810016 */ bne $a0,$at,.L0f040f78
|
|
/* f040f20: 00000000 */ nop
|
|
.L0f040f24:
|
|
/* f040f24: 8faf025c */ lw $t7,0x25c($sp)
|
|
/* f040f28: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040f2c: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040f30: c5e60008 */ lwc1 $f6,0x8($t7)
|
|
/* f040f34: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f040f38: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f040f3c: e7a600b8 */ swc1 $f6,0xb8($sp)
|
|
/* f040f40: c5ea000c */ lwc1 $f10,0xc($t7)
|
|
/* f040f44: e7aa00bc */ swc1 $f10,0xbc($sp)
|
|
/* f040f48: c5f00010 */ lwc1 $f16,0x10($t7)
|
|
/* f040f4c: e7b000c0 */ swc1 $f16,0xc0($sp)
|
|
/* f040f50: 91f80000 */ lbu $t8,0x0($t7)
|
|
/* f040f54: 17010005 */ bne $t8,$at,.L0f040f6c
|
|
/* f040f58: 3c0141c8 */ lui $at,0x41c8
|
|
/* f040f5c: 44814000 */ mtc1 $at,$f8
|
|
/* f040f60: 00000000 */ nop
|
|
/* f040f64: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f040f68: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
.L0f040f6c:
|
|
/* f040f6c: 0fc100c7 */ jal chrCalculateTrajectory
|
|
/* f040f70: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f040f74: 24030001 */ addiu $v1,$zero,0x1
|
|
.L0f040f78:
|
|
/* f040f78: 10600017 */ beqz $v1,.L0f040fd8
|
|
/* f040f7c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040f80: 0fc122a1 */ jal chrGetAngleToPos
|
|
/* f040f84: 27a500b8 */ addiu $a1,$sp,0xb8
|
|
/* f040f88: e7a000b4 */ swc1 $f0,0xb4($sp)
|
|
/* f040f8c: 0c0068f4 */ jal cosf
|
|
/* f040f90: 46000306 */ mov.s $f12,$f0
|
|
/* f040f94: c7ac00b4 */ lwc1 $f12,0xb4($sp)
|
|
/* f040f98: 0c0068f7 */ jal sinf
|
|
/* f040f9c: e7a000b0 */ swc1 $f0,0xb0($sp)
|
|
/* f040fa0: c7ac01e8 */ lwc1 $f12,0x1e8($sp)
|
|
/* f040fa4: c7ae00b0 */ lwc1 $f14,0xb0($sp)
|
|
/* f040fa8: c7a201e0 */ lwc1 $f2,0x1e0($sp)
|
|
/* f040fac: 460c0102 */ mul.s $f4,$f0,$f12
|
|
/* f040fb0: 00000000 */ nop
|
|
/* f040fb4: 46027182 */ mul.s $f6,$f14,$f2
|
|
/* f040fb8: 00000000 */ nop
|
|
/* f040fbc: 460c7282 */ mul.s $f10,$f14,$f12
|
|
/* f040fc0: 00000000 */ nop
|
|
/* f040fc4: 46020202 */ mul.s $f8,$f0,$f2
|
|
/* f040fc8: 46062400 */ add.s $f16,$f4,$f6
|
|
/* f040fcc: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f040fd0: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f040fd4: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
.L0f040fd8:
|
|
/* f040fd8: 0c00566c */ jal mtx4LoadIdentity
|
|
/* f040fdc: 27a40178 */ addiu $a0,$sp,0x178
|
|
/* f040fe0: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040fe4: 0c0058ba */ jal mtx4LoadXRotation
|
|
/* f040fe8: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f040fec: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040ff0: 0c0058dd */ jal mtx4LoadYRotation
|
|
/* f040ff4: 27a500dc */ addiu $a1,$sp,0xdc
|
|
/* f040ff8: 27a400dc */ addiu $a0,$sp,0xdc
|
|
/* f040ffc: 0c0056f8 */ jal mtx00015be0
|
|
/* f041000: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f041004: c7ac0168 */ lwc1 $f12,0x168($sp)
|
|
/* f041008: c7a401e0 */ lwc1 $f4,0x1e0($sp)
|
|
/* f04100c: c7b001e4 */ lwc1 $f16,0x1e4($sp)
|
|
/* f041010: c7a801e8 */ lwc1 $f8,0x1e8($sp)
|
|
/* f041014: 460c2182 */ mul.s $f6,$f4,$f12
|
|
/* f041018: c7a200cc */ lwc1 $f2,0xcc($sp)
|
|
/* f04101c: 3c01800a */ lui $at,%hi(g_Vars+0x4c)
|
|
/* f041020: 460c8282 */ mul.s $f10,$f16,$f12
|
|
/* f041024: c420a00c */ lwc1 $f0,%lo(g_Vars+0x4c)($at)
|
|
/* f041028: 8fac00d4 */ lw $t4,0xd4($sp)
|
|
/* f04102c: 460c4482 */ mul.s $f18,$f8,$f12
|
|
/* f041030: e7a6015c */ swc1 $f6,0x15c($sp)
|
|
/* f041034: 8fa401b8 */ lw $a0,0x1b8($sp)
|
|
/* f041038: 46022102 */ mul.s $f4,$f4,$f2
|
|
/* f04103c: e7aa0160 */ swc1 $f10,0x160($sp)
|
|
/* f041040: 2401ffff */ addiu $at,$zero,-1
|
|
/* f041044: 46003182 */ mul.s $f6,$f6,$f0
|
|
/* f041048: e7b20164 */ swc1 $f18,0x164($sp)
|
|
/* f04104c: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f041050: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f041054: 27a7011c */ addiu $a3,$sp,0x11c
|
|
/* f041058: 27ae016c */ addiu $t6,$sp,0x16c
|
|
/* f04105c: 27ab0178 */ addiu $t3,$sp,0x178
|
|
/* f041060: 46062100 */ add.s $f4,$f4,$f6
|
|
/* f041064: 46028182 */ mul.s $f6,$f16,$f2
|
|
/* f041068: e7a4016c */ swc1 $f4,0x16c($sp)
|
|
/* f04106c: 46005102 */ mul.s $f4,$f10,$f0
|
|
/* f041070: 46043400 */ add.s $f16,$f6,$f4
|
|
/* f041074: 46024282 */ mul.s $f10,$f8,$f2
|
|
/* f041078: 00000000 */ nop
|
|
/* f04107c: 46009182 */ mul.s $f6,$f18,$f0
|
|
/* f041080: e7b00170 */ swc1 $f16,0x170($sp)
|
|
/* f041084: 46065100 */ add.s $f4,$f10,$f6
|
|
/* f041088: e7a40174 */ swc1 $f4,0x174($sp)
|
|
/* f04108c: 8d8d0058 */ lw $t5,0x58($t4)
|
|
/* f041090: a48d0062 */ sh $t5,0x62($a0)
|
|
/* f041094: 84820062 */ lh $v0,0x62($a0)
|
|
/* f041098: 10410002 */ beq $v0,$at,.L0f0410a4
|
|
/* f04109c: 0002c880 */ sll $t9,$v0,0x2
|
|
/* f0410a0: a4990062 */ sh $t9,0x62($a0)
|
|
.L0f0410a4:
|
|
/* f0410a4: 8faa0274 */ lw $t2,0x274($sp)
|
|
/* f0410a8: afae0010 */ sw $t6,0x10($sp)
|
|
/* f0410ac: afab0014 */ sw $t3,0x14($sp)
|
|
/* f0410b0: afa5001c */ sw $a1,0x1c($sp)
|
|
/* f0410b4: 0fc27af3 */ jal bgun0f09ebcc
|
|
/* f0410b8: afaa0018 */ sw $t2,0x18($sp)
|
|
/* f0410bc: 8fa301b8 */ lw $v1,0x1b8($sp)
|
|
/* f0410c0: 8fac00d4 */ lw $t4,0xd4($sp)
|
|
/* f0410c4: 8c6f0040 */ lw $t7,0x40($v1)
|
|
/* f0410c8: 31f80080 */ andi $t8,$t7,0x80
|
|
/* f0410cc: 13000047 */ beqz $t8,.L0f0411ec
|
|
/* f0410d0: 00000000 */ nop
|
|
/* f0410d4: 8d820010 */ lw $v0,0x10($t4)
|
|
/* f0410d8: 00026800 */ sll $t5,$v0,0x0
|
|
/* f0410dc: 05a10007 */ bgez $t5,.L0f0410fc
|
|
/* f0410e0: 00025900 */ sll $t3,$v0,0x4
|
|
/* f0410e4: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f0410e8: 3c014000 */ lui $at,0x4000
|
|
/* f0410ec: 8c590000 */ lw $t9,0x0($v0)
|
|
/* f0410f0: 03217025 */ or $t6,$t9,$at
|
|
/* f0410f4: 10000007 */ b .L0f041114
|
|
/* f0410f8: ac4e0000 */ sw $t6,0x0($v0)
|
|
.L0f0410fc:
|
|
/* f0410fc: 05630006 */ bgezl $t3,.L0f041118
|
|
/* f041100: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
/* f041104: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f041108: 8c4a0000 */ lw $t2,0x0($v0)
|
|
/* f04110c: 354f0010 */ ori $t7,$t2,0x10
|
|
/* f041110: ac4f0000 */ sw $t7,0x0($v0)
|
|
.L0f041114:
|
|
/* f041114: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
.L0f041118:
|
|
/* f041118: 8c780048 */ lw $t8,0x48($v1)
|
|
/* f04111c: 241900f0 */ addiu $t9,$zero,0xf0
|
|
/* f041120: 3c017f1b */ lui $at,%hi(var7f1a90d8)
|
|
/* f041124: e7100010 */ swc1 $f16,0x10($t8)
|
|
/* f041128: 8c6c0048 */ lw $t4,0x48($v1)
|
|
/* f04112c: c7a80160 */ lwc1 $f8,0x160($sp)
|
|
/* f041130: e5880014 */ swc1 $f8,0x14($t4)
|
|
/* f041134: 8c6d0048 */ lw $t5,0x48($v1)
|
|
/* f041138: c7b20164 */ lwc1 $f18,0x164($sp)
|
|
/* f04113c: e5b20018 */ swc1 $f18,0x18($t5)
|
|
/* f041140: 8c6e0048 */ lw $t6,0x48($v1)
|
|
/* f041144: add900b4 */ sw $t9,0xb4($t6)
|
|
/* f041148: 8fab00d4 */ lw $t3,0xd4($sp)
|
|
/* f04114c: 8c6a0048 */ lw $t2,0x48($v1)
|
|
/* f041150: c56a005c */ lwc1 $f10,0x5c($t3)
|
|
/* f041154: e54a008c */ swc1 $f10,0x8c($t2)
|
|
/* f041158: 8faf00d4 */ lw $t7,0xd4($sp)
|
|
/* f04115c: c42490d8 */ lwc1 $f4,%lo(var7f1a90d8)($at)
|
|
/* f041160: 8c780048 */ lw $t8,0x48($v1)
|
|
/* f041164: c5e60050 */ lwc1 $f6,0x50($t7)
|
|
/* f041168: 46043402 */ mul.s $f16,$f6,$f4
|
|
/* f04116c: e7100098 */ swc1 $f16,0x98($t8)
|
|
/* f041170: 0fc0a221 */ jal chrGetTargetProp
|
|
/* f041174: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041178: 8fac01b8 */ lw $t4,0x1b8($sp)
|
|
/* f04117c: 3c01bf80 */ lui $at,0xbf80
|
|
/* f041180: 00002025 */ or $a0,$zero,$zero
|
|
/* f041184: 8d8d0048 */ lw $t5,0x48($t4)
|
|
/* f041188: 2407ffff */ addiu $a3,$zero,-1
|
|
/* f04118c: 240effff */ addiu $t6,$zero,-1
|
|
/* f041190: ada200e8 */ sw $v0,0xe8($t5)
|
|
/* f041194: 8fb900d4 */ lw $t9,0xd4($sp)
|
|
/* f041198: 240bffff */ addiu $t3,$zero,-1
|
|
/* f04119c: 87260060 */ lh $a2,0x60($t9)
|
|
/* f0411a0: 18c00012 */ blez $a2,.L0f0411ec
|
|
/* f0411a4: 00000000 */ nop
|
|
/* f0411a8: 8d850014 */ lw $a1,0x14($t4)
|
|
/* f0411ac: 44810000 */ mtc1 $at,$f0
|
|
/* f0411b0: afab002c */ sw $t3,0x2c($sp)
|
|
/* f0411b4: afa00028 */ sw $zero,0x28($sp)
|
|
/* f0411b8: afa00020 */ sw $zero,0x20($sp)
|
|
/* f0411bc: afa0001c */ sw $zero,0x1c($sp)
|
|
/* f0411c0: afa00018 */ sw $zero,0x18($sp)
|
|
/* f0411c4: afa00014 */ sw $zero,0x14($sp)
|
|
/* f0411c8: afae0010 */ sw $t6,0x10($sp)
|
|
/* f0411cc: e7a00024 */ swc1 $f0,0x24($sp)
|
|
/* f0411d0: e7a00030 */ swc1 $f0,0x30($sp)
|
|
/* f0411d4: e7a00034 */ swc1 $f0,0x34($sp)
|
|
/* f0411d8: 0fc24e7e */ jal propsnd0f0939f8
|
|
/* f0411dc: e7a00038 */ swc1 $f0,0x38($sp)
|
|
/* f0411e0: 10000002 */ b .L0f0411ec
|
|
/* f0411e4: 00000000 */ nop
|
|
/* f0411e8: afa00268 */ sw $zero,0x268($sp)
|
|
.L0f0411ec:
|
|
/* f0411ec: 10000019 */ b .L0f041254
|
|
/* f0411f0: a3a0026e */ sb $zero,0x26e($sp)
|
|
/* f0411f4: 24010006 */ addiu $at,$zero,0x6
|
|
.L0f0411f8:
|
|
/* f0411f8: 14810016 */ bne $a0,$at,.L0f041254
|
|
/* f0411fc: 93aa026f */ lbu $t2,0x26f($sp)
|
|
/* f041200: 11400014 */ beqz $t2,.L0f041254
|
|
/* f041204: 93af0263 */ lbu $t7,0x263($sp)
|
|
/* f041208: 24010001 */ addiu $at,$zero,0x1
|
|
/* f04120c: 15e10011 */ bne $t7,$at,.L0f041254
|
|
/* f041210: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f041214: 8fa2027c */ lw $v0,0x27c($sp)
|
|
/* f041218: 8db902d4 */ lw $t9,0x2d4($t5)
|
|
/* f04121c: 3c014120 */ lui $at,0x4120
|
|
/* f041220: 0002c080 */ sll $t8,$v0,0x2
|
|
/* f041224: 03386021 */ addu $t4,$t9,$t8
|
|
/* f041228: c58800e4 */ lwc1 $f8,0xe4($t4)
|
|
/* f04122c: 44819000 */ mtc1 $at,$f18
|
|
/* f041230: 44802000 */ mtc1 $zero,$f4
|
|
/* f041234: 46124282 */ mul.s $f10,$f8,$f18
|
|
/* f041238: 4600518d */ trunc.w.s $f6,$f10
|
|
/* f04123c: 440b3000 */ mfc1 $t3,$f6
|
|
/* f041240: 00000000 */ nop
|
|
/* f041244: a3ab0262 */ sb $t3,0x262($sp)
|
|
/* f041248: 8daa02d4 */ lw $t2,0x2d4($t5)
|
|
/* f04124c: 01587821 */ addu $t7,$t2,$t8
|
|
/* f041250: e5e400e4 */ swc1 $f4,0xe4($t7)
|
|
.L0f041254:
|
|
/* f041254: 93b8026e */ lbu $t8,0x26e($sp)
|
|
/* f041258: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f04125c: 530001c0 */ beqzl $t8,.L0f041960
|
|
/* f041260: 8fae01c0 */ lw $t6,0x1c0($sp)
|
|
/* f041264: 172000d6 */ bnez $t9,.L0f0415c0
|
|
/* f041268: 8fac0258 */ lw $t4,0x258($sp)
|
|
/* f04126c: 318e0200 */ andi $t6,$t4,0x200
|
|
/* f041270: 11c0004c */ beqz $t6,.L0f0413a4
|
|
/* f041274: 8fab025c */ lw $t3,0x25c($sp)
|
|
/* f041278: 916d0000 */ lbu $t5,0x0($t3)
|
|
/* f04127c: 24010006 */ addiu $at,$zero,0x6
|
|
/* f041280: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041284: 15a10047 */ bne $t5,$at,.L0f0413a4
|
|
/* f041288: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f04128c: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f041290: 0fc0e47b */ jal chrCanSeeAttackTarget
|
|
/* f041294: 00003825 */ or $a3,$zero,$zero
|
|
/* f041298: 10400042 */ beqz $v0,.L0f0413a4
|
|
/* f04129c: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f0412a0: 8d440004 */ lw $a0,0x4($t2)
|
|
/* f0412a4: 8fa50278 */ lw $a1,0x278($sp)
|
|
/* f0412a8: 0fc12aa3 */ jal chrCompareTeams
|
|
/* f0412ac: 24060002 */ addiu $a2,$zero,0x2
|
|
/* f0412b0: 1040003c */ beqz $v0,.L0f0413a4
|
|
/* f0412b4: 3c014170 */ lui $at,0x4170
|
|
/* f0412b8: 44817000 */ mtc1 $at,$f14
|
|
/* f0412bc: 8faf025c */ lw $t7,0x25c($sp)
|
|
/* f0412c0: c7aa01e0 */ lwc1 $f10,0x1e0($sp)
|
|
/* f0412c4: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f0412c8: c5f00008 */ lwc1 $f16,0x8($t7)
|
|
/* f0412cc: 460e5182 */ mul.s $f6,$f10,$f14
|
|
/* f0412d0: c7aa01e4 */ lwc1 $f10,0x1e4($sp)
|
|
/* f0412d4: 46088481 */ sub.s $f18,$f16,$f8
|
|
/* f0412d8: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f0412dc: c5e4000c */ lwc1 $f4,0xc($t7)
|
|
/* f0412e0: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0412e4: 27a501f8 */ addiu $a1,$sp,0x1f8
|
|
/* f0412e8: 46069001 */ sub.s $f0,$f18,$f6
|
|
/* f0412ec: 460e5482 */ mul.s $f18,$f10,$f14
|
|
/* f0412f0: c7aa01e8 */ lwc1 $f10,0x1e8($sp)
|
|
/* f0412f4: 46102201 */ sub.s $f8,$f4,$f16
|
|
/* f0412f8: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f0412fc: c5e60010 */ lwc1 $f6,0x10($t7)
|
|
/* f041300: 27a601f4 */ addiu $a2,$sp,0x1f4
|
|
/* f041304: 46124081 */ sub.s $f2,$f8,$f18
|
|
/* f041308: 460e5202 */ mul.s $f8,$f10,$f14
|
|
/* f04130c: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f041310: 46043401 */ sub.s $f16,$f6,$f4
|
|
/* f041314: 46000182 */ mul.s $f6,$f0,$f0
|
|
/* f041318: 00000000 */ nop
|
|
/* f04131c: 46021102 */ mul.s $f4,$f2,$f2
|
|
/* f041320: 46088301 */ sub.s $f12,$f16,$f8
|
|
/* f041324: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f041328: 46043280 */ add.s $f10,$f6,$f4
|
|
/* f04132c: 46105200 */ add.s $f8,$f10,$f16
|
|
/* f041330: 4612403e */ c.le.s $f8,$f18
|
|
/* f041334: 00000000 */ nop
|
|
/* f041338: 4500002b */ bc1f .L0f0413e8
|
|
/* f04133c: 00000000 */ nop
|
|
/* f041340: 0fc0feac */ jal chrCalculateHit
|
|
/* f041344: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f041348: 8fb801f4 */ lw $t8,0x1f4($sp)
|
|
/* f04134c: 8fac01f8 */ lw $t4,0x1f8($sp)
|
|
/* f041350: 8fae0278 */ lw $t6,0x278($sp)
|
|
/* f041354: 2f190001 */ sltiu $t9,$t8,0x1
|
|
/* f041358: 11800023 */ beqz $t4,.L0f0413e8
|
|
/* f04135c: afb901f0 */ sw $t9,0x1f0($sp)
|
|
/* f041360: 81c30007 */ lb $v1,0x7($t6)
|
|
/* f041364: 24010008 */ addiu $at,$zero,0x8
|
|
/* f041368: 3c0b800a */ lui $t3,%hi(g_Vars+0x8)
|
|
/* f04136c: 1061000a */ beq $v1,$at,.L0f041398
|
|
/* f041370: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f041374: 2401000a */ addiu $at,$zero,0xa
|
|
/* f041378: 10610007 */ beq $v1,$at,.L0f041398
|
|
/* f04137c: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f041380: 10610005 */ beq $v1,$at,.L0f041398
|
|
/* f041384: 2401001c */ addiu $at,$zero,0x1c
|
|
/* f041388: 10610003 */ beq $v1,$at,.L0f041398
|
|
/* f04138c: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f041390: 54610016 */ bnel $v1,$at,.L0f0413ec
|
|
/* f041394: 8fb901f4 */ lw $t9,0x1f4($sp)
|
|
.L0f041398:
|
|
/* f041398: 8d6b9fc8 */ lw $t3,%lo(g_Vars+0x8)($t3)
|
|
/* f04139c: 10000012 */ b .L0f0413e8
|
|
/* f0413a0: adab0048 */ sw $t3,0x48($t5)
|
|
.L0f0413a4:
|
|
/* f0413a4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f0413a8: 24010008 */ addiu $at,$zero,0x8
|
|
/* f0413ac: 3c0f800a */ lui $t7,%hi(g_Vars+0x8)
|
|
/* f0413b0: 81430007 */ lb $v1,0x7($t2)
|
|
/* f0413b4: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f0413b8: 10610009 */ beq $v1,$at,.L0f0413e0
|
|
/* f0413bc: 2401000a */ addiu $at,$zero,0xa
|
|
/* f0413c0: 10610007 */ beq $v1,$at,.L0f0413e0
|
|
/* f0413c4: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f0413c8: 10610005 */ beq $v1,$at,.L0f0413e0
|
|
/* f0413cc: 2401001c */ addiu $at,$zero,0x1c
|
|
/* f0413d0: 10610003 */ beq $v1,$at,.L0f0413e0
|
|
/* f0413d4: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f0413d8: 54610004 */ bnel $v1,$at,.L0f0413ec
|
|
/* f0413dc: 8fb901f4 */ lw $t9,0x1f4($sp)
|
|
.L0f0413e0:
|
|
/* f0413e0: 8def9fc8 */ lw $t7,%lo(g_Vars+0x8)($t7)
|
|
/* f0413e4: af0f0048 */ sw $t7,0x48($t8)
|
|
.L0f0413e8:
|
|
/* f0413e8: 8fb901f4 */ lw $t9,0x1f4($sp)
|
|
.L0f0413ec:
|
|
/* f0413ec: 8faa01cc */ lw $t2,0x1cc($sp)
|
|
/* f0413f0: 13200065 */ beqz $t9,.L0f041588
|
|
/* f0413f4: 00000000 */ nop
|
|
/* f0413f8: 0fc2c74a */ jal gsetGetDamage
|
|
/* f0413fc: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041400: 8fab025c */ lw $t3,0x25c($sp)
|
|
/* f041404: 240cffff */ addiu $t4,$zero,-1
|
|
/* f041408: 240e00c8 */ addiu $t6,$zero,0xc8
|
|
/* f04140c: e7a0009c */ swc1 $f0,0x9c($sp)
|
|
/* f041410: afa00098 */ sw $zero,0x98($sp)
|
|
/* f041414: afa00094 */ sw $zero,0x94($sp)
|
|
/* f041418: afac0090 */ sw $t4,0x90($sp)
|
|
/* f04141c: afae008c */ sw $t6,0x8c($sp)
|
|
/* f041420: 8d6d0004 */ lw $t5,0x4($t3)
|
|
/* f041424: afad0088 */ sw $t5,0x88($sp)
|
|
/* f041428: c5660008 */ lwc1 $f6,0x8($t3)
|
|
/* f04142c: e7a60228 */ swc1 $f6,0x228($sp)
|
|
/* f041430: c564000c */ lwc1 $f4,0xc($t3)
|
|
/* f041434: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
/* f041438: c56a0010 */ lwc1 $f10,0x10($t3)
|
|
/* f04143c: 0c004b70 */ jal random
|
|
/* f041440: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f041444: 304a0001 */ andi $t2,$v0,0x1
|
|
/* f041448: 11400012 */ beqz $t2,.L0f041494
|
|
/* f04144c: 00000000 */ nop
|
|
/* f041450: 0c004b70 */ jal random
|
|
/* f041454: 00000000 */ nop
|
|
/* f041458: 2401000a */ addiu $at,$zero,0xa
|
|
/* f04145c: 0041001b */ divu $zero,$v0,$at
|
|
/* f041460: 00007810 */ mfhi $t7
|
|
/* f041464: 25f80002 */ addiu $t8,$t7,0x2
|
|
/* f041468: 44989000 */ mtc1 $t8,$f18
|
|
/* f04146c: c7b0022c */ lwc1 $f16,0x22c($sp)
|
|
/* f041470: 07010005 */ bgez $t8,.L0f041488
|
|
/* f041474: 46809220 */ cvt.s.w $f8,$f18
|
|
/* f041478: 3c014f80 */ lui $at,0x4f80
|
|
/* f04147c: 44813000 */ mtc1 $at,$f6
|
|
/* f041480: 00000000 */ nop
|
|
/* f041484: 46064200 */ add.s $f8,$f8,$f6
|
|
.L0f041488:
|
|
/* f041488: 46088100 */ add.s $f4,$f16,$f8
|
|
/* f04148c: 10000011 */ b .L0f0414d4
|
|
/* f041490: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
.L0f041494:
|
|
/* f041494: 0c004b70 */ jal random
|
|
/* f041498: 00000000 */ nop
|
|
/* f04149c: 2401000a */ addiu $at,$zero,0xa
|
|
/* f0414a0: 0041001b */ divu $zero,$v0,$at
|
|
/* f0414a4: 0000c810 */ mfhi $t9
|
|
/* f0414a8: 272c0002 */ addiu $t4,$t9,0x2
|
|
/* f0414ac: 448c9000 */ mtc1 $t4,$f18
|
|
/* f0414b0: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f0414b4: 05810005 */ bgez $t4,.L0f0414cc
|
|
/* f0414b8: 468091a0 */ cvt.s.w $f6,$f18
|
|
/* f0414bc: 3c014f80 */ lui $at,0x4f80
|
|
/* f0414c0: 44818000 */ mtc1 $at,$f16
|
|
/* f0414c4: 00000000 */ nop
|
|
/* f0414c8: 46103180 */ add.s $f6,$f6,$f16
|
|
.L0f0414cc:
|
|
/* f0414cc: 46065201 */ sub.s $f8,$f10,$f6
|
|
/* f0414d0: e7a8022c */ swc1 $f8,0x22c($sp)
|
|
.L0f0414d4:
|
|
/* f0414d4: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f0414d8: 8fa5025c */ lw $a1,0x25c($sp)
|
|
/* f0414dc: 0fc29f66 */ jal bgunPlayPropHitSound
|
|
/* f0414e0: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f0414e4: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f0414e8: 8c8e0020 */ lw $t6,0x20($a0)
|
|
/* f0414ec: 51c00012 */ beqzl $t6,.L0f041538
|
|
/* f0414f0: 8faf0278 */ lw $t7,0x278($sp)
|
|
/* f0414f4: 0fc0cfe8 */ jal chrGetShield
|
|
/* f0414f8: 00000000 */ nop
|
|
/* f0414fc: 44802000 */ mtc1 $zero,$f4
|
|
/* f041500: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f041504: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041508: 4600203c */ c.lt.s $f4,$f0
|
|
/* f04150c: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041510: 27a70098 */ addiu $a3,$sp,0x98
|
|
/* f041514: 27ad008c */ addiu $t5,$sp,0x8c
|
|
/* f041518: 45000006 */ bc1f .L0f041534
|
|
/* f04151c: 27ab0094 */ addiu $t3,$sp,0x94
|
|
/* f041520: 27aa0090 */ addiu $t2,$sp,0x90
|
|
/* f041524: afaa0018 */ sw $t2,0x18($sp)
|
|
/* f041528: afad0010 */ sw $t5,0x10($sp)
|
|
/* f04152c: 0fc0ffcb */ jal chrCalculateShieldHit
|
|
/* f041530: afab0014 */ sw $t3,0x14($sp)
|
|
.L0f041534:
|
|
/* f041534: 8faf0278 */ lw $t7,0x278($sp)
|
|
.L0f041538:
|
|
/* f041538: 8fac025c */ lw $t4,0x25c($sp)
|
|
/* f04153c: 8fae0098 */ lw $t6,0x98($sp)
|
|
/* f041540: 8df8001c */ lw $t8,0x1c($t7)
|
|
/* f041544: 8fad0094 */ lw $t5,0x94($sp)
|
|
/* f041548: 8fab0090 */ lw $t3,0x90($sp)
|
|
/* f04154c: 241900c8 */ addiu $t9,$zero,0xc8
|
|
/* f041550: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f041554: afb90014 */ sw $t9,0x14($sp)
|
|
/* f041558: afa00028 */ sw $zero,0x28($sp)
|
|
/* f04155c: 8fa5009c */ lw $a1,0x9c($sp)
|
|
/* f041560: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041564: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f041568: afac0018 */ sw $t4,0x18($sp)
|
|
/* f04156c: afae001c */ sw $t6,0x1c($sp)
|
|
/* f041570: afb80010 */ sw $t8,0x10($sp)
|
|
/* f041574: afad0020 */ sw $t5,0x20($sp)
|
|
/* f041578: 0fc0d077 */ jal func0f0341dc
|
|
/* f04157c: afab0024 */ sw $t3,0x24($sp)
|
|
/* f041580: 10000010 */ b .L0f0415c4
|
|
/* f041584: 8faf01f0 */ lw $t7,0x1f0($sp)
|
|
.L0f041588:
|
|
/* f041588: 11400006 */ beqz $t2,.L0f0415a4
|
|
/* f04158c: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f041590: 91420000 */ lbu $v0,0x0($t2)
|
|
/* f041594: 24010003 */ addiu $at,$zero,0x3
|
|
/* f041598: 10410009 */ beq $v0,$at,.L0f0415c0
|
|
/* f04159c: 24010006 */ addiu $at,$zero,0x6
|
|
/* f0415a0: 10410007 */ beq $v0,$at,.L0f0415c0
|
|
.L0f0415a4:
|
|
/* f0415a4: 3c017f1b */ lui $at,%hi(var7f1a90dc)
|
|
/* f0415a8: c43090dc */ lwc1 $f16,%lo(var7f1a90dc)($at)
|
|
/* f0415ac: 4610903c */ c.lt.s $f18,$f16
|
|
/* f0415b0: 00000000 */ nop
|
|
/* f0415b4: 45020003 */ bc1fl .L0f0415c4
|
|
/* f0415b8: 8faf01f0 */ lw $t7,0x1f0($sp)
|
|
/* f0415bc: afa001f0 */ sw $zero,0x1f0($sp)
|
|
.L0f0415c0:
|
|
/* f0415c0: 8faf01f0 */ lw $t7,0x1f0($sp)
|
|
.L0f0415c4:
|
|
/* f0415c4: 8fb801cc */ lw $t8,0x1cc($sp)
|
|
/* f0415c8: 51e000e5 */ beqzl $t7,.L0f041960
|
|
/* f0415cc: 8fae01c0 */ lw $t6,0x1c0($sp)
|
|
/* f0415d0: 130000a2 */ beqz $t8,.L0f04185c
|
|
/* f0415d4: 8fae0224 */ lw $t6,0x224($sp)
|
|
/* f0415d8: 93020000 */ lbu $v0,0x0($t8)
|
|
/* f0415dc: 24010006 */ addiu $at,$zero,0x6
|
|
/* f0415e0: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f0415e4: 10410003 */ beq $v0,$at,.L0f0415f4
|
|
/* f0415e8: 24010003 */ addiu $at,$zero,0x3
|
|
/* f0415ec: 54410053 */ bnel $v0,$at,.L0f04173c
|
|
/* f0415f0: 24010001 */ addiu $at,$zero,0x1
|
|
.L0f0415f4:
|
|
/* f0415f4: 1720000c */ bnez $t9,.L0f041628
|
|
/* f0415f8: 8fac01bc */ lw $t4,0x1bc($sp)
|
|
/* f0415fc: 1580000a */ bnez $t4,.L0f041628
|
|
/* f041600: 8fae0278 */ lw $t6,0x278($sp)
|
|
/* f041604: 8dcd0018 */ lw $t5,0x18($t6)
|
|
/* f041608: 8faa01cc */ lw $t2,0x1cc($sp)
|
|
/* f04160c: 01c02825 */ or $a1,$t6,$zero
|
|
/* f041610: 31ab0040 */ andi $t3,$t5,0x40
|
|
/* f041614: 11600045 */ beqz $t3,.L0f04172c
|
|
/* f041618: 24060002 */ addiu $a2,$zero,0x2
|
|
/* f04161c: 0fc12aa3 */ jal chrCompareTeams
|
|
/* f041620: 8d440004 */ lw $a0,0x4($t2)
|
|
/* f041624: 10400041 */ beqz $v0,.L0f04172c
|
|
.L0f041628:
|
|
/* f041628: 240fffff */ addiu $t7,$zero,-1
|
|
/* f04162c: 241800c8 */ addiu $t8,$zero,0xc8
|
|
/* f041630: afa00084 */ sw $zero,0x84($sp)
|
|
/* f041634: afa00080 */ sw $zero,0x80($sp)
|
|
/* f041638: afaf007c */ sw $t7,0x7c($sp)
|
|
/* f04163c: afb80078 */ sw $t8,0x78($sp)
|
|
/* f041640: 0fc2c74a */ jal gsetGetDamage
|
|
/* f041644: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041648: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f04164c: e7a00074 */ swc1 $f0,0x74($sp)
|
|
/* f041650: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041654: 8cac0004 */ lw $t4,0x4($a1)
|
|
/* f041658: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f04165c: 0fc29f66 */ jal bgunPlayPropHitSound
|
|
/* f041660: afac0070 */ sw $t4,0x70($sp)
|
|
/* f041664: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041668: 8c8d0020 */ lw $t5,0x20($a0)
|
|
/* f04166c: 51a00012 */ beqzl $t5,.L0f0416b8
|
|
/* f041670: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f041674: 0fc0cfe8 */ jal chrGetShield
|
|
/* f041678: 00000000 */ nop
|
|
/* f04167c: 44805000 */ mtc1 $zero,$f10
|
|
/* f041680: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041684: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041688: 4600503c */ c.lt.s $f10,$f0
|
|
/* f04168c: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041690: 27a70084 */ addiu $a3,$sp,0x84
|
|
/* f041694: 27ab0078 */ addiu $t3,$sp,0x78
|
|
/* f041698: 45000006 */ bc1f .L0f0416b4
|
|
/* f04169c: 27aa0080 */ addiu $t2,$sp,0x80
|
|
/* f0416a0: 27ae007c */ addiu $t6,$sp,0x7c
|
|
/* f0416a4: afae0018 */ sw $t6,0x18($sp)
|
|
/* f0416a8: afab0010 */ sw $t3,0x10($sp)
|
|
/* f0416ac: 0fc0ffcb */ jal chrCalculateShieldHit
|
|
/* f0416b0: afaa0014 */ sw $t2,0x14($sp)
|
|
.L0f0416b4:
|
|
/* f0416b4: 8fb80278 */ lw $t8,0x278($sp)
|
|
.L0f0416b8:
|
|
/* f0416b8: 27af01e0 */ addiu $t7,$sp,0x1e0
|
|
/* f0416bc: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f0416c0: afaf0010 */ sw $t7,0x10($sp)
|
|
/* f0416c4: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0416c8: 8fa60078 */ lw $a2,0x78($sp)
|
|
/* f0416cc: 27a70228 */ addiu $a3,$sp,0x228
|
|
/* f0416d0: 0fc097a9 */ jal chrEmitSparks
|
|
/* f0416d4: afb80014 */ sw $t8,0x14($sp)
|
|
/* f0416d8: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f0416dc: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
/* f0416e0: 8faa0084 */ lw $t2,0x84($sp)
|
|
/* f0416e4: 8d99001c */ lw $t9,0x1c($t4)
|
|
/* f0416e8: 8fae0080 */ lw $t6,0x80($sp)
|
|
/* f0416ec: 8faf007c */ lw $t7,0x7c($sp)
|
|
/* f0416f0: 240d00c8 */ addiu $t5,$zero,0xc8
|
|
/* f0416f4: afad0014 */ sw $t5,0x14($sp)
|
|
/* f0416f8: afa00028 */ sw $zero,0x28($sp)
|
|
/* f0416fc: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041700: 8fa50074 */ lw $a1,0x74($sp)
|
|
/* f041704: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041708: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f04170c: afab0018 */ sw $t3,0x18($sp)
|
|
/* f041710: afaa001c */ sw $t2,0x1c($sp)
|
|
/* f041714: afb90010 */ sw $t9,0x10($sp)
|
|
/* f041718: afae0020 */ sw $t6,0x20($sp)
|
|
/* f04171c: 0fc0d077 */ jal func0f0341dc
|
|
/* f041720: afaf0024 */ sw $t7,0x24($sp)
|
|
/* f041724: 1000006f */ b .L0f0418e4
|
|
/* f041728: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f04172c:
|
|
/* f04172c: afa00250 */ sw $zero,0x250($sp)
|
|
/* f041730: 1000006b */ b .L0f0418e0
|
|
/* f041734: afa00268 */ sw $zero,0x268($sp)
|
|
/* f041738: 24010001 */ addiu $at,$zero,0x1
|
|
.L0f04173c:
|
|
/* f04173c: 10410005 */ beq $v0,$at,.L0f041754
|
|
/* f041740: 8fb801cc */ lw $t8,0x1cc($sp)
|
|
/* f041744: 24010004 */ addiu $at,$zero,0x4
|
|
/* f041748: 10410002 */ beq $v0,$at,.L0f041754
|
|
/* f04174c: 24010002 */ addiu $at,$zero,0x2
|
|
/* f041750: 14410063 */ bne $v0,$at,.L0f0418e0
|
|
.L0f041754:
|
|
/* f041754: 3c0d800a */ lui $t5,%hi(g_Vars+0x314)
|
|
/* f041758: 8dada2d4 */ lw $t5,%lo(g_Vars+0x314)($t5)
|
|
/* f04175c: 8f0c0004 */ lw $t4,0x4($t8)
|
|
/* f041760: 2419ffff */ addiu $t9,$zero,-1
|
|
/* f041764: afb90068 */ sw $t9,0x68($sp)
|
|
/* f041768: 11a00004 */ beqz $t5,.L0f04177c
|
|
/* f04176c: afac006c */ sw $t4,0x6c($sp)
|
|
/* f041770: 0fc633fe */ jal mpPlayerGetIndex
|
|
/* f041774: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041778: afa20068 */ sw $v0,0x68($sp)
|
|
.L0f04177c:
|
|
/* f04177c: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041780: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f041784: 0fc29f66 */ jal bgunPlayPropHitSound
|
|
/* f041788: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f04178c: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041790: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041794: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041798: 0fc1979d */ jal func0f065e74
|
|
/* f04179c: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f0417a0: 240b0001 */ addiu $t3,$zero,0x1
|
|
/* f0417a4: afab0210 */ sw $t3,0x210($sp)
|
|
/* f0417a8: 0fc4f92a */ jal chrIsUsingPaintball
|
|
/* f0417ac: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0417b0: 1040000b */ beqz $v0,.L0f0417e0
|
|
/* f0417b4: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0417b8: 240a0019 */ addiu $t2,$zero,0x19
|
|
/* f0417bc: afaa0014 */ sw $t2,0x14($sp)
|
|
/* f0417c0: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0417c4: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0417c8: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0417cc: 00003825 */ or $a3,$zero,$zero
|
|
/* f0417d0: 0fc4be7c */ jal sparksCreate
|
|
/* f0417d4: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0417d8: 10000007 */ b .L0f0417f8
|
|
/* f0417dc: 00000000 */ nop
|
|
.L0f0417e0:
|
|
/* f0417e0: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0417e4: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0417e8: 00003825 */ or $a3,$zero,$zero
|
|
/* f0417ec: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0417f0: 0fc4be7c */ jal sparksCreate
|
|
/* f0417f4: afa00014 */ sw $zero,0x14($sp)
|
|
.L0f0417f8:
|
|
/* f0417f8: 3c0e800a */ lui $t6,%hi(g_MissionConfig+0x3)
|
|
/* f0417fc: 81cfdfeb */ lb $t7,%lo(g_MissionConfig+0x3)($t6)
|
|
/* f041800: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f041804: 05e1000a */ bgez $t7,.L0f041830
|
|
/* f041808: 00000000 */ nop
|
|
/* f04180c: 930c0125 */ lbu $t4,0x125($t8)
|
|
/* f041810: 24010010 */ addiu $at,$zero,0x10
|
|
/* f041814: 8fb9006c */ lw $t9,0x6c($sp)
|
|
/* f041818: 15810005 */ bne $t4,$at,.L0f041830
|
|
/* f04181c: 00000000 */ nop
|
|
/* f041820: 8f2d000c */ lw $t5,0xc($t9)
|
|
/* f041824: 31ab0001 */ andi $t3,$t5,0x1
|
|
/* f041828: 5560002e */ bnezl $t3,.L0f0418e4
|
|
/* f04182c: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f041830:
|
|
/* f041830: 0fc2c74a */ jal gsetGetDamage
|
|
/* f041834: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041838: 8faa0068 */ lw $t2,0x68($sp)
|
|
/* f04183c: 44050000 */ mfc1 $a1,$f0
|
|
/* f041840: 8fa4006c */ lw $a0,0x6c($sp)
|
|
/* f041844: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041848: 93a70260 */ lbu $a3,0x260($sp)
|
|
/* f04184c: 0fc2149c */ jal objTakeGunfire
|
|
/* f041850: afaa0010 */ sw $t2,0x10($sp)
|
|
/* f041854: 10000023 */ b .L0f0418e4
|
|
/* f041858: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f04185c:
|
|
/* f04185c: 11c00020 */ beqz $t6,.L0f0418e0
|
|
/* f041860: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041864: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041868: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f04186c: 0fc1979d */ jal func0f065e74
|
|
/* f041870: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041874: 240f0001 */ addiu $t7,$zero,0x1
|
|
/* f041878: afaf0210 */ sw $t7,0x210($sp)
|
|
/* f04187c: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041880: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041884: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f041888: 0fc2a132 */ jal bgunPlayBgHitSound
|
|
/* f04188c: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041890: 0fc4f92a */ jal chrIsUsingPaintball
|
|
/* f041894: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041898: 1040000b */ beqz $v0,.L0f0418c8
|
|
/* f04189c: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0418a0: 24180019 */ addiu $t8,$zero,0x19
|
|
/* f0418a4: afb80014 */ sw $t8,0x14($sp)
|
|
/* f0418a8: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0418ac: 00002825 */ or $a1,$zero,$zero
|
|
/* f0418b0: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0418b4: 00003825 */ or $a3,$zero,$zero
|
|
/* f0418b8: 0fc4be7c */ jal sparksCreate
|
|
/* f0418bc: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0418c0: 10000008 */ b .L0f0418e4
|
|
/* f0418c4: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f0418c8:
|
|
/* f0418c8: 00002825 */ or $a1,$zero,$zero
|
|
/* f0418cc: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0418d0: 00003825 */ or $a3,$zero,$zero
|
|
/* f0418d4: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0418d8: 0fc4be7c */ jal sparksCreate
|
|
/* f0418dc: afa00014 */ sw $zero,0x14($sp)
|
|
.L0f0418e0:
|
|
/* f0418e0: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f0418e4:
|
|
/* f0418e4: 24010007 */ addiu $at,$zero,0x7
|
|
/* f0418e8: 93b90263 */ lbu $t9,0x263($sp)
|
|
/* f0418ec: 1581001b */ bne $t4,$at,.L0f04195c
|
|
/* f0418f0: 24010001 */ addiu $at,$zero,0x1
|
|
/* f0418f4: 17210019 */ bne $t9,$at,.L0f04195c
|
|
/* f0418f8: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f0418fc: 8dab02d4 */ lw $t3,0x2d4($t5)
|
|
/* f041900: 3c03800a */ lui $v1,%hi(g_Vars+0x28c)
|
|
/* f041904: 11600005 */ beqz $t3,.L0f04191c
|
|
/* f041908: 00000000 */ nop
|
|
/* f04190c: 0fc633fe */ jal mpPlayerGetIndex
|
|
/* f041910: 01a02025 */ or $a0,$t5,$zero
|
|
/* f041914: 10000002 */ b .L0f041920
|
|
/* f041918: 00401825 */ or $v1,$v0,$zero
|
|
.L0f04191c:
|
|
/* f04191c: 8c63a24c */ lw $v1,%lo(g_Vars+0x28c)($v1)
|
|
.L0f041920:
|
|
/* f041920: 8faa0210 */ lw $t2,0x210($sp)
|
|
/* f041924: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041928: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f04192c: 15400005 */ bnez $t2,.L0f041944
|
|
/* f041930: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041934: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041938: 0fc1979d */ jal func0f065e74
|
|
/* f04193c: afa30064 */ sw $v1,0x64($sp)
|
|
/* f041940: 8fa30064 */ lw $v1,0x64($sp)
|
|
.L0f041944:
|
|
/* f041944: 00002025 */ or $a0,$zero,$zero
|
|
/* f041948: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f04194c: 27a60214 */ addiu $a2,$sp,0x214
|
|
/* f041950: 24070016 */ addiu $a3,$zero,0x16
|
|
/* f041954: 0fc4a640 */ jal explosionCreateSimple
|
|
/* f041958: afa30010 */ sw $v1,0x10($sp)
|
|
.L0f04195c:
|
|
/* f04195c: 8fae01c0 */ lw $t6,0x1c0($sp)
|
|
.L0f041960:
|
|
/* f041960: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f041964: 51c00004 */ beqzl $t6,.L0f041978
|
|
/* f041968: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f04196c: 0fc1905e */ jal propSetPerimEnabled
|
|
/* f041970: 00002825 */ or $a1,$zero,$zero
|
|
/* f041974: 8fa80268 */ lw $t0,0x268($sp)
|
|
.L0f041978:
|
|
/* f041978: 8fb80250 */ lw $t8,0x250($sp)
|
|
/* f04197c: 93ac0260 */ lbu $t4,0x260($sp)
|
|
/* f041980: 0008782b */ sltu $t7,$zero,$t0
|
|
/* f041984: 1300000e */ beqz $t8,.L0f0419c0
|
|
/* f041988: 01e04025 */ or $t0,$t7,$zero
|
|
/* f04198c: 2599fffe */ addiu $t9,$t4,-2
|
|
/* f041990: 2f21002a */ sltiu $at,$t9,0x2a
|
|
/* f041994: 10200009 */ beqz $at,.L0f0419bc
|
|
/* f041998: 0019c880 */ sll $t9,$t9,0x2
|
|
/* f04199c: 3c017f1b */ lui $at,%hi(var7f1a90e0)
|
|
/* f0419a0: 00390821 */ addu $at,$at,$t9
|
|
/* f0419a4: 8c3990e0 */ lw $t9,%lo(var7f1a90e0)($at)
|
|
/* f0419a8: 03200008 */ jr $t9
|
|
/* f0419ac: 00000000 */ nop
|
|
/* f0419b0: 240b0001 */ addiu $t3,$zero,0x1
|
|
/* f0419b4: 10000002 */ b .L0f0419c0
|
|
/* f0419b8: afab0250 */ sw $t3,0x250($sp)
|
|
.L0f0419bc:
|
|
/* f0419bc: afa00250 */ sw $zero,0x250($sp)
|
|
.L0f0419c0:
|
|
/* f0419c0: 11000004 */ beqz $t0,.L0f0419d4
|
|
/* f0419c4: 01003825 */ or $a3,$t0,$zero
|
|
/* f0419c8: 8fa70250 */ lw $a3,0x250($sp)
|
|
/* f0419cc: 0007682b */ sltu $t5,$zero,$a3
|
|
/* f0419d0: 01a03825 */ or $a3,$t5,$zero
|
|
.L0f0419d4:
|
|
/* f0419d4: 27aa0244 */ addiu $t2,$sp,0x244
|
|
/* f0419d8: 27ae0228 */ addiu $t6,$sp,0x228
|
|
/* f0419dc: afae0014 */ sw $t6,0x14($sp)
|
|
/* f0419e0: afaa0010 */ sw $t2,0x10($sp)
|
|
/* f0419e4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0419e8: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f0419ec: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f0419f0: 0fc0f8a7 */ jal chrCreateFireslot
|
|
/* f0419f4: afa80054 */ sw $t0,0x54($sp)
|
|
/* f0419f8: 93af026f */ lbu $t7,0x26f($sp)
|
|
/* f0419fc: 8fa80054 */ lw $t0,0x54($sp)
|
|
/* f041a00: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041a04: 11e00015 */ beqz $t7,.L0f041a5c
|
|
/* f041a08: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041a0c: 1100000a */ beqz $t0,.L0f041a38
|
|
/* f041a10: 01003025 */ or $a2,$t0,$zero
|
|
/* f041a14: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f041a18: 8fb9027c */ lw $t9,0x27c($sp)
|
|
/* f041a1c: 8f0c02d4 */ lw $t4,0x2d4($t8)
|
|
/* f041a20: 00195880 */ sll $t3,$t9,0x2
|
|
/* f041a24: 018b1021 */ addu $v0,$t4,$t3
|
|
/* f041a28: 8c430024 */ lw $v1,0x24($v0)
|
|
/* f041a2c: 18600002 */ blez $v1,.L0f041a38
|
|
/* f041a30: 246dffff */ addiu $t5,$v1,-1
|
|
/* f041a34: ac4d0024 */ sw $t5,0x24($v0)
|
|
.L0f041a38:
|
|
/* f041a38: 11000004 */ beqz $t0,.L0f041a4c
|
|
/* f041a3c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041a40: 93a6026e */ lbu $a2,0x26e($sp)
|
|
/* f041a44: 0006502b */ sltu $t2,$zero,$a2
|
|
/* f041a48: 01403025 */ or $a2,$t2,$zero
|
|
.L0f041a4c:
|
|
/* f041a4c: 0fc0fe12 */ jal chrSetFiring
|
|
/* f041a50: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041a54: 10000004 */ b .L0f041a68
|
|
/* f041a58: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.L0f041a5c:
|
|
/* f041a5c: 0fc0fe12 */ jal chrSetFiring
|
|
/* f041a60: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f041a64: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.L0f041a68:
|
|
/* f041a68: 27bd0278 */ addiu $sp,$sp,0x278
|
|
/* f041a6c: 03e00008 */ jr $ra
|
|
/* f041a70: 00000000 */ nop
|
|
);
|
|
#elif VERSION == VERSION_PAL_FINAL
|
|
GLOBAL_ASM(
|
|
glabel chrShoot
|
|
.late_rodata
|
|
glabel var7f1a90c8
|
|
.word 0x3d888889
|
|
glabel var7f1a90cc
|
|
.word 0x481c4000
|
|
glabel var7f1a90d0
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d4
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d8
|
|
.word 0x3fd55555
|
|
glabel var7f1a90dc
|
|
.word 0x461c4000
|
|
glabel var7f1a90e0
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90e4
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90e8
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90ec
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90f0
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90f4
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90f8
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90fc
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9100
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9104
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9108
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a910c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9110
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9114
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9118
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a911c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9120
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9124
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9128
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a912c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9130
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9134
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9138
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a913c
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9140
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9144
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9148
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a914c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9150
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9154
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9158
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a915c
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9160
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9164
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9168
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a916c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9170
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9174
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9178
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a917c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9180
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9184
|
|
.word chrShoot+0x14fc
|
|
.text
|
|
/* f040658: 27bdfd88 */ addiu $sp,$sp,-632
|
|
/* f04065c: afbf0044 */ sw $ra,0x44($sp)
|
|
/* f040660: afa5027c */ sw $a1,0x27c($sp)
|
|
/* f040664: 8c8e001c */ lw $t6,0x1c($a0)
|
|
/* f040668: 240f0001 */ li $t7,0x1
|
|
/* f04066c: a3af026e */ sb $t7,0x26e($sp)
|
|
/* f040670: afae0274 */ sw $t6,0x274($sp)
|
|
/* f040674: 8c9802d4 */ lw $t8,0x2d4($a0)
|
|
/* f040678: 00001025 */ move $v0,$zero
|
|
/* f04067c: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f040680: 53000003 */ beqzl $t8,.PF0f040690
|
|
/* f040684: a3a2026f */ sb $v0,0x26f($sp)
|
|
/* f040688: 24020001 */ li $v0,0x1
|
|
/* f04068c: a3a2026f */ sb $v0,0x26f($sp)
|
|
.PF0f040690:
|
|
/* f040690: 0fc0a252 */ jal chrGetHeldProp
|
|
/* f040694: afa40278 */ sw $a0,0x278($sp)
|
|
/* f040698: 5040055c */ beqzl $v0,.PF0f041c0c
|
|
/* f04069c: 8fbf0044 */ lw $ra,0x44($sp)
|
|
/* f0406a0: afa00268 */ sw $zero,0x268($sp)
|
|
/* f0406a4: 8c590004 */ lw $t9,0x4($v0)
|
|
/* f0406a8: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0406ac: 0fc0a26a */ jal chrGetTargetProp
|
|
/* f0406b0: afb90264 */ sw $t9,0x264($sp)
|
|
/* f0406b4: 8fab0264 */ lw $t3,0x264($sp)
|
|
/* f0406b8: afa2025c */ sw $v0,0x25c($sp)
|
|
/* f0406bc: 8fa70278 */ lw $a3,0x278($sp)
|
|
/* f0406c0: 8961005c */ lwl $at,0x5c($t3)
|
|
/* f0406c4: 9961005f */ lwr $at,0x5f($t3)
|
|
/* f0406c8: 27aa0260 */ addiu $t2,$sp,0x260
|
|
/* f0406cc: 24080200 */ li $t0,0x200
|
|
/* f0406d0: ad410000 */ sw $at,0x0($t2)
|
|
/* f0406d4: 80e30007 */ lb $v1,0x7($a3)
|
|
/* f0406d8: 24010008 */ li $at,0x8
|
|
/* f0406dc: 10610007 */ beq $v1,$at,.PF0f0406fc
|
|
/* f0406e0: 2401001b */ li $at,0x1b
|
|
/* f0406e4: 10610005 */ beq $v1,$at,.PF0f0406fc
|
|
/* f0406e8: 2401001c */ li $at,0x1c
|
|
/* f0406ec: 10610003 */ beq $v1,$at,.PF0f0406fc
|
|
/* f0406f0: 2401001d */ li $at,0x1d
|
|
/* f0406f4: 54610003 */ bnel $v1,$at,.PF0f040704
|
|
/* f0406f8: afa00250 */ sw $zero,0x250($sp)
|
|
.PF0f0406fc:
|
|
/* f0406fc: 8ce8004c */ lw $t0,0x4c($a3)
|
|
/* f040700: afa00250 */ sw $zero,0x250($sp)
|
|
.PF0f040704:
|
|
/* f040704: afa00224 */ sw $zero,0x224($sp)
|
|
/* f040708: afa00210 */ sw $zero,0x210($sp)
|
|
/* f04070c: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040710: 93a50263 */ lbu $a1,0x263($sp)
|
|
/* f040714: afa00254 */ sw $zero,0x254($sp)
|
|
/* f040718: 0fc2c8f8 */ jal weaponGetNumTicksPerShot
|
|
/* f04071c: afa80258 */ sw $t0,0x258($sp)
|
|
/* f040720: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f040724: 1c400005 */ bgtz $v0,.PF0f04073c
|
|
/* f040728: 00402025 */ move $a0,$v0
|
|
/* f04072c: 240f0001 */ li $t7,0x1
|
|
/* f040730: 24060001 */ li $a2,0x1
|
|
/* f040734: 10000055 */ b .PF0f04088c
|
|
/* f040738: afaf0250 */ sw $t7,0x250($sp)
|
|
.PF0f04073c:
|
|
/* f04073c: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f040740: 8f0302d4 */ lw $v1,0x2d4($t8)
|
|
/* f040744: 5060001d */ beqzl $v1,.PF0f0407bc
|
|
/* f040748: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f04074c: 8c790020 */ lw $t9,0x20($v1)
|
|
/* f040750: 24010014 */ li $at,0x14
|
|
/* f040754: 57210019 */ bnel $t9,$at,.PF0f0407bc
|
|
/* f040758: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f04075c: 8c6d004c */ lw $t5,0x4c($v1)
|
|
/* f040760: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f040764: 000d5080 */ sll $t2,$t5,0x2
|
|
/* f040768: 05400013 */ bltz $t2,.PF0f0407b8
|
|
/* f04076c: 000b7040 */ sll $t6,$t3,0x1
|
|
/* f040770: 006e7821 */ addu $t7,$v1,$t6
|
|
/* f040774: 85f800e0 */ lh $t8,0xe0($t7)
|
|
/* f040778: 2419004b */ li $t9,0x4b
|
|
/* f04077c: 3c017f1b */ lui $at,0x7f1b
|
|
/* f040780: 03386823 */ subu $t5,$t9,$t8
|
|
/* f040784: 448d2000 */ mtc1 $t5,$f4
|
|
/* f040788: c428a32c */ lwc1 $f8,-0x5cd4($at)
|
|
/* f04078c: 44825000 */ mtc1 $v0,$f10
|
|
/* f040790: 468021a0 */ cvt.s.w $f6,$f4
|
|
/* f040794: 3c013f80 */ lui $at,0x3f80
|
|
/* f040798: 44819000 */ mtc1 $at,$f18
|
|
/* f04079c: 46805420 */ cvt.s.w $f16,$f10
|
|
/* f0407a0: 46083002 */ mul.s $f0,$f6,$f8
|
|
/* f0407a4: 46009100 */ add.s $f4,$f18,$f0
|
|
/* f0407a8: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f0407ac: 4600320d */ trunc.w.s $f8,$f6
|
|
/* f0407b0: 44044000 */ mfc1 $a0,$f8
|
|
/* f0407b4: 00000000 */ nop
|
|
.PF0f0407b8:
|
|
/* f0407b8: 8faa0278 */ lw $t2,0x278($sp)
|
|
.PF0f0407bc:
|
|
/* f0407bc: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f0407c0: 3c0f800a */ lui $t7,0x800a
|
|
/* f0407c4: 8defa548 */ lw $t7,-0x5ab8($t7)
|
|
/* f0407c8: 014b1821 */ addu $v1,$t2,$t3
|
|
/* f0407cc: 906e0004 */ lbu $t6,0x4($v1)
|
|
/* f0407d0: 01cfc821 */ addu $t9,$t6,$t7
|
|
/* f0407d4: 333800ff */ andi $t8,$t9,0xff
|
|
/* f0407d8: 0304082a */ slt $at,$t8,$a0
|
|
/* f0407dc: 1420002b */ bnez $at,.PF0f04088c
|
|
/* f0407e0: a0790004 */ sb $t9,0x4($v1)
|
|
/* f0407e4: a0600004 */ sb $zero,0x4($v1)
|
|
/* f0407e8: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f0407ec: 8fad027c */ lw $t5,0x27c($sp)
|
|
/* f0407f0: 240c0001 */ li $t4,0x1
|
|
/* f0407f4: 8d4b032c */ lw $t3,0x32c($t2)
|
|
/* f0407f8: 01ac1004 */ sllv $v0,$t4,$t5
|
|
/* f0407fc: 24060001 */ li $a2,0x1
|
|
/* f040800: 000b7300 */ sll $t6,$t3,0xc
|
|
/* f040804: 914b032d */ lbu $t3,0x32d($t2)
|
|
/* f040808: 000e7f82 */ srl $t7,$t6,0x1e
|
|
/* f04080c: 01e2c026 */ xor $t8,$t7,$v0
|
|
/* f040810: 00186080 */ sll $t4,$t8,0x2
|
|
/* f040814: 318d000c */ andi $t5,$t4,0xc
|
|
/* f040818: 316efff3 */ andi $t6,$t3,0xfff3
|
|
/* f04081c: 01ae7825 */ or $t7,$t5,$t6
|
|
/* f040820: a14f032d */ sb $t7,0x32d($t2)
|
|
/* f040824: 8d59032c */ lw $t9,0x32c($t2)
|
|
/* f040828: 93ad0260 */ lbu $t5,0x260($sp)
|
|
/* f04082c: 2401001d */ li $at,0x1d
|
|
/* f040830: 0019c300 */ sll $t8,$t9,0xc
|
|
/* f040834: 00186782 */ srl $t4,$t8,0x1e
|
|
/* f040838: 01825824 */ and $t3,$t4,$v0
|
|
/* f04083c: 15600003 */ bnez $t3,.PF0f04084c
|
|
/* f040840: 240e0001 */ li $t6,0x1
|
|
/* f040844: 55a10003 */ bnel $t5,$at,.PF0f040854
|
|
/* f040848: 8faf0278 */ lw $t7,0x278($sp)
|
|
.PF0f04084c:
|
|
/* f04084c: afae0250 */ sw $t6,0x250($sp)
|
|
/* f040850: 8faf0278 */ lw $t7,0x278($sp)
|
|
.PF0f040854:
|
|
/* f040854: 24010008 */ li $at,0x8
|
|
/* f040858: 81ea0007 */ lb $t2,0x7($t7)
|
|
/* f04085c: 1541000b */ bne $t2,$at,.PF0f04088c
|
|
/* f040860: 00000000 */ nop
|
|
/* f040864: 8de40020 */ lw $a0,0x20($t7)
|
|
/* f040868: 0c0073c3 */ jal modelGetAnimNum
|
|
/* f04086c: afa60254 */ sw $a2,0x254($sp)
|
|
/* f040870: 2401026a */ li $at,0x26a
|
|
/* f040874: 14410005 */ bne $v0,$at,.PF0f04088c
|
|
/* f040878: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f04087c: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f040880: 83380033 */ lb $t8,0x33($t9)
|
|
/* f040884: 270c0001 */ addiu $t4,$t8,0x1
|
|
/* f040888: a32c0033 */ sb $t4,0x33($t9)
|
|
.PF0f04088c:
|
|
/* f04088c: 50c004a3 */ beqzl $a2,.PF0f041b1c
|
|
/* f040890: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f040894: 0fc0f9dd */ jal chrGetAimAngle
|
|
/* f040898: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f04089c: e7a00204 */ swc1 $f0,0x204($sp)
|
|
/* f0408a0: 0fc0fa36 */ jal func0f03e754
|
|
/* f0408a4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0408a8: 93ab026f */ lbu $t3,0x26f($sp)
|
|
/* f0408ac: e7a00200 */ swc1 $f0,0x200($sp)
|
|
/* f0408b0: 240e0001 */ li $t6,0x1
|
|
/* f0408b4: 11600004 */ beqz $t3,.PF0f0408c8
|
|
/* f0408b8: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f0408bc: 240d0004 */ li $t5,0x4
|
|
/* f0408c0: 10000002 */ b .PF0f0408cc
|
|
/* f0408c4: afad01fc */ sw $t5,0x1fc($sp)
|
|
.PF0f0408c8:
|
|
/* f0408c8: afa001fc */ sw $zero,0x1fc($sp)
|
|
.PF0f0408cc:
|
|
/* f0408cc: afae0268 */ sw $t6,0x268($sp)
|
|
/* f0408d0: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0408d4: 0fc0ffda */ jal chrGetGunPos
|
|
/* f0408d8: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f0408dc: 54400032 */ bnezl $v0,.PF0f0409a8
|
|
/* f0408e0: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0408e4: 8fa20274 */ lw $v0,0x274($sp)
|
|
/* f0408e8: 3c0141f0 */ lui $at,0x41f0
|
|
/* f0408ec: 44818000 */ mtc1 $at,$f16
|
|
/* f0408f0: c44a0008 */ lwc1 $f10,0x8($v0)
|
|
/* f0408f4: 8faa027c */ lw $t2,0x27c($sp)
|
|
/* f0408f8: 24010001 */ li $at,0x1
|
|
/* f0408fc: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f040900: c452000c */ lwc1 $f18,0xc($v0)
|
|
/* f040904: 46109100 */ add.s $f4,$f18,$f16
|
|
/* f040908: e7a40248 */ swc1 $f4,0x248($sp)
|
|
/* f04090c: c4460010 */ lwc1 $f6,0x10($v0)
|
|
/* f040910: 15410013 */ bne $t2,$at,.PF0f040960
|
|
/* f040914: e7a6024c */ swc1 $f6,0x24c($sp)
|
|
/* f040918: 0c006858 */ jal cosf
|
|
/* f04091c: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040920: 3c014120 */ lui $at,0x4120
|
|
/* f040924: 44815000 */ mtc1 $at,$f10
|
|
/* f040928: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f04092c: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040930: 460a0482 */ mul.s $f18,$f0,$f10
|
|
/* f040934: 46124400 */ add.s $f16,$f8,$f18
|
|
/* f040938: 0c00685b */ jal sinf
|
|
/* f04093c: e7b00244 */ swc1 $f16,0x244($sp)
|
|
/* f040940: 3c014120 */ lui $at,0x4120
|
|
/* f040944: 44813000 */ mtc1 $at,$f6
|
|
/* f040948: 46000107 */ neg.s $f4,$f0
|
|
/* f04094c: c7a8024c */ lwc1 $f8,0x24c($sp)
|
|
/* f040950: 46062282 */ mul.s $f10,$f4,$f6
|
|
/* f040954: 460a4480 */ add.s $f18,$f8,$f10
|
|
/* f040958: 10000012 */ b .PF0f0409a4
|
|
/* f04095c: e7b2024c */ swc1 $f18,0x24c($sp)
|
|
.PF0f040960:
|
|
/* f040960: 0c006858 */ jal cosf
|
|
/* f040964: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040968: 3c014120 */ lui $at,0x4120
|
|
/* f04096c: 44812000 */ mtc1 $at,$f4
|
|
/* f040970: 46000407 */ neg.s $f16,$f0
|
|
/* f040974: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f040978: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f04097c: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040980: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040984: 0c00685b */ jal sinf
|
|
/* f040988: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f04098c: 3c014120 */ lui $at,0x4120
|
|
/* f040990: 44818000 */ mtc1 $at,$f16
|
|
/* f040994: c7b2024c */ lwc1 $f18,0x24c($sp)
|
|
/* f040998: 46100102 */ mul.s $f4,$f0,$f16
|
|
/* f04099c: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f0409a0: e7a8024c */ swc1 $f8,0x24c($sp)
|
|
.PF0f0409a4:
|
|
/* f0409a4: 8fa40278 */ lw $a0,0x278($sp)
|
|
.PF0f0409a8:
|
|
/* f0409a8: 0fc07a37 */ jal chrSetPerimEnabled
|
|
/* f0409ac: 00002825 */ move $a1,$zero
|
|
/* f0409b0: 8fb801fc */ lw $t8,0x1fc($sp)
|
|
/* f0409b4: 8faf0274 */ lw $t7,0x274($sp)
|
|
/* f0409b8: 24190010 */ li $t9,0x10
|
|
/* f0409bc: 370c082a */ ori $t4,$t8,0x82a
|
|
/* f0409c0: afac0010 */ sw $t4,0x10($sp)
|
|
/* f0409c4: afb90014 */ sw $t9,0x14($sp)
|
|
/* f0409c8: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f0409cc: 27a70234 */ addiu $a3,$sp,0x234
|
|
/* f0409d0: 25e40008 */ addiu $a0,$t7,0x8
|
|
/* f0409d4: 0c00b5cd */ jal cd0002de34
|
|
/* f0409d8: 25e50028 */ addiu $a1,$t7,0x28
|
|
/* f0409dc: 14400002 */ bnez $v0,.PF0f0409e8
|
|
/* f0409e0: 24050001 */ li $a1,0x1
|
|
/* f0409e4: afa00268 */ sw $zero,0x268($sp)
|
|
.PF0f0409e8:
|
|
/* f0409e8: 0fc07a37 */ jal chrSetPerimEnabled
|
|
/* f0409ec: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0409f0: 8fab0268 */ lw $t3,0x268($sp)
|
|
/* f0409f4: 240d0001 */ li $t5,0x1
|
|
/* f0409f8: 51600448 */ beqzl $t3,.PF0f041b1c
|
|
/* f0409fc: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f040a00: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f040a04: afa001f8 */ sw $zero,0x1f8($sp)
|
|
/* f040a08: afa001f4 */ sw $zero,0x1f4($sp)
|
|
/* f040a0c: afad01f0 */ sw $t5,0x1f0($sp)
|
|
/* f040a10: 11c00004 */ beqz $t6,.PF0f040a24
|
|
/* f040a14: afa001cc */ sw $zero,0x1cc($sp)
|
|
/* f040a18: 240a083f */ li $t2,0x83f
|
|
/* f040a1c: 10000003 */ b .PF0f040a2c
|
|
/* f040a20: afaa01c8 */ sw $t2,0x1c8($sp)
|
|
.PF0f040a24:
|
|
/* f040a24: 240f083b */ li $t7,0x83b
|
|
/* f040a28: afaf01c8 */ sw $t7,0x1c8($sp)
|
|
.PF0f040a2c:
|
|
/* f040a2c: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f040a30: 8ce20004 */ lw $v0,0x4($a3)
|
|
/* f040a34: 50400004 */ beqzl $v0,.PF0f040a48
|
|
/* f040a38: 00004825 */ move $t1,$zero
|
|
/* f040a3c: 10000002 */ b .PF0f040a48
|
|
/* f040a40: 904902fe */ lbu $t1,0x2fe($v0)
|
|
/* f040a44: 00004825 */ move $t1,$zero
|
|
.PF0f040a48:
|
|
/* f040a48: 39220003 */ xori $v0,$t1,0x3
|
|
/* f040a4c: 2c420001 */ sltiu $v0,$v0,0x1
|
|
/* f040a50: 1040000f */ beqz $v0,.PF0f040a90
|
|
/* f040a54: 00401825 */ move $v1,$v0
|
|
/* f040a58: afa2005c */ sw $v0,0x5c($sp)
|
|
/* f040a5c: 0fc124d8 */ jal chrGetDistanceToTarget
|
|
/* f040a60: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040a64: 3c014316 */ lui $at,0x4316
|
|
/* f040a68: 44813000 */ mtc1 $at,$f6
|
|
/* f040a6c: 0000c025 */ move $t8,$zero
|
|
/* f040a70: 4600303c */ c.lt.s $f6,$f0
|
|
/* f040a74: 00000000 */ nop
|
|
/* f040a78: 45020003 */ bc1fl .PF0f040a88
|
|
/* f040a7c: afb8005c */ sw $t8,0x5c($sp)
|
|
/* f040a80: 24180001 */ li $t8,0x1
|
|
/* f040a84: afb8005c */ sw $t8,0x5c($sp)
|
|
.PF0f040a88:
|
|
/* f040a88: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f040a8c: 03001825 */ move $v1,$t8
|
|
.PF0f040a90:
|
|
/* f040a90: afa301c0 */ sw $v1,0x1c0($sp)
|
|
/* f040a94: 10600016 */ beqz $v1,.PF0f040af0
|
|
/* f040a98: afa001bc */ sw $zero,0x1bc($sp)
|
|
/* f040a9c: c4ea0008 */ lwc1 $f10,0x8($a3)
|
|
/* f040aa0: c7b00244 */ lwc1 $f16,0x244($sp)
|
|
/* f040aa4: c7a80248 */ lwc1 $f8,0x248($sp)
|
|
/* f040aa8: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040aac: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f040ab0: c7b0024c */ lwc1 $f16,0x24c($sp)
|
|
/* f040ab4: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040ab8: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040abc: e7b201e0 */ swc1 $f18,0x1e0($sp)
|
|
/* f040ac0: c4e4000c */ lwc1 $f4,0xc($a3)
|
|
/* f040ac4: 46082181 */ sub.s $f6,$f4,$f8
|
|
/* f040ac8: e7a601e4 */ swc1 $f6,0x1e4($sp)
|
|
/* f040acc: c4ea0010 */ lwc1 $f10,0x10($a3)
|
|
/* f040ad0: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f040ad4: 0c0011d8 */ jal guNormalize
|
|
/* f040ad8: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
/* f040adc: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f040ae0: 0fc19102 */ jal propSetPerimEnabled
|
|
/* f040ae4: 24050001 */ li $a1,0x1
|
|
/* f040ae8: 1000002f */ b .PF0f040ba8
|
|
/* f040aec: 8fab0278 */ lw $t3,0x278($sp)
|
|
.PF0f040af0:
|
|
/* f040af0: 0c006858 */ jal cosf
|
|
/* f040af4: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040af8: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f040afc: 0c00685b */ jal sinf
|
|
/* f040b00: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040b04: c7a40060 */ lwc1 $f4,0x60($sp)
|
|
/* f040b08: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040b0c: 46040202 */ mul.s $f8,$f0,$f4
|
|
/* f040b10: 0c00685b */ jal sinf
|
|
/* f040b14: e7a801e0 */ swc1 $f8,0x1e0($sp)
|
|
/* f040b18: e7a001e4 */ swc1 $f0,0x1e4($sp)
|
|
/* f040b1c: 0c006858 */ jal cosf
|
|
/* f040b20: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040b24: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f040b28: 0c006858 */ jal cosf
|
|
/* f040b2c: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040b30: c7a60060 */ lwc1 $f6,0x60($sp)
|
|
/* f040b34: 93ac026f */ lbu $t4,0x26f($sp)
|
|
/* f040b38: 46060282 */ mul.s $f10,$f0,$f6
|
|
/* f040b3c: 11800019 */ beqz $t4,.PF0f040ba4
|
|
/* f040b40: e7aa01e8 */ swc1 $f10,0x1e8($sp)
|
|
/* f040b44: 0fc6492c */ jal botGuessCrouchPos
|
|
/* f040b48: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040b4c: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f040b50: 00404825 */ move $t1,$v0
|
|
/* f040b54: 8fae0278 */ lw $t6,0x278($sp)
|
|
/* f040b58: 8f280170 */ lw $t0,0x170($t9)
|
|
/* f040b5c: 0008582b */ sltu $t3,$zero,$t0
|
|
/* f040b60: 11600004 */ beqz $t3,.PF0f040b74
|
|
/* f040b64: 01604025 */ move $t0,$t3
|
|
/* f040b68: 8f280174 */ lw $t0,0x174($t9)
|
|
/* f040b6c: 0008682b */ sltu $t5,$zero,$t0
|
|
/* f040b70: 01a04025 */ move $t0,$t5
|
|
.PF0f040b74:
|
|
/* f040b74: 8dc302d4 */ lw $v1,0x2d4($t6)
|
|
/* f040b78: 8fb8027c */ lw $t8,0x27c($sp)
|
|
/* f040b7c: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040b80: 8c66004c */ lw $a2,0x4c($v1)
|
|
/* f040b84: 00786021 */ addu $t4,$v1,$t8
|
|
/* f040b88: 9187004d */ lbu $a3,0x4d($t4)
|
|
/* f040b8c: 8c650020 */ lw $a1,0x20($v1)
|
|
/* f040b90: 00065080 */ sll $t2,$a2,0x2
|
|
/* f040b94: 000a37c2 */ srl $a2,$t2,0x1f
|
|
/* f040b98: afa80014 */ sw $t0,0x14($sp)
|
|
/* f040b9c: 0fc284b4 */ jal bgunCalculateBotShotSpread
|
|
/* f040ba0: afa90010 */ sw $t1,0x10($sp)
|
|
.PF0f040ba4:
|
|
/* f040ba4: 8fab0278 */ lw $t3,0x278($sp)
|
|
.PF0f040ba8:
|
|
/* f040ba8: 93b90260 */ lbu $t9,0x260($sp)
|
|
/* f040bac: 24010016 */ li $at,0x16
|
|
/* f040bb0: 8d6302d4 */ lw $v1,0x2d4($t3)
|
|
/* f040bb4: 50600018 */ beqzl $v1,.PF0f040c18
|
|
/* f040bb8: 3c014780 */ lui $at,0x4780
|
|
/* f040bbc: 57210016 */ bnel $t9,$at,.PF0f040c18
|
|
/* f040bc0: 3c014780 */ lui $at,0x4780
|
|
/* f040bc4: 8c6d0128 */ lw $t5,0x128($v1)
|
|
/* f040bc8: 240e0001 */ li $t6,0x1
|
|
/* f040bcc: 01602025 */ move $a0,$t3
|
|
/* f040bd0: 15a00010 */ bnez $t5,.PF0f040c14
|
|
/* f040bd4: 00002825 */ move $a1,$zero
|
|
/* f040bd8: afae0250 */ sw $t6,0x250($sp)
|
|
/* f040bdc: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f040be0: 0fc66c21 */ jal botactShootFarsight
|
|
/* f040be4: 27a70244 */ addiu $a3,$sp,0x244
|
|
/* f040be8: 24010002 */ li $at,0x2
|
|
/* f040bec: 5441000a */ bnel $v0,$at,.PF0f040c18
|
|
/* f040bf0: 3c014780 */ lui $at,0x4780
|
|
/* f040bf4: 0c004ad4 */ jal random
|
|
/* f040bf8: 00000000 */ nop
|
|
/* f040bfc: 240100ff */ li $at,0xff
|
|
/* f040c00: 0041001b */ divu $zero,$v0,$at
|
|
/* f040c04: 00005010 */ mfhi $t2
|
|
/* f040c08: 2d4f00c9 */ sltiu $t7,$t2,0xc9
|
|
/* f040c0c: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f040c10: a3af026e */ sb $t7,0x26e($sp)
|
|
.PF0f040c14:
|
|
/* f040c14: 3c014780 */ lui $at,0x4780
|
|
.PF0f040c18:
|
|
/* f040c18: 44810000 */ mtc1 $at,$f0
|
|
/* f040c1c: c7b001e0 */ lwc1 $f16,0x1e0($sp)
|
|
/* f040c20: c7a40244 */ lwc1 $f4,0x244($sp)
|
|
/* f040c24: c7a601e4 */ lwc1 $f6,0x1e4($sp)
|
|
/* f040c28: 46008482 */ mul.s $f18,$f16,$f0
|
|
/* f040c2c: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f040c30: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040c34: 46003282 */ mul.s $f10,$f6,$f0
|
|
/* f040c38: c7a6024c */ lwc1 $f6,0x24c($sp)
|
|
/* f040c3c: 00002825 */ move $a1,$zero
|
|
/* f040c40: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f040c44: c7a401e8 */ lwc1 $f4,0x1e8($sp)
|
|
/* f040c48: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f040c4c: e7a80228 */ swc1 $f8,0x228($sp)
|
|
/* f040c50: 46002202 */ mul.s $f8,$f4,$f0
|
|
/* f040c54: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f040c58: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040c5c: 0fc07a37 */ jal chrSetPerimEnabled
|
|
/* f040c60: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f040c64: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040c68: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040c6c: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f040c70: 13000004 */ beqz $t8,.PF0f040c84
|
|
/* f040c74: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f040c78: 240c0001 */ li $t4,0x1
|
|
/* f040c7c: 3c01800a */ lui $at,0x800a
|
|
/* f040c80: ac2ca99c */ sw $t4,-0x5664($at)
|
|
.PF0f040c84:
|
|
/* f040c84: 24190010 */ li $t9,0x10
|
|
/* f040c88: afb90010 */ sw $t9,0x10($sp)
|
|
/* f040c8c: 0c00b5a4 */ jal cdTestAToB4
|
|
/* f040c90: 8fa701c8 */ lw $a3,0x1c8($sp)
|
|
/* f040c94: 1440000a */ bnez $v0,.PF0f040cc0
|
|
/* f040c98: 240d0001 */ li $t5,0x1
|
|
/* f040c9c: 3c067f1b */ lui $a2,0x7f1b
|
|
/* f040ca0: afad0224 */ sw $t5,0x224($sp)
|
|
/* f040ca4: 24c69d20 */ addiu $a2,$a2,-25312
|
|
/* f040ca8: 27a40228 */ addiu $a0,$sp,0x228
|
|
/* f040cac: 0c0091ef */ jal cdGetPos
|
|
/* f040cb0: 24052f2d */ li $a1,0x2f2d
|
|
/* f040cb4: 0c0091ec */ jal cdGetObstacle
|
|
/* f040cb8: 00000000 */ nop
|
|
/* f040cbc: afa201cc */ sw $v0,0x1cc($sp)
|
|
.PF0f040cc0:
|
|
/* f040cc0: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040cc4: 0fc07a37 */ jal chrSetPerimEnabled
|
|
/* f040cc8: 24050001 */ li $a1,0x1
|
|
/* f040ccc: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f040cd0: 3c01800a */ lui $at,0x800a
|
|
/* f040cd4: 51c00003 */ beqzl $t6,.PF0f040ce4
|
|
/* f040cd8: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
/* f040cdc: ac20a99c */ sw $zero,-0x5664($at)
|
|
/* f040ce0: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
.PF0f040ce4:
|
|
/* f040ce4: 8faa01c0 */ lw $t2,0x1c0($sp)
|
|
/* f040ce8: 55600015 */ bnezl $t3,.PF0f040d40
|
|
/* f040cec: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f040cf0: 51400013 */ beqzl $t2,.PF0f040d40
|
|
/* f040cf4: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f040cf8: 0c004ad4 */ jal random
|
|
/* f040cfc: 00000000 */ nop
|
|
/* f040d00: 24010064 */ li $at,0x64
|
|
/* f040d04: 0041001b */ divu $zero,$v0,$at
|
|
/* f040d08: 00001810 */ mfhi $v1
|
|
/* f040d0c: 2c6f0033 */ sltiu $t7,$v1,0x33
|
|
/* f040d10: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f040d14: 11e00009 */ beqz $t7,.PF0f040d3c
|
|
/* f040d18: afaf01bc */ sw $t7,0x1bc($sp)
|
|
/* f040d1c: 8fb8025c */ lw $t8,0x25c($sp)
|
|
/* f040d20: afb801cc */ sw $t8,0x1cc($sp)
|
|
/* f040d24: c7100008 */ lwc1 $f16,0x8($t8)
|
|
/* f040d28: e7b00228 */ swc1 $f16,0x228($sp)
|
|
/* f040d2c: c712000c */ lwc1 $f18,0xc($t8)
|
|
/* f040d30: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f040d34: c7040010 */ lwc1 $f4,0x10($t8)
|
|
/* f040d38: e7a40230 */ swc1 $f4,0x230($sp)
|
|
.PF0f040d3c:
|
|
/* f040d3c: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
.PF0f040d40:
|
|
/* f040d40: c7a60244 */ lwc1 $f6,0x244($sp)
|
|
/* f040d44: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f040d48: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f040d4c: 46064001 */ sub.s $f0,$f8,$f6
|
|
/* f040d50: c7b20230 */ lwc1 $f18,0x230($sp)
|
|
/* f040d54: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f040d58: 46105081 */ sub.s $f2,$f10,$f16
|
|
/* f040d5c: 46000202 */ mul.s $f8,$f0,$f0
|
|
/* f040d60: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040d64: 46049301 */ sub.s $f12,$f18,$f4
|
|
/* f040d68: 46021182 */ mul.s $f6,$f2,$f2
|
|
/* f040d6c: 24010018 */ li $at,0x18
|
|
/* f040d70: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f040d74: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040d78: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f040d7c: 1081000f */ beq $a0,$at,.PF0f040dbc
|
|
/* f040d80: e7b201d0 */ swc1 $f18,0x1d0($sp)
|
|
/* f040d84: 24010019 */ li $at,0x19
|
|
/* f040d88: 1081000c */ beq $a0,$at,.PF0f040dbc
|
|
/* f040d8c: 24010012 */ li $at,0x12
|
|
/* f040d90: 14810003 */ bne $a0,$at,.PF0f040da0
|
|
/* f040d94: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f040d98: 24010001 */ li $at,0x1
|
|
/* f040d9c: 11810007 */ beq $t4,$at,.PF0f040dbc
|
|
.PF0f040da0:
|
|
/* f040da0: 24010017 */ li $at,0x17
|
|
/* f040da4: 10810005 */ beq $a0,$at,.PF0f040dbc
|
|
/* f040da8: 2401001b */ li $at,0x1b
|
|
/* f040dac: 10810003 */ beq $a0,$at,.PF0f040dbc
|
|
/* f040db0: 24010034 */ li $at,0x34
|
|
/* f040db4: 54810179 */ bnel $a0,$at,.PF0f04139c
|
|
/* f040db8: 24010006 */ li $at,0x6
|
|
.PF0f040dbc:
|
|
/* f040dbc: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f040dc0: afa00250 */ sw $zero,0x250($sp)
|
|
/* f040dc4: 3c017f1b */ lui $at,0x7f1b
|
|
/* f040dc8: 17200006 */ bnez $t9,.PF0f040de4
|
|
/* f040dcc: c7a801d0 */ lwc1 $f8,0x1d0($sp)
|
|
/* f040dd0: c424a330 */ lwc1 $f4,-0x5cd0($at)
|
|
/* f040dd4: 4608203c */ c.lt.s $f4,$f8
|
|
/* f040dd8: 00000000 */ nop
|
|
/* f040ddc: 4502016c */ bc1fl .PF0f041390
|
|
/* f040de0: afa00268 */ sw $zero,0x268($sp)
|
|
.PF0f040de4:
|
|
/* f040de4: 0fc2c524 */ jal weaponFindById
|
|
/* f040de8: 00000000 */ nop
|
|
/* f040dec: 93ad0263 */ lbu $t5,0x263($sp)
|
|
/* f040df0: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040df4: 24010018 */ li $at,0x18
|
|
/* f040df8: 000d7080 */ sll $t6,$t5,0x2
|
|
/* f040dfc: 004e5821 */ addu $t3,$v0,$t6
|
|
/* f040e00: 10810006 */ beq $a0,$at,.PF0f040e1c
|
|
/* f040e04: 8d630014 */ lw $v1,0x14($t3)
|
|
/* f040e08: 24010034 */ li $at,0x34
|
|
/* f040e0c: 10810003 */ beq $a0,$at,.PF0f040e1c
|
|
/* f040e10: 24010019 */ li $at,0x19
|
|
/* f040e14: 5481000e */ bnel $a0,$at,.PF0f040e50
|
|
/* f040e18: 2401001b */ li $at,0x1b
|
|
.PF0f040e1c:
|
|
/* f040e1c: 8c6a0010 */ lw $t2,0x10($v1)
|
|
/* f040e20: 24050053 */ li $a1,0x53
|
|
/* f040e24: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040e28: 000a7840 */ sll $t7,$t2,0x1
|
|
/* f040e2c: 05e30003 */ bgezl $t7,.PF0f040e3c
|
|
/* f040e30: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040e34: 24050054 */ li $a1,0x54
|
|
/* f040e38: 8c640040 */ lw $a0,0x40($v1)
|
|
.PF0f040e3c:
|
|
/* f040e3c: 0fc22deb */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040e40: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040e44: 1000002e */ b .PF0f040f00
|
|
/* f040e48: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040e4c: 2401001b */ li $at,0x1b
|
|
.PF0f040e50:
|
|
/* f040e50: 1481000a */ bne $a0,$at,.PF0f040e7c
|
|
/* f040e54: 24050056 */ li $a1,0x56
|
|
/* f040e58: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040e5c: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040e60: 0fc22deb */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040e64: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040e68: 10400025 */ beqz $v0,.PF0f040f00
|
|
/* f040e6c: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040e70: 93b80263 */ lbu $t8,0x263($sp)
|
|
/* f040e74: 10000022 */ b .PF0f040f00
|
|
/* f040e78: a058005f */ sb $t8,0x5f($v0)
|
|
.PF0f040e7c:
|
|
/* f040e7c: 24010017 */ li $at,0x17
|
|
/* f040e80: 1481000a */ bne $a0,$at,.PF0f040eac
|
|
/* f040e84: 24050055 */ li $a1,0x55
|
|
/* f040e88: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040e8c: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040e90: 0fc22deb */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040e94: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040e98: 10400019 */ beqz $v0,.PF0f040f00
|
|
/* f040e9c: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040ea0: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f040ea4: 10000016 */ b .PF0f040f00
|
|
/* f040ea8: a04c005f */ sb $t4,0x5f($v0)
|
|
.PF0f040eac:
|
|
/* f040eac: 24010012 */ li $at,0x12
|
|
/* f040eb0: 1481000b */ bne $a0,$at,.PF0f040ee0
|
|
/* f040eb4: 3c0d800a */ lui $t5,0x800a
|
|
/* f040eb8: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040ebc: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040ec0: 24050055 */ li $a1,0x55
|
|
/* f040ec4: 0fc22deb */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040ec8: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040ecc: 1040000c */ beqz $v0,.PF0f040f00
|
|
/* f040ed0: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040ed4: 24190002 */ li $t9,0x2
|
|
/* f040ed8: 10000009 */ b .PF0f040f00
|
|
/* f040edc: a059005f */ sb $t9,0x5f($v0)
|
|
.PF0f040ee0:
|
|
/* f040ee0: 8dada794 */ lw $t5,-0x586c($t5)
|
|
/* f040ee4: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040ee8: 27a50260 */ addiu $a1,$sp,0x260
|
|
/* f040eec: 8dae00bc */ lw $t6,0xbc($t5)
|
|
/* f040ef0: 8dc60004 */ lw $a2,0x4($t6)
|
|
/* f040ef4: 0fc22d61 */ jal weaponCreateProjectileFromGset
|
|
/* f040ef8: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040efc: afa201b8 */ sw $v0,0x1b8($sp)
|
|
.PF0f040f00:
|
|
/* f040f00: 10400123 */ beqz $v0,.PF0f041390
|
|
/* f040f04: 8fab00d4 */ lw $t3,0xd4($sp)
|
|
/* f040f08: 8d6a004c */ lw $t2,0x4c($t3)
|
|
/* f040f0c: 3c017f1b */ lui $at,0x7f1b
|
|
/* f040f10: c430a334 */ lwc1 $f16,-0x5ccc($at)
|
|
/* f040f14: 448a3000 */ mtc1 $t2,$f6
|
|
/* f040f18: 3c014270 */ lui $at,0x4270
|
|
/* f040f1c: 44812000 */ mtc1 $at,$f4
|
|
/* f040f20: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f040f24: 3c017f1b */ lui $at,0x7f1b
|
|
/* f040f28: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040f2c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040f30: 2405001e */ li $a1,0x1e
|
|
/* f040f34: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f040f38: c430a338 */ lwc1 $f16,-0x5cc8($at)
|
|
/* f040f3c: 46049203 */ div.s $f8,$f18,$f4
|
|
/* f040f40: e7a80168 */ swc1 $f8,0x168($sp)
|
|
/* f040f44: 8d6f0054 */ lw $t7,0x54($t3)
|
|
/* f040f48: 448f3000 */ mtc1 $t7,$f6
|
|
/* f040f4c: 00000000 */ nop
|
|
/* f040f50: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f040f54: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f040f58: 13000080 */ beqz $t8,.PF0f04115c
|
|
/* f040f5c: e7b200cc */ swc1 $f18,0xcc($sp)
|
|
/* f040f60: 0fc12480 */ jal chrIsTargetInFov
|
|
/* f040f64: 00003025 */ move $a2,$zero
|
|
/* f040f68: 1040007c */ beqz $v0,.PF0f04115c
|
|
/* f040f6c: 00000000 */ nop
|
|
/* f040f70: 93a20263 */ lbu $v0,0x263($sp)
|
|
/* f040f74: 00001825 */ move $v1,$zero
|
|
/* f040f78: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040f7c: 14400025 */ bnez $v0,.PF0f041014
|
|
/* f040f80: 24010018 */ li $at,0x18
|
|
/* f040f84: 10810006 */ beq $a0,$at,.PF0f040fa0
|
|
/* f040f88: 8fac025c */ lw $t4,0x25c($sp)
|
|
/* f040f8c: 24010034 */ li $at,0x34
|
|
/* f040f90: 10810003 */ beq $a0,$at,.PF0f040fa0
|
|
/* f040f94: 24010019 */ li $at,0x19
|
|
/* f040f98: 5481001f */ bnel $a0,$at,.PF0f041018
|
|
/* f040f9c: 93a40260 */ lbu $a0,0x260($sp)
|
|
.PF0f040fa0:
|
|
/* f040fa0: 91820000 */ lbu $v0,0x0($t4)
|
|
/* f040fa4: 24010003 */ li $at,0x3
|
|
/* f040fa8: 8fb9025c */ lw $t9,0x25c($sp)
|
|
/* f040fac: 10410003 */ beq $v0,$at,.PF0f040fbc
|
|
/* f040fb0: 24010006 */ li $at,0x6
|
|
/* f040fb4: 14410051 */ bne $v0,$at,.PF0f0410fc
|
|
/* f040fb8: 00000000 */ nop
|
|
.PF0f040fbc:
|
|
/* f040fbc: c7240008 */ lwc1 $f4,0x8($t9)
|
|
/* f040fc0: c7aa0244 */ lwc1 $f10,0x244($sp)
|
|
/* f040fc4: c7b20248 */ lwc1 $f18,0x248($sp)
|
|
/* f040fc8: e7a400b8 */ swc1 $f4,0xb8($sp)
|
|
/* f040fcc: 8f2d0004 */ lw $t5,0x4($t9)
|
|
/* f040fd0: 460a2401 */ sub.s $f16,$f4,$f10
|
|
/* f040fd4: c7aa024c */ lwc1 $f10,0x24c($sp)
|
|
/* f040fd8: c5a800b4 */ lwc1 $f8,0xb4($t5)
|
|
/* f040fdc: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040fe0: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040fe4: e7a800bc */ swc1 $f8,0xbc($sp)
|
|
/* f040fe8: c7260010 */ lwc1 $f6,0x10($t9)
|
|
/* f040fec: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f040ff0: 46124101 */ sub.s $f4,$f8,$f18
|
|
/* f040ff4: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040ff8: e7a600c0 */ swc1 $f6,0xc0($sp)
|
|
/* f040ffc: 460a3401 */ sub.s $f16,$f6,$f10
|
|
/* f041000: e7a401e4 */ swc1 $f4,0x1e4($sp)
|
|
/* f041004: 0c0011d8 */ jal guNormalize
|
|
/* f041008: e7b001e8 */ swc1 $f16,0x1e8($sp)
|
|
/* f04100c: 1000003b */ b .PF0f0410fc
|
|
/* f041010: 24030001 */ li $v1,0x1
|
|
.PF0f041014:
|
|
/* f041014: 93a40260 */ lbu $a0,0x260($sp)
|
|
.PF0f041018:
|
|
/* f041018: 24050017 */ li $a1,0x17
|
|
/* f04101c: 24010012 */ li $at,0x12
|
|
/* f041020: 14a40003 */ bne $a1,$a0,.PF0f041030
|
|
/* f041024: 00000000 */ nop
|
|
/* f041028: 50400004 */ beqzl $v0,.PF0f04103c
|
|
/* f04102c: 8fae025c */ lw $t6,0x25c($sp)
|
|
.PF0f041030:
|
|
/* f041030: 14810017 */ bne $a0,$at,.PF0f041090
|
|
/* f041034: 00000000 */ nop
|
|
/* f041038: 8fae025c */ lw $t6,0x25c($sp)
|
|
.PF0f04103c:
|
|
/* f04103c: 24010003 */ li $at,0x3
|
|
/* f041040: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f041044: 91c20000 */ lbu $v0,0x0($t6)
|
|
/* f041048: 10410003 */ beq $v0,$at,.PF0f041058
|
|
/* f04104c: 24010006 */ li $at,0x6
|
|
/* f041050: 1441002a */ bne $v0,$at,.PF0f0410fc
|
|
/* f041054: 00000000 */ nop
|
|
.PF0f041058:
|
|
/* f041058: c5480008 */ lwc1 $f8,0x8($t2)
|
|
/* f04105c: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041060: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f041064: e7a800b8 */ swc1 $f8,0xb8($sp)
|
|
/* f041068: 8d4b0004 */ lw $t3,0x4($t2)
|
|
/* f04106c: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f041070: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f041074: c57200b4 */ lwc1 $f18,0xb4($t3)
|
|
/* f041078: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
/* f04107c: c5440010 */ lwc1 $f4,0x10($t2)
|
|
/* f041080: 0fc10128 */ jal chrCalculateTrajectory
|
|
/* f041084: e7a400c0 */ swc1 $f4,0xc0($sp)
|
|
/* f041088: 1000001c */ b .PF0f0410fc
|
|
/* f04108c: 24030001 */ li $v1,0x1
|
|
.PF0f041090:
|
|
/* f041090: 14a40002 */ bne $a1,$a0,.PF0f04109c
|
|
/* f041094: 24010001 */ li $at,0x1
|
|
/* f041098: 10410003 */ beq $v0,$at,.PF0f0410a8
|
|
.PF0f04109c:
|
|
/* f04109c: 2401001b */ li $at,0x1b
|
|
/* f0410a0: 14810016 */ bne $a0,$at,.PF0f0410fc
|
|
/* f0410a4: 00000000 */ nop
|
|
.PF0f0410a8:
|
|
/* f0410a8: 8faf025c */ lw $t7,0x25c($sp)
|
|
/* f0410ac: 24010006 */ li $at,0x6
|
|
/* f0410b0: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f0410b4: c5e60008 */ lwc1 $f6,0x8($t7)
|
|
/* f0410b8: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f0410bc: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f0410c0: e7a600b8 */ swc1 $f6,0xb8($sp)
|
|
/* f0410c4: c5ea000c */ lwc1 $f10,0xc($t7)
|
|
/* f0410c8: e7aa00bc */ swc1 $f10,0xbc($sp)
|
|
/* f0410cc: c5f00010 */ lwc1 $f16,0x10($t7)
|
|
/* f0410d0: e7b000c0 */ swc1 $f16,0xc0($sp)
|
|
/* f0410d4: 91f80000 */ lbu $t8,0x0($t7)
|
|
/* f0410d8: 17010005 */ bne $t8,$at,.PF0f0410f0
|
|
/* f0410dc: 3c0141c8 */ lui $at,0x41c8
|
|
/* f0410e0: 44814000 */ mtc1 $at,$f8
|
|
/* f0410e4: 00000000 */ nop
|
|
/* f0410e8: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f0410ec: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
.PF0f0410f0:
|
|
/* f0410f0: 0fc10128 */ jal chrCalculateTrajectory
|
|
/* f0410f4: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f0410f8: 24030001 */ li $v1,0x1
|
|
.PF0f0410fc:
|
|
/* f0410fc: 10600017 */ beqz $v1,.PF0f04115c
|
|
/* f041100: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041104: 0fc12307 */ jal chrGetAngleToPos
|
|
/* f041108: 27a500b8 */ addiu $a1,$sp,0xb8
|
|
/* f04110c: e7a000b4 */ swc1 $f0,0xb4($sp)
|
|
/* f041110: 0c006858 */ jal cosf
|
|
/* f041114: 46000306 */ mov.s $f12,$f0
|
|
/* f041118: c7ac00b4 */ lwc1 $f12,0xb4($sp)
|
|
/* f04111c: 0c00685b */ jal sinf
|
|
/* f041120: e7a000b0 */ swc1 $f0,0xb0($sp)
|
|
/* f041124: c7ac01e8 */ lwc1 $f12,0x1e8($sp)
|
|
/* f041128: c7ae00b0 */ lwc1 $f14,0xb0($sp)
|
|
/* f04112c: c7a201e0 */ lwc1 $f2,0x1e0($sp)
|
|
/* f041130: 460c0102 */ mul.s $f4,$f0,$f12
|
|
/* f041134: 00000000 */ nop
|
|
/* f041138: 46027182 */ mul.s $f6,$f14,$f2
|
|
/* f04113c: 00000000 */ nop
|
|
/* f041140: 460c7282 */ mul.s $f10,$f14,$f12
|
|
/* f041144: 00000000 */ nop
|
|
/* f041148: 46020202 */ mul.s $f8,$f0,$f2
|
|
/* f04114c: 46062400 */ add.s $f16,$f4,$f6
|
|
/* f041150: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f041154: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f041158: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
.PF0f04115c:
|
|
/* f04115c: 0c0055d0 */ jal mtx4LoadIdentity
|
|
/* f041160: 27a40178 */ addiu $a0,$sp,0x178
|
|
/* f041164: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f041168: 0c00581e */ jal mtx4LoadXRotation
|
|
/* f04116c: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f041170: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f041174: 0c005841 */ jal mtx4LoadYRotation
|
|
/* f041178: 27a500dc */ addiu $a1,$sp,0xdc
|
|
/* f04117c: 27a400dc */ addiu $a0,$sp,0xdc
|
|
/* f041180: 0c00565c */ jal mtx00015be0
|
|
/* f041184: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f041188: c7ac0168 */ lwc1 $f12,0x168($sp)
|
|
/* f04118c: c7a401e0 */ lwc1 $f4,0x1e0($sp)
|
|
/* f041190: c7b001e4 */ lwc1 $f16,0x1e4($sp)
|
|
/* f041194: c7a801e8 */ lwc1 $f8,0x1e8($sp)
|
|
/* f041198: 460c2182 */ mul.s $f6,$f4,$f12
|
|
/* f04119c: c7a200cc */ lwc1 $f2,0xcc($sp)
|
|
/* f0411a0: 3c01800a */ lui $at,0x800a
|
|
/* f0411a4: 460c8282 */ mul.s $f10,$f16,$f12
|
|
/* f0411a8: c420a55c */ lwc1 $f0,-0x5aa4($at)
|
|
/* f0411ac: 8fac00d4 */ lw $t4,0xd4($sp)
|
|
/* f0411b0: 460c4482 */ mul.s $f18,$f8,$f12
|
|
/* f0411b4: e7a6015c */ swc1 $f6,0x15c($sp)
|
|
/* f0411b8: 8fa401b8 */ lw $a0,0x1b8($sp)
|
|
/* f0411bc: 46022102 */ mul.s $f4,$f4,$f2
|
|
/* f0411c0: e7aa0160 */ swc1 $f10,0x160($sp)
|
|
/* f0411c4: 2401ffff */ li $at,-1
|
|
/* f0411c8: 46003182 */ mul.s $f6,$f6,$f0
|
|
/* f0411cc: e7b20164 */ swc1 $f18,0x164($sp)
|
|
/* f0411d0: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f0411d4: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f0411d8: 27a7011c */ addiu $a3,$sp,0x11c
|
|
/* f0411dc: 27ab016c */ addiu $t3,$sp,0x16c
|
|
/* f0411e0: 27aa0178 */ addiu $t2,$sp,0x178
|
|
/* f0411e4: 46062100 */ add.s $f4,$f4,$f6
|
|
/* f0411e8: 46028182 */ mul.s $f6,$f16,$f2
|
|
/* f0411ec: e7a4016c */ swc1 $f4,0x16c($sp)
|
|
/* f0411f0: 46005102 */ mul.s $f4,$f10,$f0
|
|
/* f0411f4: 46043400 */ add.s $f16,$f6,$f4
|
|
/* f0411f8: 46024282 */ mul.s $f10,$f8,$f2
|
|
/* f0411fc: 00000000 */ nop
|
|
/* f041200: 46009182 */ mul.s $f6,$f18,$f0
|
|
/* f041204: e7b00170 */ swc1 $f16,0x170($sp)
|
|
/* f041208: 46065100 */ add.s $f4,$f10,$f6
|
|
/* f04120c: e7a40174 */ swc1 $f4,0x174($sp)
|
|
/* f041210: 8d8d0058 */ lw $t5,0x58($t4)
|
|
/* f041214: a48d0062 */ sh $t5,0x62($a0)
|
|
/* f041218: 84820062 */ lh $v0,0x62($a0)
|
|
/* f04121c: 1041000a */ beq $v0,$at,.PF0f041248
|
|
/* f041220: 0002c880 */ sll $t9,$v0,0x2
|
|
/* f041224: 0322c823 */ subu $t9,$t9,$v0
|
|
/* f041228: 0019c8c0 */ sll $t9,$t9,0x3
|
|
/* f04122c: 0322c821 */ addu $t9,$t9,$v0
|
|
/* f041230: 0019c8c0 */ sll $t9,$t9,0x3
|
|
/* f041234: 2401003c */ li $at,0x3c
|
|
/* f041238: 0321001a */ div $zero,$t9,$at
|
|
/* f04123c: 00007012 */ mflo $t6
|
|
/* f041240: a48e0062 */ sh $t6,0x62($a0)
|
|
/* f041244: 00000000 */ nop
|
|
.PF0f041248:
|
|
/* f041248: 8faf0274 */ lw $t7,0x274($sp)
|
|
/* f04124c: afab0010 */ sw $t3,0x10($sp)
|
|
/* f041250: afaa0014 */ sw $t2,0x14($sp)
|
|
/* f041254: afa5001c */ sw $a1,0x1c($sp)
|
|
/* f041258: 0fc27bac */ jal bgun0f09ebcc
|
|
/* f04125c: afaf0018 */ sw $t7,0x18($sp)
|
|
/* f041260: 8fa301b8 */ lw $v1,0x1b8($sp)
|
|
/* f041264: 8fad00d4 */ lw $t5,0xd4($sp)
|
|
/* f041268: 8c780040 */ lw $t8,0x40($v1)
|
|
/* f04126c: 330c0080 */ andi $t4,$t8,0x80
|
|
/* f041270: 11800047 */ beqz $t4,.PF0f041390
|
|
/* f041274: 00000000 */ nop
|
|
/* f041278: 8da20010 */ lw $v0,0x10($t5)
|
|
/* f04127c: 0002c800 */ sll $t9,$v0,0x0
|
|
/* f041280: 07210007 */ bgez $t9,.PF0f0412a0
|
|
/* f041284: 00025100 */ sll $t2,$v0,0x4
|
|
/* f041288: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f04128c: 3c014000 */ lui $at,0x4000
|
|
/* f041290: 8c4e0000 */ lw $t6,0x0($v0)
|
|
/* f041294: 01c15825 */ or $t3,$t6,$at
|
|
/* f041298: 10000007 */ b .PF0f0412b8
|
|
/* f04129c: ac4b0000 */ sw $t3,0x0($v0)
|
|
.PF0f0412a0:
|
|
/* f0412a0: 05430006 */ bgezl $t2,.PF0f0412bc
|
|
/* f0412a4: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
/* f0412a8: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f0412ac: 8c4f0000 */ lw $t7,0x0($v0)
|
|
/* f0412b0: 35f80010 */ ori $t8,$t7,0x10
|
|
/* f0412b4: ac580000 */ sw $t8,0x0($v0)
|
|
.PF0f0412b8:
|
|
/* f0412b8: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
.PF0f0412bc:
|
|
/* f0412bc: 8c6c0048 */ lw $t4,0x48($v1)
|
|
/* f0412c0: 240e00c8 */ li $t6,0xc8
|
|
/* f0412c4: 3c017f1b */ lui $at,0x7f1b
|
|
/* f0412c8: e5900010 */ swc1 $f16,0x10($t4)
|
|
/* f0412cc: 8c6d0048 */ lw $t5,0x48($v1)
|
|
/* f0412d0: c7a80160 */ lwc1 $f8,0x160($sp)
|
|
/* f0412d4: e5a80014 */ swc1 $f8,0x14($t5)
|
|
/* f0412d8: 8c790048 */ lw $t9,0x48($v1)
|
|
/* f0412dc: c7b20164 */ lwc1 $f18,0x164($sp)
|
|
/* f0412e0: e7320018 */ swc1 $f18,0x18($t9)
|
|
/* f0412e4: 8c6b0048 */ lw $t3,0x48($v1)
|
|
/* f0412e8: ad6e00b4 */ sw $t6,0xb4($t3)
|
|
/* f0412ec: 8faa00d4 */ lw $t2,0xd4($sp)
|
|
/* f0412f0: 8c6f0048 */ lw $t7,0x48($v1)
|
|
/* f0412f4: c54a005c */ lwc1 $f10,0x5c($t2)
|
|
/* f0412f8: e5ea008c */ swc1 $f10,0x8c($t7)
|
|
/* f0412fc: 8fb800d4 */ lw $t8,0xd4($sp)
|
|
/* f041300: c424a33c */ lwc1 $f4,-0x5cc4($at)
|
|
/* f041304: 8c6c0048 */ lw $t4,0x48($v1)
|
|
/* f041308: c7060050 */ lwc1 $f6,0x50($t8)
|
|
/* f04130c: 46043402 */ mul.s $f16,$f6,$f4
|
|
/* f041310: e5900098 */ swc1 $f16,0x98($t4)
|
|
/* f041314: 0fc0a26a */ jal chrGetTargetProp
|
|
/* f041318: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f04131c: 8fad01b8 */ lw $t5,0x1b8($sp)
|
|
/* f041320: 3c01bf80 */ lui $at,0xbf80
|
|
/* f041324: 00002025 */ move $a0,$zero
|
|
/* f041328: 8db90048 */ lw $t9,0x48($t5)
|
|
/* f04132c: 2407ffff */ li $a3,-1
|
|
/* f041330: 240bffff */ li $t3,-1
|
|
/* f041334: af2200e8 */ sw $v0,0xe8($t9)
|
|
/* f041338: 8fae00d4 */ lw $t6,0xd4($sp)
|
|
/* f04133c: 240affff */ li $t2,-1
|
|
/* f041340: 85c60060 */ lh $a2,0x60($t6)
|
|
/* f041344: 18c00012 */ blez $a2,.PF0f041390
|
|
/* f041348: 00000000 */ nop
|
|
/* f04134c: 8da50014 */ lw $a1,0x14($t5)
|
|
/* f041350: 44810000 */ mtc1 $at,$f0
|
|
/* f041354: afaa002c */ sw $t2,0x2c($sp)
|
|
/* f041358: afa00028 */ sw $zero,0x28($sp)
|
|
/* f04135c: afa00020 */ sw $zero,0x20($sp)
|
|
/* f041360: afa0001c */ sw $zero,0x1c($sp)
|
|
/* f041364: afa00018 */ sw $zero,0x18($sp)
|
|
/* f041368: afa00014 */ sw $zero,0x14($sp)
|
|
/* f04136c: afab0010 */ sw $t3,0x10($sp)
|
|
/* f041370: e7a00024 */ swc1 $f0,0x24($sp)
|
|
/* f041374: e7a00030 */ swc1 $f0,0x30($sp)
|
|
/* f041378: e7a00034 */ swc1 $f0,0x34($sp)
|
|
/* f04137c: 0fc24e3a */ jal propsnd0f0939f8
|
|
/* f041380: e7a00038 */ swc1 $f0,0x38($sp)
|
|
/* f041384: 10000002 */ b .PF0f041390
|
|
/* f041388: 00000000 */ nop
|
|
/* f04138c: afa00268 */ sw $zero,0x268($sp)
|
|
.PF0f041390:
|
|
/* f041390: 10000019 */ b .PF0f0413f8
|
|
/* f041394: a3a0026e */ sb $zero,0x26e($sp)
|
|
/* f041398: 24010006 */ li $at,0x6
|
|
.PF0f04139c:
|
|
/* f04139c: 14810016 */ bne $a0,$at,.PF0f0413f8
|
|
/* f0413a0: 93af026f */ lbu $t7,0x26f($sp)
|
|
/* f0413a4: 11e00014 */ beqz $t7,.PF0f0413f8
|
|
/* f0413a8: 93b80263 */ lbu $t8,0x263($sp)
|
|
/* f0413ac: 24010001 */ li $at,0x1
|
|
/* f0413b0: 17010011 */ bne $t8,$at,.PF0f0413f8
|
|
/* f0413b4: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f0413b8: 8fa2027c */ lw $v0,0x27c($sp)
|
|
/* f0413bc: 8f2e02d4 */ lw $t6,0x2d4($t9)
|
|
/* f0413c0: 3c014120 */ lui $at,0x4120
|
|
/* f0413c4: 00026080 */ sll $t4,$v0,0x2
|
|
/* f0413c8: 01cc6821 */ addu $t5,$t6,$t4
|
|
/* f0413cc: c5a800e4 */ lwc1 $f8,0xe4($t5)
|
|
/* f0413d0: 44819000 */ mtc1 $at,$f18
|
|
/* f0413d4: 44802000 */ mtc1 $zero,$f4
|
|
/* f0413d8: 46124282 */ mul.s $f10,$f8,$f18
|
|
/* f0413dc: 4600518d */ trunc.w.s $f6,$f10
|
|
/* f0413e0: 440a3000 */ mfc1 $t2,$f6
|
|
/* f0413e4: 00000000 */ nop
|
|
/* f0413e8: a3aa0262 */ sb $t2,0x262($sp)
|
|
/* f0413ec: 8f2f02d4 */ lw $t7,0x2d4($t9)
|
|
/* f0413f0: 01ecc021 */ addu $t8,$t7,$t4
|
|
/* f0413f4: e70400e4 */ swc1 $f4,0xe4($t8)
|
|
.PF0f0413f8:
|
|
/* f0413f8: 93ac026e */ lbu $t4,0x26e($sp)
|
|
/* f0413fc: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f041400: 518001c0 */ beqzl $t4,.PF0f041b04
|
|
/* f041404: 8fab01c0 */ lw $t3,0x1c0($sp)
|
|
/* f041408: 15c000d6 */ bnez $t6,.PF0f041764
|
|
/* f04140c: 8fad0258 */ lw $t5,0x258($sp)
|
|
/* f041410: 31ab0200 */ andi $t3,$t5,0x200
|
|
/* f041414: 1160004c */ beqz $t3,.PF0f041548
|
|
/* f041418: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f04141c: 91590000 */ lbu $t9,0x0($t2)
|
|
/* f041420: 24010006 */ li $at,0x6
|
|
/* f041424: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041428: 17210047 */ bne $t9,$at,.PF0f041548
|
|
/* f04142c: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f041430: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f041434: 0fc0e4dc */ jal chrCanSeeAttackTarget
|
|
/* f041438: 00003825 */ move $a3,$zero
|
|
/* f04143c: 10400042 */ beqz $v0,.PF0f041548
|
|
/* f041440: 8faf025c */ lw $t7,0x25c($sp)
|
|
/* f041444: 8de40004 */ lw $a0,0x4($t7)
|
|
/* f041448: 8fa50278 */ lw $a1,0x278($sp)
|
|
/* f04144c: 0fc12b09 */ jal chrCompareTeams
|
|
/* f041450: 24060002 */ li $a2,0x2
|
|
/* f041454: 1040003c */ beqz $v0,.PF0f041548
|
|
/* f041458: 3c014170 */ lui $at,0x4170
|
|
/* f04145c: 44817000 */ mtc1 $at,$f14
|
|
/* f041460: 8fb8025c */ lw $t8,0x25c($sp)
|
|
/* f041464: c7aa01e0 */ lwc1 $f10,0x1e0($sp)
|
|
/* f041468: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f04146c: c7100008 */ lwc1 $f16,0x8($t8)
|
|
/* f041470: 460e5182 */ mul.s $f6,$f10,$f14
|
|
/* f041474: c7aa01e4 */ lwc1 $f10,0x1e4($sp)
|
|
/* f041478: 46088481 */ sub.s $f18,$f16,$f8
|
|
/* f04147c: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f041480: c704000c */ lwc1 $f4,0xc($t8)
|
|
/* f041484: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041488: 27a501f8 */ addiu $a1,$sp,0x1f8
|
|
/* f04148c: 46069001 */ sub.s $f0,$f18,$f6
|
|
/* f041490: 460e5482 */ mul.s $f18,$f10,$f14
|
|
/* f041494: c7aa01e8 */ lwc1 $f10,0x1e8($sp)
|
|
/* f041498: 46102201 */ sub.s $f8,$f4,$f16
|
|
/* f04149c: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f0414a0: c7060010 */ lwc1 $f6,0x10($t8)
|
|
/* f0414a4: 27a601f4 */ addiu $a2,$sp,0x1f4
|
|
/* f0414a8: 46124081 */ sub.s $f2,$f8,$f18
|
|
/* f0414ac: 460e5202 */ mul.s $f8,$f10,$f14
|
|
/* f0414b0: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f0414b4: 46043401 */ sub.s $f16,$f6,$f4
|
|
/* f0414b8: 46000182 */ mul.s $f6,$f0,$f0
|
|
/* f0414bc: 00000000 */ nop
|
|
/* f0414c0: 46021102 */ mul.s $f4,$f2,$f2
|
|
/* f0414c4: 46088301 */ sub.s $f12,$f16,$f8
|
|
/* f0414c8: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f0414cc: 46043280 */ add.s $f10,$f6,$f4
|
|
/* f0414d0: 46105200 */ add.s $f8,$f10,$f16
|
|
/* f0414d4: 4612403e */ c.le.s $f8,$f18
|
|
/* f0414d8: 00000000 */ nop
|
|
/* f0414dc: 4500002b */ bc1f .PF0f04158c
|
|
/* f0414e0: 00000000 */ nop
|
|
/* f0414e4: 0fc0ff0d */ jal chrCalculateHit
|
|
/* f0414e8: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f0414ec: 8fac01f4 */ lw $t4,0x1f4($sp)
|
|
/* f0414f0: 8fad01f8 */ lw $t5,0x1f8($sp)
|
|
/* f0414f4: 8fab0278 */ lw $t3,0x278($sp)
|
|
/* f0414f8: 2d8e0001 */ sltiu $t6,$t4,0x1
|
|
/* f0414fc: 11a00023 */ beqz $t5,.PF0f04158c
|
|
/* f041500: afae01f0 */ sw $t6,0x1f0($sp)
|
|
/* f041504: 81630007 */ lb $v1,0x7($t3)
|
|
/* f041508: 24010008 */ li $at,0x8
|
|
/* f04150c: 3c0a800a */ lui $t2,0x800a
|
|
/* f041510: 1061000a */ beq $v1,$at,.PF0f04153c
|
|
/* f041514: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f041518: 2401000a */ li $at,0xa
|
|
/* f04151c: 10610007 */ beq $v1,$at,.PF0f04153c
|
|
/* f041520: 2401001b */ li $at,0x1b
|
|
/* f041524: 10610005 */ beq $v1,$at,.PF0f04153c
|
|
/* f041528: 2401001c */ li $at,0x1c
|
|
/* f04152c: 10610003 */ beq $v1,$at,.PF0f04153c
|
|
/* f041530: 2401001d */ li $at,0x1d
|
|
/* f041534: 54610016 */ bnel $v1,$at,.PF0f041590
|
|
/* f041538: 8fae01f4 */ lw $t6,0x1f4($sp)
|
|
.PF0f04153c:
|
|
/* f04153c: 8d4aa518 */ lw $t2,-0x5ae8($t2)
|
|
/* f041540: 10000012 */ b .PF0f04158c
|
|
/* f041544: af2a0048 */ sw $t2,0x48($t9)
|
|
.PF0f041548:
|
|
/* f041548: 8faf0278 */ lw $t7,0x278($sp)
|
|
/* f04154c: 24010008 */ li $at,0x8
|
|
/* f041550: 3c18800a */ lui $t8,0x800a
|
|
/* f041554: 81e30007 */ lb $v1,0x7($t7)
|
|
/* f041558: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f04155c: 10610009 */ beq $v1,$at,.PF0f041584
|
|
/* f041560: 2401000a */ li $at,0xa
|
|
/* f041564: 10610007 */ beq $v1,$at,.PF0f041584
|
|
/* f041568: 2401001b */ li $at,0x1b
|
|
/* f04156c: 10610005 */ beq $v1,$at,.PF0f041584
|
|
/* f041570: 2401001c */ li $at,0x1c
|
|
/* f041574: 10610003 */ beq $v1,$at,.PF0f041584
|
|
/* f041578: 2401001d */ li $at,0x1d
|
|
/* f04157c: 54610004 */ bnel $v1,$at,.PF0f041590
|
|
/* f041580: 8fae01f4 */ lw $t6,0x1f4($sp)
|
|
.PF0f041584:
|
|
/* f041584: 8f18a518 */ lw $t8,-0x5ae8($t8)
|
|
/* f041588: ad980048 */ sw $t8,0x48($t4)
|
|
.PF0f04158c:
|
|
/* f04158c: 8fae01f4 */ lw $t6,0x1f4($sp)
|
|
.PF0f041590:
|
|
/* f041590: 8faf01cc */ lw $t7,0x1cc($sp)
|
|
/* f041594: 11c00065 */ beqz $t6,.PF0f04172c
|
|
/* f041598: 00000000 */ nop
|
|
/* f04159c: 0fc2c87a */ jal gsetGetDamage
|
|
/* f0415a0: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f0415a4: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f0415a8: 240dffff */ li $t5,-1
|
|
/* f0415ac: 240b00c8 */ li $t3,0xc8
|
|
/* f0415b0: e7a0009c */ swc1 $f0,0x9c($sp)
|
|
/* f0415b4: afa00098 */ sw $zero,0x98($sp)
|
|
/* f0415b8: afa00094 */ sw $zero,0x94($sp)
|
|
/* f0415bc: afad0090 */ sw $t5,0x90($sp)
|
|
/* f0415c0: afab008c */ sw $t3,0x8c($sp)
|
|
/* f0415c4: 8d590004 */ lw $t9,0x4($t2)
|
|
/* f0415c8: afb90088 */ sw $t9,0x88($sp)
|
|
/* f0415cc: c5460008 */ lwc1 $f6,0x8($t2)
|
|
/* f0415d0: e7a60228 */ swc1 $f6,0x228($sp)
|
|
/* f0415d4: c544000c */ lwc1 $f4,0xc($t2)
|
|
/* f0415d8: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
/* f0415dc: c54a0010 */ lwc1 $f10,0x10($t2)
|
|
/* f0415e0: 0c004ad4 */ jal random
|
|
/* f0415e4: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f0415e8: 304f0001 */ andi $t7,$v0,0x1
|
|
/* f0415ec: 11e00012 */ beqz $t7,.PF0f041638
|
|
/* f0415f0: 00000000 */ nop
|
|
/* f0415f4: 0c004ad4 */ jal random
|
|
/* f0415f8: 00000000 */ nop
|
|
/* f0415fc: 2401000a */ li $at,0xa
|
|
/* f041600: 0041001b */ divu $zero,$v0,$at
|
|
/* f041604: 0000c010 */ mfhi $t8
|
|
/* f041608: 270c0002 */ addiu $t4,$t8,0x2
|
|
/* f04160c: 448c9000 */ mtc1 $t4,$f18
|
|
/* f041610: c7b0022c */ lwc1 $f16,0x22c($sp)
|
|
/* f041614: 05810005 */ bgez $t4,.PF0f04162c
|
|
/* f041618: 46809220 */ cvt.s.w $f8,$f18
|
|
/* f04161c: 3c014f80 */ lui $at,0x4f80
|
|
/* f041620: 44813000 */ mtc1 $at,$f6
|
|
/* f041624: 00000000 */ nop
|
|
/* f041628: 46064200 */ add.s $f8,$f8,$f6
|
|
.PF0f04162c:
|
|
/* f04162c: 46088100 */ add.s $f4,$f16,$f8
|
|
/* f041630: 10000011 */ b .PF0f041678
|
|
/* f041634: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
.PF0f041638:
|
|
/* f041638: 0c004ad4 */ jal random
|
|
/* f04163c: 00000000 */ nop
|
|
/* f041640: 2401000a */ li $at,0xa
|
|
/* f041644: 0041001b */ divu $zero,$v0,$at
|
|
/* f041648: 00007010 */ mfhi $t6
|
|
/* f04164c: 25cd0002 */ addiu $t5,$t6,0x2
|
|
/* f041650: 448d9000 */ mtc1 $t5,$f18
|
|
/* f041654: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f041658: 05a10005 */ bgez $t5,.PF0f041670
|
|
/* f04165c: 468091a0 */ cvt.s.w $f6,$f18
|
|
/* f041660: 3c014f80 */ lui $at,0x4f80
|
|
/* f041664: 44818000 */ mtc1 $at,$f16
|
|
/* f041668: 00000000 */ nop
|
|
/* f04166c: 46103180 */ add.s $f6,$f6,$f16
|
|
.PF0f041670:
|
|
/* f041670: 46065201 */ sub.s $f8,$f10,$f6
|
|
/* f041674: e7a8022c */ swc1 $f8,0x22c($sp)
|
|
.PF0f041678:
|
|
/* f041678: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f04167c: 8fa5025c */ lw $a1,0x25c($sp)
|
|
/* f041680: 0fc2a079 */ jal bgunPlayPropHitSound
|
|
/* f041684: 2406ffff */ li $a2,-1
|
|
/* f041688: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f04168c: 8c8b0020 */ lw $t3,0x20($a0)
|
|
/* f041690: 51600012 */ beqzl $t3,.PF0f0416dc
|
|
/* f041694: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f041698: 0fc0d042 */ jal chrGetShield
|
|
/* f04169c: 00000000 */ nop
|
|
/* f0416a0: 44802000 */ mtc1 $zero,$f4
|
|
/* f0416a4: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f0416a8: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f0416ac: 4600203c */ c.lt.s $f4,$f0
|
|
/* f0416b0: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f0416b4: 27a70098 */ addiu $a3,$sp,0x98
|
|
/* f0416b8: 27b9008c */ addiu $t9,$sp,0x8c
|
|
/* f0416bc: 45000006 */ bc1f .PF0f0416d8
|
|
/* f0416c0: 27aa0094 */ addiu $t2,$sp,0x94
|
|
/* f0416c4: 27af0090 */ addiu $t7,$sp,0x90
|
|
/* f0416c8: afaf0018 */ sw $t7,0x18($sp)
|
|
/* f0416cc: afb90010 */ sw $t9,0x10($sp)
|
|
/* f0416d0: 0fc1002c */ jal chrCalculateShieldHit
|
|
/* f0416d4: afaa0014 */ sw $t2,0x14($sp)
|
|
.PF0f0416d8:
|
|
/* f0416d8: 8fb80278 */ lw $t8,0x278($sp)
|
|
.PF0f0416dc:
|
|
/* f0416dc: 8fad025c */ lw $t5,0x25c($sp)
|
|
/* f0416e0: 8fab0098 */ lw $t3,0x98($sp)
|
|
/* f0416e4: 8f0c001c */ lw $t4,0x1c($t8)
|
|
/* f0416e8: 8fb90094 */ lw $t9,0x94($sp)
|
|
/* f0416ec: 8faa0090 */ lw $t2,0x90($sp)
|
|
/* f0416f0: 240e00c8 */ li $t6,0xc8
|
|
/* f0416f4: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f0416f8: afae0014 */ sw $t6,0x14($sp)
|
|
/* f0416fc: afa00028 */ sw $zero,0x28($sp)
|
|
/* f041700: 8fa5009c */ lw $a1,0x9c($sp)
|
|
/* f041704: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041708: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f04170c: afad0018 */ sw $t5,0x18($sp)
|
|
/* f041710: afab001c */ sw $t3,0x1c($sp)
|
|
/* f041714: afac0010 */ sw $t4,0x10($sp)
|
|
/* f041718: afb90020 */ sw $t9,0x20($sp)
|
|
/* f04171c: 0fc0d0d1 */ jal func0f0341dc
|
|
/* f041720: afaa0024 */ sw $t2,0x24($sp)
|
|
/* f041724: 10000010 */ b .PF0f041768
|
|
/* f041728: 8fb801f0 */ lw $t8,0x1f0($sp)
|
|
.PF0f04172c:
|
|
/* f04172c: 11e00006 */ beqz $t7,.PF0f041748
|
|
/* f041730: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f041734: 91e20000 */ lbu $v0,0x0($t7)
|
|
/* f041738: 24010003 */ li $at,0x3
|
|
/* f04173c: 10410009 */ beq $v0,$at,.PF0f041764
|
|
/* f041740: 24010006 */ li $at,0x6
|
|
/* f041744: 10410007 */ beq $v0,$at,.PF0f041764
|
|
.PF0f041748:
|
|
/* f041748: 3c017f1b */ lui $at,0x7f1b
|
|
/* f04174c: c430a340 */ lwc1 $f16,-0x5cc0($at)
|
|
/* f041750: 4610903c */ c.lt.s $f18,$f16
|
|
/* f041754: 00000000 */ nop
|
|
/* f041758: 45020003 */ bc1fl .PF0f041768
|
|
/* f04175c: 8fb801f0 */ lw $t8,0x1f0($sp)
|
|
/* f041760: afa001f0 */ sw $zero,0x1f0($sp)
|
|
.PF0f041764:
|
|
/* f041764: 8fb801f0 */ lw $t8,0x1f0($sp)
|
|
.PF0f041768:
|
|
/* f041768: 8fac01cc */ lw $t4,0x1cc($sp)
|
|
/* f04176c: 530000e5 */ beqzl $t8,.PF0f041b04
|
|
/* f041770: 8fab01c0 */ lw $t3,0x1c0($sp)
|
|
/* f041774: 118000a2 */ beqz $t4,.PF0f041a00
|
|
/* f041778: 8fab0224 */ lw $t3,0x224($sp)
|
|
/* f04177c: 91820000 */ lbu $v0,0x0($t4)
|
|
/* f041780: 24010006 */ li $at,0x6
|
|
/* f041784: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f041788: 10410003 */ beq $v0,$at,.PF0f041798
|
|
/* f04178c: 24010003 */ li $at,0x3
|
|
/* f041790: 54410053 */ bnel $v0,$at,.PF0f0418e0
|
|
/* f041794: 24010001 */ li $at,0x1
|
|
.PF0f041798:
|
|
/* f041798: 15c0000c */ bnez $t6,.PF0f0417cc
|
|
/* f04179c: 8fad01bc */ lw $t5,0x1bc($sp)
|
|
/* f0417a0: 15a0000a */ bnez $t5,.PF0f0417cc
|
|
/* f0417a4: 8fab0278 */ lw $t3,0x278($sp)
|
|
/* f0417a8: 8d790018 */ lw $t9,0x18($t3)
|
|
/* f0417ac: 8faf01cc */ lw $t7,0x1cc($sp)
|
|
/* f0417b0: 01602825 */ move $a1,$t3
|
|
/* f0417b4: 332a0040 */ andi $t2,$t9,0x40
|
|
/* f0417b8: 11400045 */ beqz $t2,.PF0f0418d0
|
|
/* f0417bc: 24060002 */ li $a2,0x2
|
|
/* f0417c0: 0fc12b09 */ jal chrCompareTeams
|
|
/* f0417c4: 8de40004 */ lw $a0,0x4($t7)
|
|
/* f0417c8: 10400041 */ beqz $v0,.PF0f0418d0
|
|
.PF0f0417cc:
|
|
/* f0417cc: 2418ffff */ li $t8,-1
|
|
/* f0417d0: 240c00c8 */ li $t4,0xc8
|
|
/* f0417d4: afa00084 */ sw $zero,0x84($sp)
|
|
/* f0417d8: afa00080 */ sw $zero,0x80($sp)
|
|
/* f0417dc: afb8007c */ sw $t8,0x7c($sp)
|
|
/* f0417e0: afac0078 */ sw $t4,0x78($sp)
|
|
/* f0417e4: 0fc2c87a */ jal gsetGetDamage
|
|
/* f0417e8: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f0417ec: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0417f0: e7a00074 */ swc1 $f0,0x74($sp)
|
|
/* f0417f4: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f0417f8: 8cad0004 */ lw $t5,0x4($a1)
|
|
/* f0417fc: 2406ffff */ li $a2,-1
|
|
/* f041800: 0fc2a079 */ jal bgunPlayPropHitSound
|
|
/* f041804: afad0070 */ sw $t5,0x70($sp)
|
|
/* f041808: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f04180c: 8c990020 */ lw $t9,0x20($a0)
|
|
/* f041810: 53200012 */ beqzl $t9,.PF0f04185c
|
|
/* f041814: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f041818: 0fc0d042 */ jal chrGetShield
|
|
/* f04181c: 00000000 */ nop
|
|
/* f041820: 44805000 */ mtc1 $zero,$f10
|
|
/* f041824: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041828: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f04182c: 4600503c */ c.lt.s $f10,$f0
|
|
/* f041830: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041834: 27a70084 */ addiu $a3,$sp,0x84
|
|
/* f041838: 27aa0078 */ addiu $t2,$sp,0x78
|
|
/* f04183c: 45000006 */ bc1f .PF0f041858
|
|
/* f041840: 27af0080 */ addiu $t7,$sp,0x80
|
|
/* f041844: 27ab007c */ addiu $t3,$sp,0x7c
|
|
/* f041848: afab0018 */ sw $t3,0x18($sp)
|
|
/* f04184c: afaa0010 */ sw $t2,0x10($sp)
|
|
/* f041850: 0fc1002c */ jal chrCalculateShieldHit
|
|
/* f041854: afaf0014 */ sw $t7,0x14($sp)
|
|
.PF0f041858:
|
|
/* f041858: 8fac0278 */ lw $t4,0x278($sp)
|
|
.PF0f04185c:
|
|
/* f04185c: 27b801e0 */ addiu $t8,$sp,0x1e0
|
|
/* f041860: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041864: afb80010 */ sw $t8,0x10($sp)
|
|
/* f041868: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f04186c: 8fa60078 */ lw $a2,0x78($sp)
|
|
/* f041870: 27a70228 */ addiu $a3,$sp,0x228
|
|
/* f041874: 0fc097f2 */ jal chrEmitSparks
|
|
/* f041878: afac0014 */ sw $t4,0x14($sp)
|
|
/* f04187c: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f041880: 8faa01cc */ lw $t2,0x1cc($sp)
|
|
/* f041884: 8faf0084 */ lw $t7,0x84($sp)
|
|
/* f041888: 8dae001c */ lw $t6,0x1c($t5)
|
|
/* f04188c: 8fab0080 */ lw $t3,0x80($sp)
|
|
/* f041890: 8fb8007c */ lw $t8,0x7c($sp)
|
|
/* f041894: 241900c8 */ li $t9,0xc8
|
|
/* f041898: afb90014 */ sw $t9,0x14($sp)
|
|
/* f04189c: afa00028 */ sw $zero,0x28($sp)
|
|
/* f0418a0: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f0418a4: 8fa50074 */ lw $a1,0x74($sp)
|
|
/* f0418a8: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f0418ac: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f0418b0: afaa0018 */ sw $t2,0x18($sp)
|
|
/* f0418b4: afaf001c */ sw $t7,0x1c($sp)
|
|
/* f0418b8: afae0010 */ sw $t6,0x10($sp)
|
|
/* f0418bc: afab0020 */ sw $t3,0x20($sp)
|
|
/* f0418c0: 0fc0d0d1 */ jal func0f0341dc
|
|
/* f0418c4: afb80024 */ sw $t8,0x24($sp)
|
|
/* f0418c8: 1000006f */ b .PF0f041a88
|
|
/* f0418cc: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PF0f0418d0:
|
|
/* f0418d0: afa00250 */ sw $zero,0x250($sp)
|
|
/* f0418d4: 1000006b */ b .PF0f041a84
|
|
/* f0418d8: afa00268 */ sw $zero,0x268($sp)
|
|
/* f0418dc: 24010001 */ li $at,0x1
|
|
.PF0f0418e0:
|
|
/* f0418e0: 10410005 */ beq $v0,$at,.PF0f0418f8
|
|
/* f0418e4: 8fac01cc */ lw $t4,0x1cc($sp)
|
|
/* f0418e8: 24010004 */ li $at,0x4
|
|
/* f0418ec: 10410002 */ beq $v0,$at,.PF0f0418f8
|
|
/* f0418f0: 24010002 */ li $at,0x2
|
|
/* f0418f4: 14410063 */ bne $v0,$at,.PF0f041a84
|
|
.PF0f0418f8:
|
|
/* f0418f8: 3c19800a */ lui $t9,0x800a
|
|
/* f0418fc: 8f39a824 */ lw $t9,-0x57dc($t9)
|
|
/* f041900: 8d8d0004 */ lw $t5,0x4($t4)
|
|
/* f041904: 240effff */ li $t6,-1
|
|
/* f041908: afae0068 */ sw $t6,0x68($sp)
|
|
/* f04190c: 13200004 */ beqz $t9,.PF0f041920
|
|
/* f041910: afad006c */ sw $t5,0x6c($sp)
|
|
/* f041914: 0fc63831 */ jal mpPlayerGetIndex
|
|
/* f041918: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f04191c: afa20068 */ sw $v0,0x68($sp)
|
|
.PF0f041920:
|
|
/* f041920: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041924: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f041928: 0fc2a079 */ jal bgunPlayPropHitSound
|
|
/* f04192c: 2406ffff */ li $a2,-1
|
|
/* f041930: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041934: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041938: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f04193c: 0fc19841 */ jal func0f065e74
|
|
/* f041940: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041944: 240a0001 */ li $t2,0x1
|
|
/* f041948: afaa0210 */ sw $t2,0x210($sp)
|
|
/* f04194c: 0fc4fc06 */ jal chrIsUsingPaintball
|
|
/* f041950: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041954: 1040000b */ beqz $v0,.PF0f041984
|
|
/* f041958: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f04195c: 240f0019 */ li $t7,0x19
|
|
/* f041960: afaf0014 */ sw $t7,0x14($sp)
|
|
/* f041964: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f041968: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f04196c: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041970: 00003825 */ move $a3,$zero
|
|
/* f041974: 0fc4c159 */ jal sparksCreate
|
|
/* f041978: afa00010 */ sw $zero,0x10($sp)
|
|
/* f04197c: 10000007 */ b .PF0f04199c
|
|
/* f041980: 00000000 */ nop
|
|
.PF0f041984:
|
|
/* f041984: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f041988: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f04198c: 00003825 */ move $a3,$zero
|
|
/* f041990: afa00010 */ sw $zero,0x10($sp)
|
|
/* f041994: 0fc4c159 */ jal sparksCreate
|
|
/* f041998: afa00014 */ sw $zero,0x14($sp)
|
|
.PF0f04199c:
|
|
/* f04199c: 3c0b800a */ lui $t3,0x800a
|
|
/* f0419a0: 8178e58b */ lb $t8,-0x1a75($t3)
|
|
/* f0419a4: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f0419a8: 0701000a */ bgez $t8,.PF0f0419d4
|
|
/* f0419ac: 00000000 */ nop
|
|
/* f0419b0: 918d0125 */ lbu $t5,0x125($t4)
|
|
/* f0419b4: 24010010 */ li $at,0x10
|
|
/* f0419b8: 8fae006c */ lw $t6,0x6c($sp)
|
|
/* f0419bc: 15a10005 */ bne $t5,$at,.PF0f0419d4
|
|
/* f0419c0: 00000000 */ nop
|
|
/* f0419c4: 8dd9000c */ lw $t9,0xc($t6)
|
|
/* f0419c8: 332a0001 */ andi $t2,$t9,0x1
|
|
/* f0419cc: 5540002e */ bnezl $t2,.PF0f041a88
|
|
/* f0419d0: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PF0f0419d4:
|
|
/* f0419d4: 0fc2c87a */ jal gsetGetDamage
|
|
/* f0419d8: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f0419dc: 8faf0068 */ lw $t7,0x68($sp)
|
|
/* f0419e0: 44050000 */ mfc1 $a1,$f0
|
|
/* f0419e4: 8fa4006c */ lw $a0,0x6c($sp)
|
|
/* f0419e8: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0419ec: 93a70260 */ lbu $a3,0x260($sp)
|
|
/* f0419f0: 0fc21530 */ jal objTakeGunfire
|
|
/* f0419f4: afaf0010 */ sw $t7,0x10($sp)
|
|
/* f0419f8: 10000023 */ b .PF0f041a88
|
|
/* f0419fc: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PF0f041a00:
|
|
/* f041a00: 11600020 */ beqz $t3,.PF0f041a84
|
|
/* f041a04: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041a08: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041a0c: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041a10: 0fc19841 */ jal func0f065e74
|
|
/* f041a14: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041a18: 24180001 */ li $t8,0x1
|
|
/* f041a1c: afb80210 */ sw $t8,0x210($sp)
|
|
/* f041a20: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041a24: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041a28: 2406ffff */ li $a2,-1
|
|
/* f041a2c: 0fc2a245 */ jal bgunPlayBgHitSound
|
|
/* f041a30: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041a34: 0fc4fc06 */ jal chrIsUsingPaintball
|
|
/* f041a38: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041a3c: 1040000b */ beqz $v0,.PF0f041a6c
|
|
/* f041a40: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f041a44: 240c0019 */ li $t4,0x19
|
|
/* f041a48: afac0014 */ sw $t4,0x14($sp)
|
|
/* f041a4c: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f041a50: 00002825 */ move $a1,$zero
|
|
/* f041a54: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041a58: 00003825 */ move $a3,$zero
|
|
/* f041a5c: 0fc4c159 */ jal sparksCreate
|
|
/* f041a60: afa00010 */ sw $zero,0x10($sp)
|
|
/* f041a64: 10000008 */ b .PF0f041a88
|
|
/* f041a68: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PF0f041a6c:
|
|
/* f041a6c: 00002825 */ move $a1,$zero
|
|
/* f041a70: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041a74: 00003825 */ move $a3,$zero
|
|
/* f041a78: afa00010 */ sw $zero,0x10($sp)
|
|
/* f041a7c: 0fc4c159 */ jal sparksCreate
|
|
/* f041a80: afa00014 */ sw $zero,0x14($sp)
|
|
.PF0f041a84:
|
|
/* f041a84: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PF0f041a88:
|
|
/* f041a88: 24010007 */ li $at,0x7
|
|
/* f041a8c: 93ae0263 */ lbu $t6,0x263($sp)
|
|
/* f041a90: 15a1001b */ bne $t5,$at,.PF0f041b00
|
|
/* f041a94: 24010001 */ li $at,0x1
|
|
/* f041a98: 15c10019 */ bne $t6,$at,.PF0f041b00
|
|
/* f041a9c: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f041aa0: 8f2a02d4 */ lw $t2,0x2d4($t9)
|
|
/* f041aa4: 3c03800a */ lui $v1,0x800a
|
|
/* f041aa8: 11400005 */ beqz $t2,.PF0f041ac0
|
|
/* f041aac: 00000000 */ nop
|
|
/* f041ab0: 0fc63831 */ jal mpPlayerGetIndex
|
|
/* f041ab4: 03202025 */ move $a0,$t9
|
|
/* f041ab8: 10000002 */ b .PF0f041ac4
|
|
/* f041abc: 00401825 */ move $v1,$v0
|
|
.PF0f041ac0:
|
|
/* f041ac0: 8c63a79c */ lw $v1,-0x5864($v1)
|
|
.PF0f041ac4:
|
|
/* f041ac4: 8faf0210 */ lw $t7,0x210($sp)
|
|
/* f041ac8: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041acc: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041ad0: 15e00005 */ bnez $t7,.PF0f041ae8
|
|
/* f041ad4: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041ad8: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041adc: 0fc19841 */ jal func0f065e74
|
|
/* f041ae0: afa30064 */ sw $v1,0x64($sp)
|
|
/* f041ae4: 8fa30064 */ lw $v1,0x64($sp)
|
|
.PF0f041ae8:
|
|
/* f041ae8: 00002025 */ move $a0,$zero
|
|
/* f041aec: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041af0: 27a60214 */ addiu $a2,$sp,0x214
|
|
/* f041af4: 24070016 */ li $a3,0x16
|
|
/* f041af8: 0fc4a8f4 */ jal explosionCreateSimple
|
|
/* f041afc: afa30010 */ sw $v1,0x10($sp)
|
|
.PF0f041b00:
|
|
/* f041b00: 8fab01c0 */ lw $t3,0x1c0($sp)
|
|
.PF0f041b04:
|
|
/* f041b04: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f041b08: 51600004 */ beqzl $t3,.PF0f041b1c
|
|
/* f041b0c: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f041b10: 0fc19102 */ jal propSetPerimEnabled
|
|
/* f041b14: 00002825 */ move $a1,$zero
|
|
/* f041b18: 8fa80268 */ lw $t0,0x268($sp)
|
|
.PF0f041b1c:
|
|
/* f041b1c: 8fac0250 */ lw $t4,0x250($sp)
|
|
/* f041b20: 93ad0260 */ lbu $t5,0x260($sp)
|
|
/* f041b24: 0008c02b */ sltu $t8,$zero,$t0
|
|
/* f041b28: 1180000e */ beqz $t4,.PF0f041b64
|
|
/* f041b2c: 03004025 */ move $t0,$t8
|
|
/* f041b30: 25aefffe */ addiu $t6,$t5,-2
|
|
/* f041b34: 2dc1002a */ sltiu $at,$t6,0x2a
|
|
/* f041b38: 10200009 */ beqz $at,.PF0f041b60
|
|
/* f041b3c: 000e7080 */ sll $t6,$t6,0x2
|
|
/* f041b40: 3c017f1b */ lui $at,0x7f1b
|
|
/* f041b44: 002e0821 */ addu $at,$at,$t6
|
|
/* f041b48: 8c2ea344 */ lw $t6,-0x5cbc($at)
|
|
/* f041b4c: 01c00008 */ jr $t6
|
|
/* f041b50: 00000000 */ nop
|
|
/* f041b54: 240a0001 */ li $t2,0x1
|
|
/* f041b58: 10000002 */ b .PF0f041b64
|
|
/* f041b5c: afaa0250 */ sw $t2,0x250($sp)
|
|
.PF0f041b60:
|
|
/* f041b60: afa00250 */ sw $zero,0x250($sp)
|
|
.PF0f041b64:
|
|
/* f041b64: 11000004 */ beqz $t0,.PF0f041b78
|
|
/* f041b68: 01003825 */ move $a3,$t0
|
|
/* f041b6c: 8fa70250 */ lw $a3,0x250($sp)
|
|
/* f041b70: 0007c82b */ sltu $t9,$zero,$a3
|
|
/* f041b74: 03203825 */ move $a3,$t9
|
|
.PF0f041b78:
|
|
/* f041b78: 27af0244 */ addiu $t7,$sp,0x244
|
|
/* f041b7c: 27ab0228 */ addiu $t3,$sp,0x228
|
|
/* f041b80: afab0014 */ sw $t3,0x14($sp)
|
|
/* f041b84: afaf0010 */ sw $t7,0x10($sp)
|
|
/* f041b88: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041b8c: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041b90: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f041b94: 0fc0f908 */ jal chrCreateFireslot
|
|
/* f041b98: afa80054 */ sw $t0,0x54($sp)
|
|
/* f041b9c: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f041ba0: 8fa80054 */ lw $t0,0x54($sp)
|
|
/* f041ba4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041ba8: 13000015 */ beqz $t8,.PF0f041c00
|
|
/* f041bac: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041bb0: 1100000a */ beqz $t0,.PF0f041bdc
|
|
/* f041bb4: 01003025 */ move $a2,$t0
|
|
/* f041bb8: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f041bbc: 8fae027c */ lw $t6,0x27c($sp)
|
|
/* f041bc0: 8d8d02d4 */ lw $t5,0x2d4($t4)
|
|
/* f041bc4: 000e5080 */ sll $t2,$t6,0x2
|
|
/* f041bc8: 01aa1021 */ addu $v0,$t5,$t2
|
|
/* f041bcc: 8c430024 */ lw $v1,0x24($v0)
|
|
/* f041bd0: 18600002 */ blez $v1,.PF0f041bdc
|
|
/* f041bd4: 2479ffff */ addiu $t9,$v1,-1
|
|
/* f041bd8: ac590024 */ sw $t9,0x24($v0)
|
|
.PF0f041bdc:
|
|
/* f041bdc: 11000004 */ beqz $t0,.PF0f041bf0
|
|
/* f041be0: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041be4: 93a6026e */ lbu $a2,0x26e($sp)
|
|
/* f041be8: 0006782b */ sltu $t7,$zero,$a2
|
|
/* f041bec: 01e03025 */ move $a2,$t7
|
|
.PF0f041bf0:
|
|
/* f041bf0: 0fc0fe73 */ jal chrSetFiring
|
|
/* f041bf4: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041bf8: 10000004 */ b .PF0f041c0c
|
|
/* f041bfc: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.PF0f041c00:
|
|
/* f041c00: 0fc0fe73 */ jal chrSetFiring
|
|
/* f041c04: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f041c08: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.PF0f041c0c:
|
|
/* f041c0c: 27bd0278 */ addiu $sp,$sp,0x278
|
|
/* f041c10: 03e00008 */ jr $ra
|
|
/* f041c14: 00000000 */ nop
|
|
);
|
|
#elif VERSION == VERSION_PAL_BETA
|
|
GLOBAL_ASM(
|
|
glabel chrShoot
|
|
.late_rodata
|
|
glabel var7f1a90c8
|
|
.word 0x3d888889
|
|
glabel var7f1a90cc
|
|
.word 0x481c4000
|
|
glabel var7f1a90d0
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d4
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d8
|
|
.word 0x3fd55555
|
|
glabel var7f1a90dc
|
|
.word 0x461c4000
|
|
glabel var7f1a90e0
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90e4
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90e8
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90ec
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90f0
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90f4
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90f8
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a90fc
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9100
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9104
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9108
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a910c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9110
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9114
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9118
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a911c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9120
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9124
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9128
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a912c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9130
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9134
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9138
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a913c
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9140
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9144
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9148
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a914c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9150
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9154
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9158
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a915c
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9160
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9164
|
|
.word chrShoot+0x1508
|
|
glabel var7f1a9168
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a916c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9170
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9174
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9178
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a917c
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9180
|
|
.word chrShoot+0x14fc
|
|
glabel var7f1a9184
|
|
.word chrShoot+0x14fc
|
|
.text
|
|
/* f0405e4: 27bdfd88 */ addiu $sp,$sp,-632
|
|
/* f0405e8: afbf0044 */ sw $ra,0x44($sp)
|
|
/* f0405ec: afa5027c */ sw $a1,0x27c($sp)
|
|
/* f0405f0: 8c8e001c */ lw $t6,0x1c($a0)
|
|
/* f0405f4: 240f0001 */ li $t7,0x1
|
|
/* f0405f8: a3af026e */ sb $t7,0x26e($sp)
|
|
/* f0405fc: afae0274 */ sw $t6,0x274($sp)
|
|
/* f040600: 8c9802d4 */ lw $t8,0x2d4($a0)
|
|
/* f040604: 00001025 */ move $v0,$zero
|
|
/* f040608: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f04060c: 53000003 */ beqzl $t8,.PB0f04061c
|
|
/* f040610: a3a2026f */ sb $v0,0x26f($sp)
|
|
/* f040614: 24020001 */ li $v0,0x1
|
|
/* f040618: a3a2026f */ sb $v0,0x26f($sp)
|
|
.PB0f04061c:
|
|
/* f04061c: 0fc0a23d */ jal chrGetHeldProp
|
|
/* f040620: afa40278 */ sw $a0,0x278($sp)
|
|
/* f040624: 5040055c */ beqzl $v0,.PB0f041b98
|
|
/* f040628: 8fbf0044 */ lw $ra,0x44($sp)
|
|
/* f04062c: afa00268 */ sw $zero,0x268($sp)
|
|
/* f040630: 8c590004 */ lw $t9,0x4($v0)
|
|
/* f040634: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040638: 0fc0a255 */ jal chrGetTargetProp
|
|
/* f04063c: afb90264 */ sw $t9,0x264($sp)
|
|
/* f040640: 8fab0264 */ lw $t3,0x264($sp)
|
|
/* f040644: afa2025c */ sw $v0,0x25c($sp)
|
|
/* f040648: 8fa70278 */ lw $a3,0x278($sp)
|
|
/* f04064c: 8961005c */ lwl $at,0x5c($t3)
|
|
/* f040650: 9961005f */ lwr $at,0x5f($t3)
|
|
/* f040654: 27aa0260 */ addiu $t2,$sp,0x260
|
|
/* f040658: 24080200 */ li $t0,0x200
|
|
/* f04065c: ad410000 */ sw $at,0x0($t2)
|
|
/* f040660: 80e30007 */ lb $v1,0x7($a3)
|
|
/* f040664: 24010008 */ li $at,0x8
|
|
/* f040668: 10610007 */ beq $v1,$at,.PB0f040688
|
|
/* f04066c: 2401001b */ li $at,0x1b
|
|
/* f040670: 10610005 */ beq $v1,$at,.PB0f040688
|
|
/* f040674: 2401001c */ li $at,0x1c
|
|
/* f040678: 10610003 */ beq $v1,$at,.PB0f040688
|
|
/* f04067c: 2401001d */ li $at,0x1d
|
|
/* f040680: 54610003 */ bnel $v1,$at,.PB0f040690
|
|
/* f040684: afa00250 */ sw $zero,0x250($sp)
|
|
.PB0f040688:
|
|
/* f040688: 8ce8004c */ lw $t0,0x4c($a3)
|
|
/* f04068c: afa00250 */ sw $zero,0x250($sp)
|
|
.PB0f040690:
|
|
/* f040690: afa00224 */ sw $zero,0x224($sp)
|
|
/* f040694: afa00210 */ sw $zero,0x210($sp)
|
|
/* f040698: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f04069c: 93a50263 */ lbu $a1,0x263($sp)
|
|
/* f0406a0: afa00254 */ sw $zero,0x254($sp)
|
|
/* f0406a4: 0fc2c8be */ jal weaponGetNumTicksPerShot
|
|
/* f0406a8: afa80258 */ sw $t0,0x258($sp)
|
|
/* f0406ac: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f0406b0: 1c400005 */ bgtz $v0,.PB0f0406c8
|
|
/* f0406b4: 00402025 */ move $a0,$v0
|
|
/* f0406b8: 240f0001 */ li $t7,0x1
|
|
/* f0406bc: 24060001 */ li $a2,0x1
|
|
/* f0406c0: 10000055 */ b .PB0f040818
|
|
/* f0406c4: afaf0250 */ sw $t7,0x250($sp)
|
|
.PB0f0406c8:
|
|
/* f0406c8: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f0406cc: 8f0302d4 */ lw $v1,0x2d4($t8)
|
|
/* f0406d0: 5060001d */ beqzl $v1,.PB0f040748
|
|
/* f0406d4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f0406d8: 8c790020 */ lw $t9,0x20($v1)
|
|
/* f0406dc: 24010014 */ li $at,0x14
|
|
/* f0406e0: 57210019 */ bnel $t9,$at,.PB0f040748
|
|
/* f0406e4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f0406e8: 8c6d004c */ lw $t5,0x4c($v1)
|
|
/* f0406ec: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f0406f0: 000d5080 */ sll $t2,$t5,0x2
|
|
/* f0406f4: 05400013 */ bltz $t2,.PB0f040744
|
|
/* f0406f8: 000b7040 */ sll $t6,$t3,0x1
|
|
/* f0406fc: 006e7821 */ addu $t7,$v1,$t6
|
|
/* f040700: 85f800e0 */ lh $t8,0xe0($t7)
|
|
/* f040704: 2419004b */ li $t9,0x4b
|
|
/* f040708: 3c017f1b */ lui $at,0x7f1b
|
|
/* f04070c: 03386823 */ subu $t5,$t9,$t8
|
|
/* f040710: 448d2000 */ mtc1 $t5,$f4
|
|
/* f040714: c428adac */ lwc1 $f8,-0x5254($at)
|
|
/* f040718: 44825000 */ mtc1 $v0,$f10
|
|
/* f04071c: 468021a0 */ cvt.s.w $f6,$f4
|
|
/* f040720: 3c013f80 */ lui $at,0x3f80
|
|
/* f040724: 44819000 */ mtc1 $at,$f18
|
|
/* f040728: 46805420 */ cvt.s.w $f16,$f10
|
|
/* f04072c: 46083002 */ mul.s $f0,$f6,$f8
|
|
/* f040730: 46009100 */ add.s $f4,$f18,$f0
|
|
/* f040734: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f040738: 4600320d */ trunc.w.s $f8,$f6
|
|
/* f04073c: 44044000 */ mfc1 $a0,$f8
|
|
/* f040740: 00000000 */ nop
|
|
.PB0f040744:
|
|
/* f040744: 8faa0278 */ lw $t2,0x278($sp)
|
|
.PB0f040748:
|
|
/* f040748: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f04074c: 3c0f800a */ lui $t7,0x800a
|
|
/* f040750: 8defe508 */ lw $t7,-0x1af8($t7)
|
|
/* f040754: 014b1821 */ addu $v1,$t2,$t3
|
|
/* f040758: 906e0004 */ lbu $t6,0x4($v1)
|
|
/* f04075c: 01cfc821 */ addu $t9,$t6,$t7
|
|
/* f040760: 333800ff */ andi $t8,$t9,0xff
|
|
/* f040764: 0304082a */ slt $at,$t8,$a0
|
|
/* f040768: 1420002b */ bnez $at,.PB0f040818
|
|
/* f04076c: a0790004 */ sb $t9,0x4($v1)
|
|
/* f040770: a0600004 */ sb $zero,0x4($v1)
|
|
/* f040774: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f040778: 8fad027c */ lw $t5,0x27c($sp)
|
|
/* f04077c: 240c0001 */ li $t4,0x1
|
|
/* f040780: 8d4b032c */ lw $t3,0x32c($t2)
|
|
/* f040784: 01ac1004 */ sllv $v0,$t4,$t5
|
|
/* f040788: 24060001 */ li $a2,0x1
|
|
/* f04078c: 000b7300 */ sll $t6,$t3,0xc
|
|
/* f040790: 914b032d */ lbu $t3,0x32d($t2)
|
|
/* f040794: 000e7f82 */ srl $t7,$t6,0x1e
|
|
/* f040798: 01e2c026 */ xor $t8,$t7,$v0
|
|
/* f04079c: 00186080 */ sll $t4,$t8,0x2
|
|
/* f0407a0: 318d000c */ andi $t5,$t4,0xc
|
|
/* f0407a4: 316efff3 */ andi $t6,$t3,0xfff3
|
|
/* f0407a8: 01ae7825 */ or $t7,$t5,$t6
|
|
/* f0407ac: a14f032d */ sb $t7,0x32d($t2)
|
|
/* f0407b0: 8d59032c */ lw $t9,0x32c($t2)
|
|
/* f0407b4: 93ad0260 */ lbu $t5,0x260($sp)
|
|
/* f0407b8: 2401001d */ li $at,0x1d
|
|
/* f0407bc: 0019c300 */ sll $t8,$t9,0xc
|
|
/* f0407c0: 00186782 */ srl $t4,$t8,0x1e
|
|
/* f0407c4: 01825824 */ and $t3,$t4,$v0
|
|
/* f0407c8: 15600003 */ bnez $t3,.PB0f0407d8
|
|
/* f0407cc: 240e0001 */ li $t6,0x1
|
|
/* f0407d0: 55a10003 */ bnel $t5,$at,.PB0f0407e0
|
|
/* f0407d4: 8faf0278 */ lw $t7,0x278($sp)
|
|
.PB0f0407d8:
|
|
/* f0407d8: afae0250 */ sw $t6,0x250($sp)
|
|
/* f0407dc: 8faf0278 */ lw $t7,0x278($sp)
|
|
.PB0f0407e0:
|
|
/* f0407e0: 24010008 */ li $at,0x8
|
|
/* f0407e4: 81ea0007 */ lb $t2,0x7($t7)
|
|
/* f0407e8: 1541000b */ bne $t2,$at,.PB0f040818
|
|
/* f0407ec: 00000000 */ nop
|
|
/* f0407f0: 8de40020 */ lw $a0,0x20($t7)
|
|
/* f0407f4: 0c0076f3 */ jal modelGetAnimNum
|
|
/* f0407f8: afa60254 */ sw $a2,0x254($sp)
|
|
/* f0407fc: 2401026a */ li $at,0x26a
|
|
/* f040800: 14410005 */ bne $v0,$at,.PB0f040818
|
|
/* f040804: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f040808: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f04080c: 83380033 */ lb $t8,0x33($t9)
|
|
/* f040810: 270c0001 */ addiu $t4,$t8,0x1
|
|
/* f040814: a32c0033 */ sb $t4,0x33($t9)
|
|
.PB0f040818:
|
|
/* f040818: 50c004a3 */ beqzl $a2,.PB0f041aa8
|
|
/* f04081c: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f040820: 0fc0f9c0 */ jal chrGetAimAngle
|
|
/* f040824: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040828: e7a00204 */ swc1 $f0,0x204($sp)
|
|
/* f04082c: 0fc0fa19 */ jal func0f03e754
|
|
/* f040830: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040834: 93ab026f */ lbu $t3,0x26f($sp)
|
|
/* f040838: e7a00200 */ swc1 $f0,0x200($sp)
|
|
/* f04083c: 240e0001 */ li $t6,0x1
|
|
/* f040840: 11600004 */ beqz $t3,.PB0f040854
|
|
/* f040844: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f040848: 240d0004 */ li $t5,0x4
|
|
/* f04084c: 10000002 */ b .PB0f040858
|
|
/* f040850: afad01fc */ sw $t5,0x1fc($sp)
|
|
.PB0f040854:
|
|
/* f040854: afa001fc */ sw $zero,0x1fc($sp)
|
|
.PB0f040858:
|
|
/* f040858: afae0268 */ sw $t6,0x268($sp)
|
|
/* f04085c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040860: 0fc0ffbd */ jal chrGetGunPos
|
|
/* f040864: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f040868: 54400032 */ bnezl $v0,.PB0f040934
|
|
/* f04086c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040870: 8fa20274 */ lw $v0,0x274($sp)
|
|
/* f040874: 3c0141f0 */ lui $at,0x41f0
|
|
/* f040878: 44818000 */ mtc1 $at,$f16
|
|
/* f04087c: c44a0008 */ lwc1 $f10,0x8($v0)
|
|
/* f040880: 8faa027c */ lw $t2,0x27c($sp)
|
|
/* f040884: 24010001 */ li $at,0x1
|
|
/* f040888: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f04088c: c452000c */ lwc1 $f18,0xc($v0)
|
|
/* f040890: 46109100 */ add.s $f4,$f18,$f16
|
|
/* f040894: e7a40248 */ swc1 $f4,0x248($sp)
|
|
/* f040898: c4460010 */ lwc1 $f6,0x10($v0)
|
|
/* f04089c: 15410013 */ bne $t2,$at,.PB0f0408ec
|
|
/* f0408a0: e7a6024c */ swc1 $f6,0x24c($sp)
|
|
/* f0408a4: 0c006b88 */ jal cosf
|
|
/* f0408a8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0408ac: 3c014120 */ lui $at,0x4120
|
|
/* f0408b0: 44815000 */ mtc1 $at,$f10
|
|
/* f0408b4: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f0408b8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0408bc: 460a0482 */ mul.s $f18,$f0,$f10
|
|
/* f0408c0: 46124400 */ add.s $f16,$f8,$f18
|
|
/* f0408c4: 0c006b8b */ jal sinf
|
|
/* f0408c8: e7b00244 */ swc1 $f16,0x244($sp)
|
|
/* f0408cc: 3c014120 */ lui $at,0x4120
|
|
/* f0408d0: 44813000 */ mtc1 $at,$f6
|
|
/* f0408d4: 46000107 */ neg.s $f4,$f0
|
|
/* f0408d8: c7a8024c */ lwc1 $f8,0x24c($sp)
|
|
/* f0408dc: 46062282 */ mul.s $f10,$f4,$f6
|
|
/* f0408e0: 460a4480 */ add.s $f18,$f8,$f10
|
|
/* f0408e4: 10000012 */ b .PB0f040930
|
|
/* f0408e8: e7b2024c */ swc1 $f18,0x24c($sp)
|
|
.PB0f0408ec:
|
|
/* f0408ec: 0c006b88 */ jal cosf
|
|
/* f0408f0: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0408f4: 3c014120 */ lui $at,0x4120
|
|
/* f0408f8: 44812000 */ mtc1 $at,$f4
|
|
/* f0408fc: 46000407 */ neg.s $f16,$f0
|
|
/* f040900: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f040904: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f040908: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f04090c: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040910: 0c006b8b */ jal sinf
|
|
/* f040914: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f040918: 3c014120 */ lui $at,0x4120
|
|
/* f04091c: 44818000 */ mtc1 $at,$f16
|
|
/* f040920: c7b2024c */ lwc1 $f18,0x24c($sp)
|
|
/* f040924: 46100102 */ mul.s $f4,$f0,$f16
|
|
/* f040928: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f04092c: e7a8024c */ swc1 $f8,0x24c($sp)
|
|
.PB0f040930:
|
|
/* f040930: 8fa40278 */ lw $a0,0x278($sp)
|
|
.PB0f040934:
|
|
/* f040934: 0fc07a1f */ jal chrSetPerimEnabled
|
|
/* f040938: 00002825 */ move $a1,$zero
|
|
/* f04093c: 8fb801fc */ lw $t8,0x1fc($sp)
|
|
/* f040940: 8faf0274 */ lw $t7,0x274($sp)
|
|
/* f040944: 24190010 */ li $t9,0x10
|
|
/* f040948: 370c082a */ ori $t4,$t8,0x82a
|
|
/* f04094c: afac0010 */ sw $t4,0x10($sp)
|
|
/* f040950: afb90014 */ sw $t9,0x14($sp)
|
|
/* f040954: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f040958: 27a70234 */ addiu $a3,$sp,0x234
|
|
/* f04095c: 25e40008 */ addiu $a0,$t7,0x8
|
|
/* f040960: 0c00b8fd */ jal cd0002de34
|
|
/* f040964: 25e50028 */ addiu $a1,$t7,0x28
|
|
/* f040968: 14400002 */ bnez $v0,.PB0f040974
|
|
/* f04096c: 24050001 */ li $a1,0x1
|
|
/* f040970: afa00268 */ sw $zero,0x268($sp)
|
|
.PB0f040974:
|
|
/* f040974: 0fc07a1f */ jal chrSetPerimEnabled
|
|
/* f040978: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f04097c: 8fab0268 */ lw $t3,0x268($sp)
|
|
/* f040980: 240d0001 */ li $t5,0x1
|
|
/* f040984: 51600448 */ beqzl $t3,.PB0f041aa8
|
|
/* f040988: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f04098c: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f040990: afa001f8 */ sw $zero,0x1f8($sp)
|
|
/* f040994: afa001f4 */ sw $zero,0x1f4($sp)
|
|
/* f040998: afad01f0 */ sw $t5,0x1f0($sp)
|
|
/* f04099c: 11c00004 */ beqz $t6,.PB0f0409b0
|
|
/* f0409a0: afa001cc */ sw $zero,0x1cc($sp)
|
|
/* f0409a4: 240a083f */ li $t2,0x83f
|
|
/* f0409a8: 10000003 */ b .PB0f0409b8
|
|
/* f0409ac: afaa01c8 */ sw $t2,0x1c8($sp)
|
|
.PB0f0409b0:
|
|
/* f0409b0: 240f083b */ li $t7,0x83b
|
|
/* f0409b4: afaf01c8 */ sw $t7,0x1c8($sp)
|
|
.PB0f0409b8:
|
|
/* f0409b8: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f0409bc: 8ce20004 */ lw $v0,0x4($a3)
|
|
/* f0409c0: 50400004 */ beqzl $v0,.PB0f0409d4
|
|
/* f0409c4: 00004825 */ move $t1,$zero
|
|
/* f0409c8: 10000002 */ b .PB0f0409d4
|
|
/* f0409cc: 904902fe */ lbu $t1,0x2fe($v0)
|
|
/* f0409d0: 00004825 */ move $t1,$zero
|
|
.PB0f0409d4:
|
|
/* f0409d4: 39220003 */ xori $v0,$t1,0x3
|
|
/* f0409d8: 2c420001 */ sltiu $v0,$v0,0x1
|
|
/* f0409dc: 1040000f */ beqz $v0,.PB0f040a1c
|
|
/* f0409e0: 00401825 */ move $v1,$v0
|
|
/* f0409e4: afa2005c */ sw $v0,0x5c($sp)
|
|
/* f0409e8: 0fc124bb */ jal chrGetDistanceToTarget
|
|
/* f0409ec: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0409f0: 3c014316 */ lui $at,0x4316
|
|
/* f0409f4: 44813000 */ mtc1 $at,$f6
|
|
/* f0409f8: 0000c025 */ move $t8,$zero
|
|
/* f0409fc: 4600303c */ c.lt.s $f6,$f0
|
|
/* f040a00: 00000000 */ nop
|
|
/* f040a04: 45020003 */ bc1fl .PB0f040a14
|
|
/* f040a08: afb8005c */ sw $t8,0x5c($sp)
|
|
/* f040a0c: 24180001 */ li $t8,0x1
|
|
/* f040a10: afb8005c */ sw $t8,0x5c($sp)
|
|
.PB0f040a14:
|
|
/* f040a14: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f040a18: 03001825 */ move $v1,$t8
|
|
.PB0f040a1c:
|
|
/* f040a1c: afa301c0 */ sw $v1,0x1c0($sp)
|
|
/* f040a20: 10600016 */ beqz $v1,.PB0f040a7c
|
|
/* f040a24: afa001bc */ sw $zero,0x1bc($sp)
|
|
/* f040a28: c4ea0008 */ lwc1 $f10,0x8($a3)
|
|
/* f040a2c: c7b00244 */ lwc1 $f16,0x244($sp)
|
|
/* f040a30: c7a80248 */ lwc1 $f8,0x248($sp)
|
|
/* f040a34: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040a38: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f040a3c: c7b0024c */ lwc1 $f16,0x24c($sp)
|
|
/* f040a40: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040a44: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040a48: e7b201e0 */ swc1 $f18,0x1e0($sp)
|
|
/* f040a4c: c4e4000c */ lwc1 $f4,0xc($a3)
|
|
/* f040a50: 46082181 */ sub.s $f6,$f4,$f8
|
|
/* f040a54: e7a601e4 */ swc1 $f6,0x1e4($sp)
|
|
/* f040a58: c4ea0010 */ lwc1 $f10,0x10($a3)
|
|
/* f040a5c: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f040a60: 0c0011d8 */ jal guNormalize
|
|
/* f040a64: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
/* f040a68: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f040a6c: 0fc190d6 */ jal propSetPerimEnabled
|
|
/* f040a70: 24050001 */ li $a1,0x1
|
|
/* f040a74: 1000002f */ b .PB0f040b34
|
|
/* f040a78: 8fab0278 */ lw $t3,0x278($sp)
|
|
.PB0f040a7c:
|
|
/* f040a7c: 0c006b88 */ jal cosf
|
|
/* f040a80: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040a84: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f040a88: 0c006b8b */ jal sinf
|
|
/* f040a8c: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040a90: c7a40060 */ lwc1 $f4,0x60($sp)
|
|
/* f040a94: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040a98: 46040202 */ mul.s $f8,$f0,$f4
|
|
/* f040a9c: 0c006b8b */ jal sinf
|
|
/* f040aa0: e7a801e0 */ swc1 $f8,0x1e0($sp)
|
|
/* f040aa4: e7a001e4 */ swc1 $f0,0x1e4($sp)
|
|
/* f040aa8: 0c006b88 */ jal cosf
|
|
/* f040aac: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040ab0: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f040ab4: 0c006b88 */ jal cosf
|
|
/* f040ab8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040abc: c7a60060 */ lwc1 $f6,0x60($sp)
|
|
/* f040ac0: 93ac026f */ lbu $t4,0x26f($sp)
|
|
/* f040ac4: 46060282 */ mul.s $f10,$f0,$f6
|
|
/* f040ac8: 11800019 */ beqz $t4,.PB0f040b30
|
|
/* f040acc: e7aa01e8 */ swc1 $f10,0x1e8($sp)
|
|
/* f040ad0: 0fc64be8 */ jal botGuessCrouchPos
|
|
/* f040ad4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040ad8: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f040adc: 00404825 */ move $t1,$v0
|
|
/* f040ae0: 8fae0278 */ lw $t6,0x278($sp)
|
|
/* f040ae4: 8f280170 */ lw $t0,0x170($t9)
|
|
/* f040ae8: 0008582b */ sltu $t3,$zero,$t0
|
|
/* f040aec: 11600004 */ beqz $t3,.PB0f040b00
|
|
/* f040af0: 01604025 */ move $t0,$t3
|
|
/* f040af4: 8f280174 */ lw $t0,0x174($t9)
|
|
/* f040af8: 0008682b */ sltu $t5,$zero,$t0
|
|
/* f040afc: 01a04025 */ move $t0,$t5
|
|
.PB0f040b00:
|
|
/* f040b00: 8dc302d4 */ lw $v1,0x2d4($t6)
|
|
/* f040b04: 8fb8027c */ lw $t8,0x27c($sp)
|
|
/* f040b08: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040b0c: 8c66004c */ lw $a2,0x4c($v1)
|
|
/* f040b10: 00786021 */ addu $t4,$v1,$t8
|
|
/* f040b14: 9187004d */ lbu $a3,0x4d($t4)
|
|
/* f040b18: 8c650020 */ lw $a1,0x20($v1)
|
|
/* f040b1c: 00065080 */ sll $t2,$a2,0x2
|
|
/* f040b20: 000a37c2 */ srl $a2,$t2,0x1f
|
|
/* f040b24: afa80014 */ sw $t0,0x14($sp)
|
|
/* f040b28: 0fc28488 */ jal bgunCalculateBotShotSpread
|
|
/* f040b2c: afa90010 */ sw $t1,0x10($sp)
|
|
.PB0f040b30:
|
|
/* f040b30: 8fab0278 */ lw $t3,0x278($sp)
|
|
.PB0f040b34:
|
|
/* f040b34: 93b90260 */ lbu $t9,0x260($sp)
|
|
/* f040b38: 24010016 */ li $at,0x16
|
|
/* f040b3c: 8d6302d4 */ lw $v1,0x2d4($t3)
|
|
/* f040b40: 50600018 */ beqzl $v1,.PB0f040ba4
|
|
/* f040b44: 3c014780 */ lui $at,0x4780
|
|
/* f040b48: 57210016 */ bnel $t9,$at,.PB0f040ba4
|
|
/* f040b4c: 3c014780 */ lui $at,0x4780
|
|
/* f040b50: 8c6d0128 */ lw $t5,0x128($v1)
|
|
/* f040b54: 240e0001 */ li $t6,0x1
|
|
/* f040b58: 01602025 */ move $a0,$t3
|
|
/* f040b5c: 15a00010 */ bnez $t5,.PB0f040ba0
|
|
/* f040b60: 00002825 */ move $a1,$zero
|
|
/* f040b64: afae0250 */ sw $t6,0x250($sp)
|
|
/* f040b68: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f040b6c: 0fc66ed9 */ jal botactShootFarsight
|
|
/* f040b70: 27a70244 */ addiu $a3,$sp,0x244
|
|
/* f040b74: 24010002 */ li $at,0x2
|
|
/* f040b78: 5441000a */ bnel $v0,$at,.PB0f040ba4
|
|
/* f040b7c: 3c014780 */ lui $at,0x4780
|
|
/* f040b80: 0c004be0 */ jal random
|
|
/* f040b84: 00000000 */ nop
|
|
/* f040b88: 240100ff */ li $at,0xff
|
|
/* f040b8c: 0041001b */ divu $zero,$v0,$at
|
|
/* f040b90: 00005010 */ mfhi $t2
|
|
/* f040b94: 2d4f00c9 */ sltiu $t7,$t2,0xc9
|
|
/* f040b98: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f040b9c: a3af026e */ sb $t7,0x26e($sp)
|
|
.PB0f040ba0:
|
|
/* f040ba0: 3c014780 */ lui $at,0x4780
|
|
.PB0f040ba4:
|
|
/* f040ba4: 44810000 */ mtc1 $at,$f0
|
|
/* f040ba8: c7b001e0 */ lwc1 $f16,0x1e0($sp)
|
|
/* f040bac: c7a40244 */ lwc1 $f4,0x244($sp)
|
|
/* f040bb0: c7a601e4 */ lwc1 $f6,0x1e4($sp)
|
|
/* f040bb4: 46008482 */ mul.s $f18,$f16,$f0
|
|
/* f040bb8: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f040bbc: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040bc0: 46003282 */ mul.s $f10,$f6,$f0
|
|
/* f040bc4: c7a6024c */ lwc1 $f6,0x24c($sp)
|
|
/* f040bc8: 00002825 */ move $a1,$zero
|
|
/* f040bcc: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f040bd0: c7a401e8 */ lwc1 $f4,0x1e8($sp)
|
|
/* f040bd4: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f040bd8: e7a80228 */ swc1 $f8,0x228($sp)
|
|
/* f040bdc: 46002202 */ mul.s $f8,$f4,$f0
|
|
/* f040be0: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f040be4: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040be8: 0fc07a1f */ jal chrSetPerimEnabled
|
|
/* f040bec: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f040bf0: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040bf4: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040bf8: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f040bfc: 13000004 */ beqz $t8,.PB0f040c10
|
|
/* f040c00: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f040c04: 240c0001 */ li $t4,0x1
|
|
/* f040c08: 3c01800a */ lui $at,0x800a
|
|
/* f040c0c: ac2ce95c */ sw $t4,-0x16a4($at)
|
|
.PB0f040c10:
|
|
/* f040c10: 24190010 */ li $t9,0x10
|
|
/* f040c14: afb90010 */ sw $t9,0x10($sp)
|
|
/* f040c18: 0c00b8d4 */ jal cdTestAToB4
|
|
/* f040c1c: 8fa701c8 */ lw $a3,0x1c8($sp)
|
|
/* f040c20: 1440000a */ bnez $v0,.PB0f040c4c
|
|
/* f040c24: 240d0001 */ li $t5,0x1
|
|
/* f040c28: 3c067f1b */ lui $a2,0x7f1b
|
|
/* f040c2c: afad0224 */ sw $t5,0x224($sp)
|
|
/* f040c30: 24c6a7c4 */ addiu $a2,$a2,-22588
|
|
/* f040c34: 27a40228 */ addiu $a0,$sp,0x228
|
|
/* f040c38: 0c00951f */ jal cdGetPos
|
|
/* f040c3c: 24052f28 */ li $a1,0x2f28
|
|
/* f040c40: 0c00951c */ jal cdGetObstacle
|
|
/* f040c44: 00000000 */ nop
|
|
/* f040c48: afa201cc */ sw $v0,0x1cc($sp)
|
|
.PB0f040c4c:
|
|
/* f040c4c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040c50: 0fc07a1f */ jal chrSetPerimEnabled
|
|
/* f040c54: 24050001 */ li $a1,0x1
|
|
/* f040c58: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f040c5c: 3c01800a */ lui $at,0x800a
|
|
/* f040c60: 51c00003 */ beqzl $t6,.PB0f040c70
|
|
/* f040c64: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
/* f040c68: ac20e95c */ sw $zero,-0x16a4($at)
|
|
/* f040c6c: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
.PB0f040c70:
|
|
/* f040c70: 8faa01c0 */ lw $t2,0x1c0($sp)
|
|
/* f040c74: 55600015 */ bnezl $t3,.PB0f040ccc
|
|
/* f040c78: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f040c7c: 51400013 */ beqzl $t2,.PB0f040ccc
|
|
/* f040c80: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f040c84: 0c004be0 */ jal random
|
|
/* f040c88: 00000000 */ nop
|
|
/* f040c8c: 24010064 */ li $at,0x64
|
|
/* f040c90: 0041001b */ divu $zero,$v0,$at
|
|
/* f040c94: 00001810 */ mfhi $v1
|
|
/* f040c98: 2c6f0033 */ sltiu $t7,$v1,0x33
|
|
/* f040c9c: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f040ca0: 11e00009 */ beqz $t7,.PB0f040cc8
|
|
/* f040ca4: afaf01bc */ sw $t7,0x1bc($sp)
|
|
/* f040ca8: 8fb8025c */ lw $t8,0x25c($sp)
|
|
/* f040cac: afb801cc */ sw $t8,0x1cc($sp)
|
|
/* f040cb0: c7100008 */ lwc1 $f16,0x8($t8)
|
|
/* f040cb4: e7b00228 */ swc1 $f16,0x228($sp)
|
|
/* f040cb8: c712000c */ lwc1 $f18,0xc($t8)
|
|
/* f040cbc: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f040cc0: c7040010 */ lwc1 $f4,0x10($t8)
|
|
/* f040cc4: e7a40230 */ swc1 $f4,0x230($sp)
|
|
.PB0f040cc8:
|
|
/* f040cc8: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
.PB0f040ccc:
|
|
/* f040ccc: c7a60244 */ lwc1 $f6,0x244($sp)
|
|
/* f040cd0: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f040cd4: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f040cd8: 46064001 */ sub.s $f0,$f8,$f6
|
|
/* f040cdc: c7b20230 */ lwc1 $f18,0x230($sp)
|
|
/* f040ce0: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f040ce4: 46105081 */ sub.s $f2,$f10,$f16
|
|
/* f040ce8: 46000202 */ mul.s $f8,$f0,$f0
|
|
/* f040cec: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040cf0: 46049301 */ sub.s $f12,$f18,$f4
|
|
/* f040cf4: 46021182 */ mul.s $f6,$f2,$f2
|
|
/* f040cf8: 24010018 */ li $at,0x18
|
|
/* f040cfc: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f040d00: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040d04: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f040d08: 1081000f */ beq $a0,$at,.PB0f040d48
|
|
/* f040d0c: e7b201d0 */ swc1 $f18,0x1d0($sp)
|
|
/* f040d10: 24010019 */ li $at,0x19
|
|
/* f040d14: 1081000c */ beq $a0,$at,.PB0f040d48
|
|
/* f040d18: 24010012 */ li $at,0x12
|
|
/* f040d1c: 14810003 */ bne $a0,$at,.PB0f040d2c
|
|
/* f040d20: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f040d24: 24010001 */ li $at,0x1
|
|
/* f040d28: 11810007 */ beq $t4,$at,.PB0f040d48
|
|
.PB0f040d2c:
|
|
/* f040d2c: 24010017 */ li $at,0x17
|
|
/* f040d30: 10810005 */ beq $a0,$at,.PB0f040d48
|
|
/* f040d34: 2401001b */ li $at,0x1b
|
|
/* f040d38: 10810003 */ beq $a0,$at,.PB0f040d48
|
|
/* f040d3c: 24010034 */ li $at,0x34
|
|
/* f040d40: 54810179 */ bnel $a0,$at,.PB0f041328
|
|
/* f040d44: 24010006 */ li $at,0x6
|
|
.PB0f040d48:
|
|
/* f040d48: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f040d4c: afa00250 */ sw $zero,0x250($sp)
|
|
/* f040d50: 3c017f1b */ lui $at,0x7f1b
|
|
/* f040d54: 17200006 */ bnez $t9,.PB0f040d70
|
|
/* f040d58: c7a801d0 */ lwc1 $f8,0x1d0($sp)
|
|
/* f040d5c: c424adb0 */ lwc1 $f4,-0x5250($at)
|
|
/* f040d60: 4608203c */ c.lt.s $f4,$f8
|
|
/* f040d64: 00000000 */ nop
|
|
/* f040d68: 4502016c */ bc1fl .PB0f04131c
|
|
/* f040d6c: afa00268 */ sw $zero,0x268($sp)
|
|
.PB0f040d70:
|
|
/* f040d70: 0fc2c4f8 */ jal weaponFindById
|
|
/* f040d74: 00000000 */ nop
|
|
/* f040d78: 93ad0263 */ lbu $t5,0x263($sp)
|
|
/* f040d7c: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040d80: 24010018 */ li $at,0x18
|
|
/* f040d84: 000d7080 */ sll $t6,$t5,0x2
|
|
/* f040d88: 004e5821 */ addu $t3,$v0,$t6
|
|
/* f040d8c: 10810006 */ beq $a0,$at,.PB0f040da8
|
|
/* f040d90: 8d630014 */ lw $v1,0x14($t3)
|
|
/* f040d94: 24010034 */ li $at,0x34
|
|
/* f040d98: 10810003 */ beq $a0,$at,.PB0f040da8
|
|
/* f040d9c: 24010019 */ li $at,0x19
|
|
/* f040da0: 5481000e */ bnel $a0,$at,.PB0f040ddc
|
|
/* f040da4: 2401001b */ li $at,0x1b
|
|
.PB0f040da8:
|
|
/* f040da8: 8c6a0010 */ lw $t2,0x10($v1)
|
|
/* f040dac: 24050053 */ li $a1,0x53
|
|
/* f040db0: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040db4: 000a7840 */ sll $t7,$t2,0x1
|
|
/* f040db8: 05e30003 */ bgezl $t7,.PB0f040dc8
|
|
/* f040dbc: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040dc0: 24050054 */ li $a1,0x54
|
|
/* f040dc4: 8c640040 */ lw $a0,0x40($v1)
|
|
.PB0f040dc8:
|
|
/* f040dc8: 0fc22dbf */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040dcc: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040dd0: 1000002e */ b .PB0f040e8c
|
|
/* f040dd4: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040dd8: 2401001b */ li $at,0x1b
|
|
.PB0f040ddc:
|
|
/* f040ddc: 1481000a */ bne $a0,$at,.PB0f040e08
|
|
/* f040de0: 24050056 */ li $a1,0x56
|
|
/* f040de4: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040de8: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040dec: 0fc22dbf */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040df0: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040df4: 10400025 */ beqz $v0,.PB0f040e8c
|
|
/* f040df8: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040dfc: 93b80263 */ lbu $t8,0x263($sp)
|
|
/* f040e00: 10000022 */ b .PB0f040e8c
|
|
/* f040e04: a058005f */ sb $t8,0x5f($v0)
|
|
.PB0f040e08:
|
|
/* f040e08: 24010017 */ li $at,0x17
|
|
/* f040e0c: 1481000a */ bne $a0,$at,.PB0f040e38
|
|
/* f040e10: 24050055 */ li $a1,0x55
|
|
/* f040e14: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040e18: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040e1c: 0fc22dbf */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040e20: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040e24: 10400019 */ beqz $v0,.PB0f040e8c
|
|
/* f040e28: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040e2c: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f040e30: 10000016 */ b .PB0f040e8c
|
|
/* f040e34: a04c005f */ sb $t4,0x5f($v0)
|
|
.PB0f040e38:
|
|
/* f040e38: 24010012 */ li $at,0x12
|
|
/* f040e3c: 1481000b */ bne $a0,$at,.PB0f040e6c
|
|
/* f040e40: 3c0d800a */ lui $t5,0x800a
|
|
/* f040e44: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040e48: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040e4c: 24050055 */ li $a1,0x55
|
|
/* f040e50: 0fc22dbf */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040e54: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040e58: 1040000c */ beqz $v0,.PB0f040e8c
|
|
/* f040e5c: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040e60: 24190002 */ li $t9,0x2
|
|
/* f040e64: 10000009 */ b .PB0f040e8c
|
|
/* f040e68: a059005f */ sb $t9,0x5f($v0)
|
|
.PB0f040e6c:
|
|
/* f040e6c: 8dade754 */ lw $t5,-0x18ac($t5)
|
|
/* f040e70: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040e74: 27a50260 */ addiu $a1,$sp,0x260
|
|
/* f040e78: 8dae00bc */ lw $t6,0xbc($t5)
|
|
/* f040e7c: 8dc60004 */ lw $a2,0x4($t6)
|
|
/* f040e80: 0fc22d35 */ jal weaponCreateProjectileFromGset
|
|
/* f040e84: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040e88: afa201b8 */ sw $v0,0x1b8($sp)
|
|
.PB0f040e8c:
|
|
/* f040e8c: 10400123 */ beqz $v0,.PB0f04131c
|
|
/* f040e90: 8fab00d4 */ lw $t3,0xd4($sp)
|
|
/* f040e94: 8d6a004c */ lw $t2,0x4c($t3)
|
|
/* f040e98: 3c017f1b */ lui $at,0x7f1b
|
|
/* f040e9c: c430adb4 */ lwc1 $f16,-0x524c($at)
|
|
/* f040ea0: 448a3000 */ mtc1 $t2,$f6
|
|
/* f040ea4: 3c014270 */ lui $at,0x4270
|
|
/* f040ea8: 44812000 */ mtc1 $at,$f4
|
|
/* f040eac: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f040eb0: 3c017f1b */ lui $at,0x7f1b
|
|
/* f040eb4: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040eb8: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040ebc: 2405001e */ li $a1,0x1e
|
|
/* f040ec0: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f040ec4: c430adb8 */ lwc1 $f16,-0x5248($at)
|
|
/* f040ec8: 46049203 */ div.s $f8,$f18,$f4
|
|
/* f040ecc: e7a80168 */ swc1 $f8,0x168($sp)
|
|
/* f040ed0: 8d6f0054 */ lw $t7,0x54($t3)
|
|
/* f040ed4: 448f3000 */ mtc1 $t7,$f6
|
|
/* f040ed8: 00000000 */ nop
|
|
/* f040edc: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f040ee0: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f040ee4: 13000080 */ beqz $t8,.PB0f0410e8
|
|
/* f040ee8: e7b200cc */ swc1 $f18,0xcc($sp)
|
|
/* f040eec: 0fc12463 */ jal chrIsTargetInFov
|
|
/* f040ef0: 00003025 */ move $a2,$zero
|
|
/* f040ef4: 1040007c */ beqz $v0,.PB0f0410e8
|
|
/* f040ef8: 00000000 */ nop
|
|
/* f040efc: 93a20263 */ lbu $v0,0x263($sp)
|
|
/* f040f00: 00001825 */ move $v1,$zero
|
|
/* f040f04: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040f08: 14400025 */ bnez $v0,.PB0f040fa0
|
|
/* f040f0c: 24010018 */ li $at,0x18
|
|
/* f040f10: 10810006 */ beq $a0,$at,.PB0f040f2c
|
|
/* f040f14: 8fac025c */ lw $t4,0x25c($sp)
|
|
/* f040f18: 24010034 */ li $at,0x34
|
|
/* f040f1c: 10810003 */ beq $a0,$at,.PB0f040f2c
|
|
/* f040f20: 24010019 */ li $at,0x19
|
|
/* f040f24: 5481001f */ bnel $a0,$at,.PB0f040fa4
|
|
/* f040f28: 93a40260 */ lbu $a0,0x260($sp)
|
|
.PB0f040f2c:
|
|
/* f040f2c: 91820000 */ lbu $v0,0x0($t4)
|
|
/* f040f30: 24010003 */ li $at,0x3
|
|
/* f040f34: 8fb9025c */ lw $t9,0x25c($sp)
|
|
/* f040f38: 10410003 */ beq $v0,$at,.PB0f040f48
|
|
/* f040f3c: 24010006 */ li $at,0x6
|
|
/* f040f40: 14410051 */ bne $v0,$at,.PB0f041088
|
|
/* f040f44: 00000000 */ nop
|
|
.PB0f040f48:
|
|
/* f040f48: c7240008 */ lwc1 $f4,0x8($t9)
|
|
/* f040f4c: c7aa0244 */ lwc1 $f10,0x244($sp)
|
|
/* f040f50: c7b20248 */ lwc1 $f18,0x248($sp)
|
|
/* f040f54: e7a400b8 */ swc1 $f4,0xb8($sp)
|
|
/* f040f58: 8f2d0004 */ lw $t5,0x4($t9)
|
|
/* f040f5c: 460a2401 */ sub.s $f16,$f4,$f10
|
|
/* f040f60: c7aa024c */ lwc1 $f10,0x24c($sp)
|
|
/* f040f64: c5a800b4 */ lwc1 $f8,0xb4($t5)
|
|
/* f040f68: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040f6c: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040f70: e7a800bc */ swc1 $f8,0xbc($sp)
|
|
/* f040f74: c7260010 */ lwc1 $f6,0x10($t9)
|
|
/* f040f78: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f040f7c: 46124101 */ sub.s $f4,$f8,$f18
|
|
/* f040f80: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040f84: e7a600c0 */ swc1 $f6,0xc0($sp)
|
|
/* f040f88: 460a3401 */ sub.s $f16,$f6,$f10
|
|
/* f040f8c: e7a401e4 */ swc1 $f4,0x1e4($sp)
|
|
/* f040f90: 0c0011d8 */ jal guNormalize
|
|
/* f040f94: e7b001e8 */ swc1 $f16,0x1e8($sp)
|
|
/* f040f98: 1000003b */ b .PB0f041088
|
|
/* f040f9c: 24030001 */ li $v1,0x1
|
|
.PB0f040fa0:
|
|
/* f040fa0: 93a40260 */ lbu $a0,0x260($sp)
|
|
.PB0f040fa4:
|
|
/* f040fa4: 24050017 */ li $a1,0x17
|
|
/* f040fa8: 24010012 */ li $at,0x12
|
|
/* f040fac: 14a40003 */ bne $a1,$a0,.PB0f040fbc
|
|
/* f040fb0: 00000000 */ nop
|
|
/* f040fb4: 50400004 */ beqzl $v0,.PB0f040fc8
|
|
/* f040fb8: 8fae025c */ lw $t6,0x25c($sp)
|
|
.PB0f040fbc:
|
|
/* f040fbc: 14810017 */ bne $a0,$at,.PB0f04101c
|
|
/* f040fc0: 00000000 */ nop
|
|
/* f040fc4: 8fae025c */ lw $t6,0x25c($sp)
|
|
.PB0f040fc8:
|
|
/* f040fc8: 24010003 */ li $at,0x3
|
|
/* f040fcc: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f040fd0: 91c20000 */ lbu $v0,0x0($t6)
|
|
/* f040fd4: 10410003 */ beq $v0,$at,.PB0f040fe4
|
|
/* f040fd8: 24010006 */ li $at,0x6
|
|
/* f040fdc: 1441002a */ bne $v0,$at,.PB0f041088
|
|
/* f040fe0: 00000000 */ nop
|
|
.PB0f040fe4:
|
|
/* f040fe4: c5480008 */ lwc1 $f8,0x8($t2)
|
|
/* f040fe8: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040fec: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f040ff0: e7a800b8 */ swc1 $f8,0xb8($sp)
|
|
/* f040ff4: 8d4b0004 */ lw $t3,0x4($t2)
|
|
/* f040ff8: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f040ffc: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f041000: c57200b4 */ lwc1 $f18,0xb4($t3)
|
|
/* f041004: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
/* f041008: c5440010 */ lwc1 $f4,0x10($t2)
|
|
/* f04100c: 0fc1010b */ jal chrCalculateTrajectory
|
|
/* f041010: e7a400c0 */ swc1 $f4,0xc0($sp)
|
|
/* f041014: 1000001c */ b .PB0f041088
|
|
/* f041018: 24030001 */ li $v1,0x1
|
|
.PB0f04101c:
|
|
/* f04101c: 14a40002 */ bne $a1,$a0,.PB0f041028
|
|
/* f041020: 24010001 */ li $at,0x1
|
|
/* f041024: 10410003 */ beq $v0,$at,.PB0f041034
|
|
.PB0f041028:
|
|
/* f041028: 2401001b */ li $at,0x1b
|
|
/* f04102c: 14810016 */ bne $a0,$at,.PB0f041088
|
|
/* f041030: 00000000 */ nop
|
|
.PB0f041034:
|
|
/* f041034: 8faf025c */ lw $t7,0x25c($sp)
|
|
/* f041038: 24010006 */ li $at,0x6
|
|
/* f04103c: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041040: c5e60008 */ lwc1 $f6,0x8($t7)
|
|
/* f041044: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f041048: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f04104c: e7a600b8 */ swc1 $f6,0xb8($sp)
|
|
/* f041050: c5ea000c */ lwc1 $f10,0xc($t7)
|
|
/* f041054: e7aa00bc */ swc1 $f10,0xbc($sp)
|
|
/* f041058: c5f00010 */ lwc1 $f16,0x10($t7)
|
|
/* f04105c: e7b000c0 */ swc1 $f16,0xc0($sp)
|
|
/* f041060: 91f80000 */ lbu $t8,0x0($t7)
|
|
/* f041064: 17010005 */ bne $t8,$at,.PB0f04107c
|
|
/* f041068: 3c0141c8 */ lui $at,0x41c8
|
|
/* f04106c: 44814000 */ mtc1 $at,$f8
|
|
/* f041070: 00000000 */ nop
|
|
/* f041074: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f041078: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
.PB0f04107c:
|
|
/* f04107c: 0fc1010b */ jal chrCalculateTrajectory
|
|
/* f041080: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f041084: 24030001 */ li $v1,0x1
|
|
.PB0f041088:
|
|
/* f041088: 10600017 */ beqz $v1,.PB0f0410e8
|
|
/* f04108c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041090: 0fc122ea */ jal chrGetAngleToPos
|
|
/* f041094: 27a500b8 */ addiu $a1,$sp,0xb8
|
|
/* f041098: e7a000b4 */ swc1 $f0,0xb4($sp)
|
|
/* f04109c: 0c006b88 */ jal cosf
|
|
/* f0410a0: 46000306 */ mov.s $f12,$f0
|
|
/* f0410a4: c7ac00b4 */ lwc1 $f12,0xb4($sp)
|
|
/* f0410a8: 0c006b8b */ jal sinf
|
|
/* f0410ac: e7a000b0 */ swc1 $f0,0xb0($sp)
|
|
/* f0410b0: c7ac01e8 */ lwc1 $f12,0x1e8($sp)
|
|
/* f0410b4: c7ae00b0 */ lwc1 $f14,0xb0($sp)
|
|
/* f0410b8: c7a201e0 */ lwc1 $f2,0x1e0($sp)
|
|
/* f0410bc: 460c0102 */ mul.s $f4,$f0,$f12
|
|
/* f0410c0: 00000000 */ nop
|
|
/* f0410c4: 46027182 */ mul.s $f6,$f14,$f2
|
|
/* f0410c8: 00000000 */ nop
|
|
/* f0410cc: 460c7282 */ mul.s $f10,$f14,$f12
|
|
/* f0410d0: 00000000 */ nop
|
|
/* f0410d4: 46020202 */ mul.s $f8,$f0,$f2
|
|
/* f0410d8: 46062400 */ add.s $f16,$f4,$f6
|
|
/* f0410dc: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f0410e0: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f0410e4: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
.PB0f0410e8:
|
|
/* f0410e8: 0c005900 */ jal mtx4LoadIdentity
|
|
/* f0410ec: 27a40178 */ addiu $a0,$sp,0x178
|
|
/* f0410f0: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f0410f4: 0c005b4e */ jal mtx4LoadXRotation
|
|
/* f0410f8: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f0410fc: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f041100: 0c005b71 */ jal mtx4LoadYRotation
|
|
/* f041104: 27a500dc */ addiu $a1,$sp,0xdc
|
|
/* f041108: 27a400dc */ addiu $a0,$sp,0xdc
|
|
/* f04110c: 0c00598c */ jal mtx00015be0
|
|
/* f041110: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f041114: c7ac0168 */ lwc1 $f12,0x168($sp)
|
|
/* f041118: c7a401e0 */ lwc1 $f4,0x1e0($sp)
|
|
/* f04111c: c7b001e4 */ lwc1 $f16,0x1e4($sp)
|
|
/* f041120: c7a801e8 */ lwc1 $f8,0x1e8($sp)
|
|
/* f041124: 460c2182 */ mul.s $f6,$f4,$f12
|
|
/* f041128: c7a200cc */ lwc1 $f2,0xcc($sp)
|
|
/* f04112c: 3c01800a */ lui $at,0x800a
|
|
/* f041130: 460c8282 */ mul.s $f10,$f16,$f12
|
|
/* f041134: c420e51c */ lwc1 $f0,-0x1ae4($at)
|
|
/* f041138: 8fac00d4 */ lw $t4,0xd4($sp)
|
|
/* f04113c: 460c4482 */ mul.s $f18,$f8,$f12
|
|
/* f041140: e7a6015c */ swc1 $f6,0x15c($sp)
|
|
/* f041144: 8fa401b8 */ lw $a0,0x1b8($sp)
|
|
/* f041148: 46022102 */ mul.s $f4,$f4,$f2
|
|
/* f04114c: e7aa0160 */ swc1 $f10,0x160($sp)
|
|
/* f041150: 2401ffff */ li $at,-1
|
|
/* f041154: 46003182 */ mul.s $f6,$f6,$f0
|
|
/* f041158: e7b20164 */ swc1 $f18,0x164($sp)
|
|
/* f04115c: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f041160: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f041164: 27a7011c */ addiu $a3,$sp,0x11c
|
|
/* f041168: 27ab016c */ addiu $t3,$sp,0x16c
|
|
/* f04116c: 27aa0178 */ addiu $t2,$sp,0x178
|
|
/* f041170: 46062100 */ add.s $f4,$f4,$f6
|
|
/* f041174: 46028182 */ mul.s $f6,$f16,$f2
|
|
/* f041178: e7a4016c */ swc1 $f4,0x16c($sp)
|
|
/* f04117c: 46005102 */ mul.s $f4,$f10,$f0
|
|
/* f041180: 46043400 */ add.s $f16,$f6,$f4
|
|
/* f041184: 46024282 */ mul.s $f10,$f8,$f2
|
|
/* f041188: 00000000 */ nop
|
|
/* f04118c: 46009182 */ mul.s $f6,$f18,$f0
|
|
/* f041190: e7b00170 */ swc1 $f16,0x170($sp)
|
|
/* f041194: 46065100 */ add.s $f4,$f10,$f6
|
|
/* f041198: e7a40174 */ swc1 $f4,0x174($sp)
|
|
/* f04119c: 8d8d0058 */ lw $t5,0x58($t4)
|
|
/* f0411a0: a48d0062 */ sh $t5,0x62($a0)
|
|
/* f0411a4: 84820062 */ lh $v0,0x62($a0)
|
|
/* f0411a8: 1041000a */ beq $v0,$at,.PB0f0411d4
|
|
/* f0411ac: 0002c880 */ sll $t9,$v0,0x2
|
|
/* f0411b0: 0322c823 */ subu $t9,$t9,$v0
|
|
/* f0411b4: 0019c8c0 */ sll $t9,$t9,0x3
|
|
/* f0411b8: 0322c821 */ addu $t9,$t9,$v0
|
|
/* f0411bc: 0019c8c0 */ sll $t9,$t9,0x3
|
|
/* f0411c0: 2401003c */ li $at,0x3c
|
|
/* f0411c4: 0321001a */ div $zero,$t9,$at
|
|
/* f0411c8: 00007012 */ mflo $t6
|
|
/* f0411cc: a48e0062 */ sh $t6,0x62($a0)
|
|
/* f0411d0: 00000000 */ nop
|
|
.PB0f0411d4:
|
|
/* f0411d4: 8faf0274 */ lw $t7,0x274($sp)
|
|
/* f0411d8: afab0010 */ sw $t3,0x10($sp)
|
|
/* f0411dc: afaa0014 */ sw $t2,0x14($sp)
|
|
/* f0411e0: afa5001c */ sw $a1,0x1c($sp)
|
|
/* f0411e4: 0fc27b80 */ jal bgun0f09ebcc
|
|
/* f0411e8: afaf0018 */ sw $t7,0x18($sp)
|
|
/* f0411ec: 8fa301b8 */ lw $v1,0x1b8($sp)
|
|
/* f0411f0: 8fad00d4 */ lw $t5,0xd4($sp)
|
|
/* f0411f4: 8c780040 */ lw $t8,0x40($v1)
|
|
/* f0411f8: 330c0080 */ andi $t4,$t8,0x80
|
|
/* f0411fc: 11800047 */ beqz $t4,.PB0f04131c
|
|
/* f041200: 00000000 */ nop
|
|
/* f041204: 8da20010 */ lw $v0,0x10($t5)
|
|
/* f041208: 0002c800 */ sll $t9,$v0,0x0
|
|
/* f04120c: 07210007 */ bgez $t9,.PB0f04122c
|
|
/* f041210: 00025100 */ sll $t2,$v0,0x4
|
|
/* f041214: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f041218: 3c014000 */ lui $at,0x4000
|
|
/* f04121c: 8c4e0000 */ lw $t6,0x0($v0)
|
|
/* f041220: 01c15825 */ or $t3,$t6,$at
|
|
/* f041224: 10000007 */ b .PB0f041244
|
|
/* f041228: ac4b0000 */ sw $t3,0x0($v0)
|
|
.PB0f04122c:
|
|
/* f04122c: 05430006 */ bgezl $t2,.PB0f041248
|
|
/* f041230: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
/* f041234: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f041238: 8c4f0000 */ lw $t7,0x0($v0)
|
|
/* f04123c: 35f80010 */ ori $t8,$t7,0x10
|
|
/* f041240: ac580000 */ sw $t8,0x0($v0)
|
|
.PB0f041244:
|
|
/* f041244: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
.PB0f041248:
|
|
/* f041248: 8c6c0048 */ lw $t4,0x48($v1)
|
|
/* f04124c: 240e00c8 */ li $t6,0xc8
|
|
/* f041250: 3c017f1b */ lui $at,0x7f1b
|
|
/* f041254: e5900010 */ swc1 $f16,0x10($t4)
|
|
/* f041258: 8c6d0048 */ lw $t5,0x48($v1)
|
|
/* f04125c: c7a80160 */ lwc1 $f8,0x160($sp)
|
|
/* f041260: e5a80014 */ swc1 $f8,0x14($t5)
|
|
/* f041264: 8c790048 */ lw $t9,0x48($v1)
|
|
/* f041268: c7b20164 */ lwc1 $f18,0x164($sp)
|
|
/* f04126c: e7320018 */ swc1 $f18,0x18($t9)
|
|
/* f041270: 8c6b0048 */ lw $t3,0x48($v1)
|
|
/* f041274: ad6e00b4 */ sw $t6,0xb4($t3)
|
|
/* f041278: 8faa00d4 */ lw $t2,0xd4($sp)
|
|
/* f04127c: 8c6f0048 */ lw $t7,0x48($v1)
|
|
/* f041280: c54a005c */ lwc1 $f10,0x5c($t2)
|
|
/* f041284: e5ea008c */ swc1 $f10,0x8c($t7)
|
|
/* f041288: 8fb800d4 */ lw $t8,0xd4($sp)
|
|
/* f04128c: c424adbc */ lwc1 $f4,-0x5244($at)
|
|
/* f041290: 8c6c0048 */ lw $t4,0x48($v1)
|
|
/* f041294: c7060050 */ lwc1 $f6,0x50($t8)
|
|
/* f041298: 46043402 */ mul.s $f16,$f6,$f4
|
|
/* f04129c: e5900098 */ swc1 $f16,0x98($t4)
|
|
/* f0412a0: 0fc0a255 */ jal chrGetTargetProp
|
|
/* f0412a4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0412a8: 8fad01b8 */ lw $t5,0x1b8($sp)
|
|
/* f0412ac: 3c01bf80 */ lui $at,0xbf80
|
|
/* f0412b0: 00002025 */ move $a0,$zero
|
|
/* f0412b4: 8db90048 */ lw $t9,0x48($t5)
|
|
/* f0412b8: 2407ffff */ li $a3,-1
|
|
/* f0412bc: 240bffff */ li $t3,-1
|
|
/* f0412c0: af2200e8 */ sw $v0,0xe8($t9)
|
|
/* f0412c4: 8fae00d4 */ lw $t6,0xd4($sp)
|
|
/* f0412c8: 240affff */ li $t2,-1
|
|
/* f0412cc: 85c60060 */ lh $a2,0x60($t6)
|
|
/* f0412d0: 18c00012 */ blez $a2,.PB0f04131c
|
|
/* f0412d4: 00000000 */ nop
|
|
/* f0412d8: 8da50014 */ lw $a1,0x14($t5)
|
|
/* f0412dc: 44810000 */ mtc1 $at,$f0
|
|
/* f0412e0: afaa002c */ sw $t2,0x2c($sp)
|
|
/* f0412e4: afa00028 */ sw $zero,0x28($sp)
|
|
/* f0412e8: afa00020 */ sw $zero,0x20($sp)
|
|
/* f0412ec: afa0001c */ sw $zero,0x1c($sp)
|
|
/* f0412f0: afa00018 */ sw $zero,0x18($sp)
|
|
/* f0412f4: afa00014 */ sw $zero,0x14($sp)
|
|
/* f0412f8: afab0010 */ sw $t3,0x10($sp)
|
|
/* f0412fc: e7a00024 */ swc1 $f0,0x24($sp)
|
|
/* f041300: e7a00030 */ swc1 $f0,0x30($sp)
|
|
/* f041304: e7a00034 */ swc1 $f0,0x34($sp)
|
|
/* f041308: 0fc24e0e */ jal propsnd0f0939f8
|
|
/* f04130c: e7a00038 */ swc1 $f0,0x38($sp)
|
|
/* f041310: 10000002 */ b .PB0f04131c
|
|
/* f041314: 00000000 */ nop
|
|
/* f041318: afa00268 */ sw $zero,0x268($sp)
|
|
.PB0f04131c:
|
|
/* f04131c: 10000019 */ b .PB0f041384
|
|
/* f041320: a3a0026e */ sb $zero,0x26e($sp)
|
|
/* f041324: 24010006 */ li $at,0x6
|
|
.PB0f041328:
|
|
/* f041328: 14810016 */ bne $a0,$at,.PB0f041384
|
|
/* f04132c: 93af026f */ lbu $t7,0x26f($sp)
|
|
/* f041330: 11e00014 */ beqz $t7,.PB0f041384
|
|
/* f041334: 93b80263 */ lbu $t8,0x263($sp)
|
|
/* f041338: 24010001 */ li $at,0x1
|
|
/* f04133c: 17010011 */ bne $t8,$at,.PB0f041384
|
|
/* f041340: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f041344: 8fa2027c */ lw $v0,0x27c($sp)
|
|
/* f041348: 8f2e02d4 */ lw $t6,0x2d4($t9)
|
|
/* f04134c: 3c014120 */ lui $at,0x4120
|
|
/* f041350: 00026080 */ sll $t4,$v0,0x2
|
|
/* f041354: 01cc6821 */ addu $t5,$t6,$t4
|
|
/* f041358: c5a800e4 */ lwc1 $f8,0xe4($t5)
|
|
/* f04135c: 44819000 */ mtc1 $at,$f18
|
|
/* f041360: 44802000 */ mtc1 $zero,$f4
|
|
/* f041364: 46124282 */ mul.s $f10,$f8,$f18
|
|
/* f041368: 4600518d */ trunc.w.s $f6,$f10
|
|
/* f04136c: 440a3000 */ mfc1 $t2,$f6
|
|
/* f041370: 00000000 */ nop
|
|
/* f041374: a3aa0262 */ sb $t2,0x262($sp)
|
|
/* f041378: 8f2f02d4 */ lw $t7,0x2d4($t9)
|
|
/* f04137c: 01ecc021 */ addu $t8,$t7,$t4
|
|
/* f041380: e70400e4 */ swc1 $f4,0xe4($t8)
|
|
.PB0f041384:
|
|
/* f041384: 93ac026e */ lbu $t4,0x26e($sp)
|
|
/* f041388: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f04138c: 518001c0 */ beqzl $t4,.PB0f041a90
|
|
/* f041390: 8fab01c0 */ lw $t3,0x1c0($sp)
|
|
/* f041394: 15c000d6 */ bnez $t6,.PB0f0416f0
|
|
/* f041398: 8fad0258 */ lw $t5,0x258($sp)
|
|
/* f04139c: 31ab0200 */ andi $t3,$t5,0x200
|
|
/* f0413a0: 1160004c */ beqz $t3,.PB0f0414d4
|
|
/* f0413a4: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f0413a8: 91590000 */ lbu $t9,0x0($t2)
|
|
/* f0413ac: 24010006 */ li $at,0x6
|
|
/* f0413b0: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0413b4: 17210047 */ bne $t9,$at,.PB0f0414d4
|
|
/* f0413b8: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f0413bc: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f0413c0: 0fc0e4bf */ jal chrCanSeeAttackTarget
|
|
/* f0413c4: 00003825 */ move $a3,$zero
|
|
/* f0413c8: 10400042 */ beqz $v0,.PB0f0414d4
|
|
/* f0413cc: 8faf025c */ lw $t7,0x25c($sp)
|
|
/* f0413d0: 8de40004 */ lw $a0,0x4($t7)
|
|
/* f0413d4: 8fa50278 */ lw $a1,0x278($sp)
|
|
/* f0413d8: 0fc12aec */ jal chrCompareTeams
|
|
/* f0413dc: 24060002 */ li $a2,0x2
|
|
/* f0413e0: 1040003c */ beqz $v0,.PB0f0414d4
|
|
/* f0413e4: 3c014170 */ lui $at,0x4170
|
|
/* f0413e8: 44817000 */ mtc1 $at,$f14
|
|
/* f0413ec: 8fb8025c */ lw $t8,0x25c($sp)
|
|
/* f0413f0: c7aa01e0 */ lwc1 $f10,0x1e0($sp)
|
|
/* f0413f4: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f0413f8: c7100008 */ lwc1 $f16,0x8($t8)
|
|
/* f0413fc: 460e5182 */ mul.s $f6,$f10,$f14
|
|
/* f041400: c7aa01e4 */ lwc1 $f10,0x1e4($sp)
|
|
/* f041404: 46088481 */ sub.s $f18,$f16,$f8
|
|
/* f041408: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f04140c: c704000c */ lwc1 $f4,0xc($t8)
|
|
/* f041410: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041414: 27a501f8 */ addiu $a1,$sp,0x1f8
|
|
/* f041418: 46069001 */ sub.s $f0,$f18,$f6
|
|
/* f04141c: 460e5482 */ mul.s $f18,$f10,$f14
|
|
/* f041420: c7aa01e8 */ lwc1 $f10,0x1e8($sp)
|
|
/* f041424: 46102201 */ sub.s $f8,$f4,$f16
|
|
/* f041428: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f04142c: c7060010 */ lwc1 $f6,0x10($t8)
|
|
/* f041430: 27a601f4 */ addiu $a2,$sp,0x1f4
|
|
/* f041434: 46124081 */ sub.s $f2,$f8,$f18
|
|
/* f041438: 460e5202 */ mul.s $f8,$f10,$f14
|
|
/* f04143c: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f041440: 46043401 */ sub.s $f16,$f6,$f4
|
|
/* f041444: 46000182 */ mul.s $f6,$f0,$f0
|
|
/* f041448: 00000000 */ nop
|
|
/* f04144c: 46021102 */ mul.s $f4,$f2,$f2
|
|
/* f041450: 46088301 */ sub.s $f12,$f16,$f8
|
|
/* f041454: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f041458: 46043280 */ add.s $f10,$f6,$f4
|
|
/* f04145c: 46105200 */ add.s $f8,$f10,$f16
|
|
/* f041460: 4612403e */ c.le.s $f8,$f18
|
|
/* f041464: 00000000 */ nop
|
|
/* f041468: 4500002b */ bc1f .PB0f041518
|
|
/* f04146c: 00000000 */ nop
|
|
/* f041470: 0fc0fef0 */ jal chrCalculateHit
|
|
/* f041474: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f041478: 8fac01f4 */ lw $t4,0x1f4($sp)
|
|
/* f04147c: 8fad01f8 */ lw $t5,0x1f8($sp)
|
|
/* f041480: 8fab0278 */ lw $t3,0x278($sp)
|
|
/* f041484: 2d8e0001 */ sltiu $t6,$t4,0x1
|
|
/* f041488: 11a00023 */ beqz $t5,.PB0f041518
|
|
/* f04148c: afae01f0 */ sw $t6,0x1f0($sp)
|
|
/* f041490: 81630007 */ lb $v1,0x7($t3)
|
|
/* f041494: 24010008 */ li $at,0x8
|
|
/* f041498: 3c0a800a */ lui $t2,0x800a
|
|
/* f04149c: 1061000a */ beq $v1,$at,.PB0f0414c8
|
|
/* f0414a0: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f0414a4: 2401000a */ li $at,0xa
|
|
/* f0414a8: 10610007 */ beq $v1,$at,.PB0f0414c8
|
|
/* f0414ac: 2401001b */ li $at,0x1b
|
|
/* f0414b0: 10610005 */ beq $v1,$at,.PB0f0414c8
|
|
/* f0414b4: 2401001c */ li $at,0x1c
|
|
/* f0414b8: 10610003 */ beq $v1,$at,.PB0f0414c8
|
|
/* f0414bc: 2401001d */ li $at,0x1d
|
|
/* f0414c0: 54610016 */ bnel $v1,$at,.PB0f04151c
|
|
/* f0414c4: 8fae01f4 */ lw $t6,0x1f4($sp)
|
|
.PB0f0414c8:
|
|
/* f0414c8: 8d4ae4d8 */ lw $t2,-0x1b28($t2)
|
|
/* f0414cc: 10000012 */ b .PB0f041518
|
|
/* f0414d0: af2a0048 */ sw $t2,0x48($t9)
|
|
.PB0f0414d4:
|
|
/* f0414d4: 8faf0278 */ lw $t7,0x278($sp)
|
|
/* f0414d8: 24010008 */ li $at,0x8
|
|
/* f0414dc: 3c18800a */ lui $t8,0x800a
|
|
/* f0414e0: 81e30007 */ lb $v1,0x7($t7)
|
|
/* f0414e4: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f0414e8: 10610009 */ beq $v1,$at,.PB0f041510
|
|
/* f0414ec: 2401000a */ li $at,0xa
|
|
/* f0414f0: 10610007 */ beq $v1,$at,.PB0f041510
|
|
/* f0414f4: 2401001b */ li $at,0x1b
|
|
/* f0414f8: 10610005 */ beq $v1,$at,.PB0f041510
|
|
/* f0414fc: 2401001c */ li $at,0x1c
|
|
/* f041500: 10610003 */ beq $v1,$at,.PB0f041510
|
|
/* f041504: 2401001d */ li $at,0x1d
|
|
/* f041508: 54610004 */ bnel $v1,$at,.PB0f04151c
|
|
/* f04150c: 8fae01f4 */ lw $t6,0x1f4($sp)
|
|
.PB0f041510:
|
|
/* f041510: 8f18e4d8 */ lw $t8,-0x1b28($t8)
|
|
/* f041514: ad980048 */ sw $t8,0x48($t4)
|
|
.PB0f041518:
|
|
/* f041518: 8fae01f4 */ lw $t6,0x1f4($sp)
|
|
.PB0f04151c:
|
|
/* f04151c: 8faf01cc */ lw $t7,0x1cc($sp)
|
|
/* f041520: 11c00065 */ beqz $t6,.PB0f0416b8
|
|
/* f041524: 00000000 */ nop
|
|
/* f041528: 0fc2c84e */ jal gsetGetDamage
|
|
/* f04152c: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041530: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f041534: 240dffff */ li $t5,-1
|
|
/* f041538: 240b00c8 */ li $t3,0xc8
|
|
/* f04153c: e7a0009c */ swc1 $f0,0x9c($sp)
|
|
/* f041540: afa00098 */ sw $zero,0x98($sp)
|
|
/* f041544: afa00094 */ sw $zero,0x94($sp)
|
|
/* f041548: afad0090 */ sw $t5,0x90($sp)
|
|
/* f04154c: afab008c */ sw $t3,0x8c($sp)
|
|
/* f041550: 8d590004 */ lw $t9,0x4($t2)
|
|
/* f041554: afb90088 */ sw $t9,0x88($sp)
|
|
/* f041558: c5460008 */ lwc1 $f6,0x8($t2)
|
|
/* f04155c: e7a60228 */ swc1 $f6,0x228($sp)
|
|
/* f041560: c544000c */ lwc1 $f4,0xc($t2)
|
|
/* f041564: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
/* f041568: c54a0010 */ lwc1 $f10,0x10($t2)
|
|
/* f04156c: 0c004be0 */ jal random
|
|
/* f041570: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f041574: 304f0001 */ andi $t7,$v0,0x1
|
|
/* f041578: 11e00012 */ beqz $t7,.PB0f0415c4
|
|
/* f04157c: 00000000 */ nop
|
|
/* f041580: 0c004be0 */ jal random
|
|
/* f041584: 00000000 */ nop
|
|
/* f041588: 2401000a */ li $at,0xa
|
|
/* f04158c: 0041001b */ divu $zero,$v0,$at
|
|
/* f041590: 0000c010 */ mfhi $t8
|
|
/* f041594: 270c0002 */ addiu $t4,$t8,0x2
|
|
/* f041598: 448c9000 */ mtc1 $t4,$f18
|
|
/* f04159c: c7b0022c */ lwc1 $f16,0x22c($sp)
|
|
/* f0415a0: 05810005 */ bgez $t4,.PB0f0415b8
|
|
/* f0415a4: 46809220 */ cvt.s.w $f8,$f18
|
|
/* f0415a8: 3c014f80 */ lui $at,0x4f80
|
|
/* f0415ac: 44813000 */ mtc1 $at,$f6
|
|
/* f0415b0: 00000000 */ nop
|
|
/* f0415b4: 46064200 */ add.s $f8,$f8,$f6
|
|
.PB0f0415b8:
|
|
/* f0415b8: 46088100 */ add.s $f4,$f16,$f8
|
|
/* f0415bc: 10000011 */ b .PB0f041604
|
|
/* f0415c0: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
.PB0f0415c4:
|
|
/* f0415c4: 0c004be0 */ jal random
|
|
/* f0415c8: 00000000 */ nop
|
|
/* f0415cc: 2401000a */ li $at,0xa
|
|
/* f0415d0: 0041001b */ divu $zero,$v0,$at
|
|
/* f0415d4: 00007010 */ mfhi $t6
|
|
/* f0415d8: 25cd0002 */ addiu $t5,$t6,0x2
|
|
/* f0415dc: 448d9000 */ mtc1 $t5,$f18
|
|
/* f0415e0: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f0415e4: 05a10005 */ bgez $t5,.PB0f0415fc
|
|
/* f0415e8: 468091a0 */ cvt.s.w $f6,$f18
|
|
/* f0415ec: 3c014f80 */ lui $at,0x4f80
|
|
/* f0415f0: 44818000 */ mtc1 $at,$f16
|
|
/* f0415f4: 00000000 */ nop
|
|
/* f0415f8: 46103180 */ add.s $f6,$f6,$f16
|
|
.PB0f0415fc:
|
|
/* f0415fc: 46065201 */ sub.s $f8,$f10,$f6
|
|
/* f041600: e7a8022c */ swc1 $f8,0x22c($sp)
|
|
.PB0f041604:
|
|
/* f041604: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041608: 8fa5025c */ lw $a1,0x25c($sp)
|
|
/* f04160c: 0fc2a04d */ jal bgunPlayPropHitSound
|
|
/* f041610: 2406ffff */ li $a2,-1
|
|
/* f041614: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f041618: 8c8b0020 */ lw $t3,0x20($a0)
|
|
/* f04161c: 51600012 */ beqzl $t3,.PB0f041668
|
|
/* f041620: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f041624: 0fc0d025 */ jal chrGetShield
|
|
/* f041628: 00000000 */ nop
|
|
/* f04162c: 44802000 */ mtc1 $zero,$f4
|
|
/* f041630: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f041634: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041638: 4600203c */ c.lt.s $f4,$f0
|
|
/* f04163c: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041640: 27a70098 */ addiu $a3,$sp,0x98
|
|
/* f041644: 27b9008c */ addiu $t9,$sp,0x8c
|
|
/* f041648: 45000006 */ bc1f .PB0f041664
|
|
/* f04164c: 27aa0094 */ addiu $t2,$sp,0x94
|
|
/* f041650: 27af0090 */ addiu $t7,$sp,0x90
|
|
/* f041654: afaf0018 */ sw $t7,0x18($sp)
|
|
/* f041658: afb90010 */ sw $t9,0x10($sp)
|
|
/* f04165c: 0fc1000f */ jal chrCalculateShieldHit
|
|
/* f041660: afaa0014 */ sw $t2,0x14($sp)
|
|
.PB0f041664:
|
|
/* f041664: 8fb80278 */ lw $t8,0x278($sp)
|
|
.PB0f041668:
|
|
/* f041668: 8fad025c */ lw $t5,0x25c($sp)
|
|
/* f04166c: 8fab0098 */ lw $t3,0x98($sp)
|
|
/* f041670: 8f0c001c */ lw $t4,0x1c($t8)
|
|
/* f041674: 8fb90094 */ lw $t9,0x94($sp)
|
|
/* f041678: 8faa0090 */ lw $t2,0x90($sp)
|
|
/* f04167c: 240e00c8 */ li $t6,0xc8
|
|
/* f041680: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f041684: afae0014 */ sw $t6,0x14($sp)
|
|
/* f041688: afa00028 */ sw $zero,0x28($sp)
|
|
/* f04168c: 8fa5009c */ lw $a1,0x9c($sp)
|
|
/* f041690: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041694: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f041698: afad0018 */ sw $t5,0x18($sp)
|
|
/* f04169c: afab001c */ sw $t3,0x1c($sp)
|
|
/* f0416a0: afac0010 */ sw $t4,0x10($sp)
|
|
/* f0416a4: afb90020 */ sw $t9,0x20($sp)
|
|
/* f0416a8: 0fc0d0b4 */ jal func0f0341dc
|
|
/* f0416ac: afaa0024 */ sw $t2,0x24($sp)
|
|
/* f0416b0: 10000010 */ b .PB0f0416f4
|
|
/* f0416b4: 8fb801f0 */ lw $t8,0x1f0($sp)
|
|
.PB0f0416b8:
|
|
/* f0416b8: 11e00006 */ beqz $t7,.PB0f0416d4
|
|
/* f0416bc: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f0416c0: 91e20000 */ lbu $v0,0x0($t7)
|
|
/* f0416c4: 24010003 */ li $at,0x3
|
|
/* f0416c8: 10410009 */ beq $v0,$at,.PB0f0416f0
|
|
/* f0416cc: 24010006 */ li $at,0x6
|
|
/* f0416d0: 10410007 */ beq $v0,$at,.PB0f0416f0
|
|
.PB0f0416d4:
|
|
/* f0416d4: 3c017f1b */ lui $at,0x7f1b
|
|
/* f0416d8: c430adc0 */ lwc1 $f16,-0x5240($at)
|
|
/* f0416dc: 4610903c */ c.lt.s $f18,$f16
|
|
/* f0416e0: 00000000 */ nop
|
|
/* f0416e4: 45020003 */ bc1fl .PB0f0416f4
|
|
/* f0416e8: 8fb801f0 */ lw $t8,0x1f0($sp)
|
|
/* f0416ec: afa001f0 */ sw $zero,0x1f0($sp)
|
|
.PB0f0416f0:
|
|
/* f0416f0: 8fb801f0 */ lw $t8,0x1f0($sp)
|
|
.PB0f0416f4:
|
|
/* f0416f4: 8fac01cc */ lw $t4,0x1cc($sp)
|
|
/* f0416f8: 530000e5 */ beqzl $t8,.PB0f041a90
|
|
/* f0416fc: 8fab01c0 */ lw $t3,0x1c0($sp)
|
|
/* f041700: 118000a2 */ beqz $t4,.PB0f04198c
|
|
/* f041704: 8fab0224 */ lw $t3,0x224($sp)
|
|
/* f041708: 91820000 */ lbu $v0,0x0($t4)
|
|
/* f04170c: 24010006 */ li $at,0x6
|
|
/* f041710: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f041714: 10410003 */ beq $v0,$at,.PB0f041724
|
|
/* f041718: 24010003 */ li $at,0x3
|
|
/* f04171c: 54410053 */ bnel $v0,$at,.PB0f04186c
|
|
/* f041720: 24010001 */ li $at,0x1
|
|
.PB0f041724:
|
|
/* f041724: 15c0000c */ bnez $t6,.PB0f041758
|
|
/* f041728: 8fad01bc */ lw $t5,0x1bc($sp)
|
|
/* f04172c: 15a0000a */ bnez $t5,.PB0f041758
|
|
/* f041730: 8fab0278 */ lw $t3,0x278($sp)
|
|
/* f041734: 8d790018 */ lw $t9,0x18($t3)
|
|
/* f041738: 8faf01cc */ lw $t7,0x1cc($sp)
|
|
/* f04173c: 01602825 */ move $a1,$t3
|
|
/* f041740: 332a0040 */ andi $t2,$t9,0x40
|
|
/* f041744: 11400045 */ beqz $t2,.PB0f04185c
|
|
/* f041748: 24060002 */ li $a2,0x2
|
|
/* f04174c: 0fc12aec */ jal chrCompareTeams
|
|
/* f041750: 8de40004 */ lw $a0,0x4($t7)
|
|
/* f041754: 10400041 */ beqz $v0,.PB0f04185c
|
|
.PB0f041758:
|
|
/* f041758: 2418ffff */ li $t8,-1
|
|
/* f04175c: 240c00c8 */ li $t4,0xc8
|
|
/* f041760: afa00084 */ sw $zero,0x84($sp)
|
|
/* f041764: afa00080 */ sw $zero,0x80($sp)
|
|
/* f041768: afb8007c */ sw $t8,0x7c($sp)
|
|
/* f04176c: afac0078 */ sw $t4,0x78($sp)
|
|
/* f041770: 0fc2c84e */ jal gsetGetDamage
|
|
/* f041774: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041778: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f04177c: e7a00074 */ swc1 $f0,0x74($sp)
|
|
/* f041780: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041784: 8cad0004 */ lw $t5,0x4($a1)
|
|
/* f041788: 2406ffff */ li $a2,-1
|
|
/* f04178c: 0fc2a04d */ jal bgunPlayPropHitSound
|
|
/* f041790: afad0070 */ sw $t5,0x70($sp)
|
|
/* f041794: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041798: 8c990020 */ lw $t9,0x20($a0)
|
|
/* f04179c: 53200012 */ beqzl $t9,.PB0f0417e8
|
|
/* f0417a0: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f0417a4: 0fc0d025 */ jal chrGetShield
|
|
/* f0417a8: 00000000 */ nop
|
|
/* f0417ac: 44805000 */ mtc1 $zero,$f10
|
|
/* f0417b0: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f0417b4: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f0417b8: 4600503c */ c.lt.s $f10,$f0
|
|
/* f0417bc: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f0417c0: 27a70084 */ addiu $a3,$sp,0x84
|
|
/* f0417c4: 27aa0078 */ addiu $t2,$sp,0x78
|
|
/* f0417c8: 45000006 */ bc1f .PB0f0417e4
|
|
/* f0417cc: 27af0080 */ addiu $t7,$sp,0x80
|
|
/* f0417d0: 27ab007c */ addiu $t3,$sp,0x7c
|
|
/* f0417d4: afab0018 */ sw $t3,0x18($sp)
|
|
/* f0417d8: afaa0010 */ sw $t2,0x10($sp)
|
|
/* f0417dc: 0fc1000f */ jal chrCalculateShieldHit
|
|
/* f0417e0: afaf0014 */ sw $t7,0x14($sp)
|
|
.PB0f0417e4:
|
|
/* f0417e4: 8fac0278 */ lw $t4,0x278($sp)
|
|
.PB0f0417e8:
|
|
/* f0417e8: 27b801e0 */ addiu $t8,$sp,0x1e0
|
|
/* f0417ec: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f0417f0: afb80010 */ sw $t8,0x10($sp)
|
|
/* f0417f4: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0417f8: 8fa60078 */ lw $a2,0x78($sp)
|
|
/* f0417fc: 27a70228 */ addiu $a3,$sp,0x228
|
|
/* f041800: 0fc097dd */ jal chrEmitSparks
|
|
/* f041804: afac0014 */ sw $t4,0x14($sp)
|
|
/* f041808: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f04180c: 8faa01cc */ lw $t2,0x1cc($sp)
|
|
/* f041810: 8faf0084 */ lw $t7,0x84($sp)
|
|
/* f041814: 8dae001c */ lw $t6,0x1c($t5)
|
|
/* f041818: 8fab0080 */ lw $t3,0x80($sp)
|
|
/* f04181c: 8fb8007c */ lw $t8,0x7c($sp)
|
|
/* f041820: 241900c8 */ li $t9,0xc8
|
|
/* f041824: afb90014 */ sw $t9,0x14($sp)
|
|
/* f041828: afa00028 */ sw $zero,0x28($sp)
|
|
/* f04182c: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041830: 8fa50074 */ lw $a1,0x74($sp)
|
|
/* f041834: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041838: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f04183c: afaa0018 */ sw $t2,0x18($sp)
|
|
/* f041840: afaf001c */ sw $t7,0x1c($sp)
|
|
/* f041844: afae0010 */ sw $t6,0x10($sp)
|
|
/* f041848: afab0020 */ sw $t3,0x20($sp)
|
|
/* f04184c: 0fc0d0b4 */ jal func0f0341dc
|
|
/* f041850: afb80024 */ sw $t8,0x24($sp)
|
|
/* f041854: 1000006f */ b .PB0f041a14
|
|
/* f041858: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PB0f04185c:
|
|
/* f04185c: afa00250 */ sw $zero,0x250($sp)
|
|
/* f041860: 1000006b */ b .PB0f041a10
|
|
/* f041864: afa00268 */ sw $zero,0x268($sp)
|
|
/* f041868: 24010001 */ li $at,0x1
|
|
.PB0f04186c:
|
|
/* f04186c: 10410005 */ beq $v0,$at,.PB0f041884
|
|
/* f041870: 8fac01cc */ lw $t4,0x1cc($sp)
|
|
/* f041874: 24010004 */ li $at,0x4
|
|
/* f041878: 10410002 */ beq $v0,$at,.PB0f041884
|
|
/* f04187c: 24010002 */ li $at,0x2
|
|
/* f041880: 14410063 */ bne $v0,$at,.PB0f041a10
|
|
.PB0f041884:
|
|
/* f041884: 3c19800a */ lui $t9,0x800a
|
|
/* f041888: 8f39e7e4 */ lw $t9,-0x181c($t9)
|
|
/* f04188c: 8d8d0004 */ lw $t5,0x4($t4)
|
|
/* f041890: 240effff */ li $t6,-1
|
|
/* f041894: afae0068 */ sw $t6,0x68($sp)
|
|
/* f041898: 13200004 */ beqz $t9,.PB0f0418ac
|
|
/* f04189c: afad006c */ sw $t5,0x6c($sp)
|
|
/* f0418a0: 0fc63af1 */ jal mpPlayerGetIndex
|
|
/* f0418a4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0418a8: afa20068 */ sw $v0,0x68($sp)
|
|
.PB0f0418ac:
|
|
/* f0418ac: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f0418b0: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0418b4: 0fc2a04d */ jal bgunPlayPropHitSound
|
|
/* f0418b8: 2406ffff */ li $a2,-1
|
|
/* f0418bc: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f0418c0: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f0418c4: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0418c8: 0fc19815 */ jal func0f065e74
|
|
/* f0418cc: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f0418d0: 240a0001 */ li $t2,0x1
|
|
/* f0418d4: afaa0210 */ sw $t2,0x210($sp)
|
|
/* f0418d8: 0fc4fe8e */ jal chrIsUsingPaintball
|
|
/* f0418dc: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0418e0: 1040000b */ beqz $v0,.PB0f041910
|
|
/* f0418e4: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0418e8: 240f0019 */ li $t7,0x19
|
|
/* f0418ec: afaf0014 */ sw $t7,0x14($sp)
|
|
/* f0418f0: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0418f4: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0418f8: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0418fc: 00003825 */ move $a3,$zero
|
|
/* f041900: 0fc4c3dd */ jal sparksCreate
|
|
/* f041904: afa00010 */ sw $zero,0x10($sp)
|
|
/* f041908: 10000007 */ b .PB0f041928
|
|
/* f04190c: 00000000 */ nop
|
|
.PB0f041910:
|
|
/* f041910: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f041914: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041918: 00003825 */ move $a3,$zero
|
|
/* f04191c: afa00010 */ sw $zero,0x10($sp)
|
|
/* f041920: 0fc4c3dd */ jal sparksCreate
|
|
/* f041924: afa00014 */ sw $zero,0x14($sp)
|
|
.PB0f041928:
|
|
/* f041928: 3c0b800a */ lui $t3,0x800a
|
|
/* f04192c: 8178251b */ lb $t8,0x251b($t3)
|
|
/* f041930: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f041934: 0701000a */ bgez $t8,.PB0f041960
|
|
/* f041938: 00000000 */ nop
|
|
/* f04193c: 918d0125 */ lbu $t5,0x125($t4)
|
|
/* f041940: 24010010 */ li $at,0x10
|
|
/* f041944: 8fae006c */ lw $t6,0x6c($sp)
|
|
/* f041948: 15a10005 */ bne $t5,$at,.PB0f041960
|
|
/* f04194c: 00000000 */ nop
|
|
/* f041950: 8dd9000c */ lw $t9,0xc($t6)
|
|
/* f041954: 332a0001 */ andi $t2,$t9,0x1
|
|
/* f041958: 5540002e */ bnezl $t2,.PB0f041a14
|
|
/* f04195c: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PB0f041960:
|
|
/* f041960: 0fc2c84e */ jal gsetGetDamage
|
|
/* f041964: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041968: 8faf0068 */ lw $t7,0x68($sp)
|
|
/* f04196c: 44050000 */ mfc1 $a1,$f0
|
|
/* f041970: 8fa4006c */ lw $a0,0x6c($sp)
|
|
/* f041974: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041978: 93a70260 */ lbu $a3,0x260($sp)
|
|
/* f04197c: 0fc21504 */ jal objTakeGunfire
|
|
/* f041980: afaf0010 */ sw $t7,0x10($sp)
|
|
/* f041984: 10000023 */ b .PB0f041a14
|
|
/* f041988: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PB0f04198c:
|
|
/* f04198c: 11600020 */ beqz $t3,.PB0f041a10
|
|
/* f041990: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041994: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041998: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f04199c: 0fc19815 */ jal func0f065e74
|
|
/* f0419a0: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f0419a4: 24180001 */ li $t8,0x1
|
|
/* f0419a8: afb80210 */ sw $t8,0x210($sp)
|
|
/* f0419ac: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f0419b0: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f0419b4: 2406ffff */ li $a2,-1
|
|
/* f0419b8: 0fc2a219 */ jal bgunPlayBgHitSound
|
|
/* f0419bc: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f0419c0: 0fc4fe8e */ jal chrIsUsingPaintball
|
|
/* f0419c4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0419c8: 1040000b */ beqz $v0,.PB0f0419f8
|
|
/* f0419cc: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0419d0: 240c0019 */ li $t4,0x19
|
|
/* f0419d4: afac0014 */ sw $t4,0x14($sp)
|
|
/* f0419d8: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0419dc: 00002825 */ move $a1,$zero
|
|
/* f0419e0: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0419e4: 00003825 */ move $a3,$zero
|
|
/* f0419e8: 0fc4c3dd */ jal sparksCreate
|
|
/* f0419ec: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0419f0: 10000008 */ b .PB0f041a14
|
|
/* f0419f4: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PB0f0419f8:
|
|
/* f0419f8: 00002825 */ move $a1,$zero
|
|
/* f0419fc: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041a00: 00003825 */ move $a3,$zero
|
|
/* f041a04: afa00010 */ sw $zero,0x10($sp)
|
|
/* f041a08: 0fc4c3dd */ jal sparksCreate
|
|
/* f041a0c: afa00014 */ sw $zero,0x14($sp)
|
|
.PB0f041a10:
|
|
/* f041a10: 93ad0260 */ lbu $t5,0x260($sp)
|
|
.PB0f041a14:
|
|
/* f041a14: 24010007 */ li $at,0x7
|
|
/* f041a18: 93ae0263 */ lbu $t6,0x263($sp)
|
|
/* f041a1c: 15a1001b */ bne $t5,$at,.PB0f041a8c
|
|
/* f041a20: 24010001 */ li $at,0x1
|
|
/* f041a24: 15c10019 */ bne $t6,$at,.PB0f041a8c
|
|
/* f041a28: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f041a2c: 8f2a02d4 */ lw $t2,0x2d4($t9)
|
|
/* f041a30: 3c03800a */ lui $v1,0x800a
|
|
/* f041a34: 11400005 */ beqz $t2,.PB0f041a4c
|
|
/* f041a38: 00000000 */ nop
|
|
/* f041a3c: 0fc63af1 */ jal mpPlayerGetIndex
|
|
/* f041a40: 03202025 */ move $a0,$t9
|
|
/* f041a44: 10000002 */ b .PB0f041a50
|
|
/* f041a48: 00401825 */ move $v1,$v0
|
|
.PB0f041a4c:
|
|
/* f041a4c: 8c63e75c */ lw $v1,-0x18a4($v1)
|
|
.PB0f041a50:
|
|
/* f041a50: 8faf0210 */ lw $t7,0x210($sp)
|
|
/* f041a54: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041a58: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041a5c: 15e00005 */ bnez $t7,.PB0f041a74
|
|
/* f041a60: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041a64: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041a68: 0fc19815 */ jal func0f065e74
|
|
/* f041a6c: afa30064 */ sw $v1,0x64($sp)
|
|
/* f041a70: 8fa30064 */ lw $v1,0x64($sp)
|
|
.PB0f041a74:
|
|
/* f041a74: 00002025 */ move $a0,$zero
|
|
/* f041a78: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041a7c: 27a60214 */ addiu $a2,$sp,0x214
|
|
/* f041a80: 24070016 */ li $a3,0x16
|
|
/* f041a84: 0fc4ab78 */ jal explosionCreateSimple
|
|
/* f041a88: afa30010 */ sw $v1,0x10($sp)
|
|
.PB0f041a8c:
|
|
/* f041a8c: 8fab01c0 */ lw $t3,0x1c0($sp)
|
|
.PB0f041a90:
|
|
/* f041a90: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f041a94: 51600004 */ beqzl $t3,.PB0f041aa8
|
|
/* f041a98: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f041a9c: 0fc190d6 */ jal propSetPerimEnabled
|
|
/* f041aa0: 00002825 */ move $a1,$zero
|
|
/* f041aa4: 8fa80268 */ lw $t0,0x268($sp)
|
|
.PB0f041aa8:
|
|
/* f041aa8: 8fac0250 */ lw $t4,0x250($sp)
|
|
/* f041aac: 93ad0260 */ lbu $t5,0x260($sp)
|
|
/* f041ab0: 0008c02b */ sltu $t8,$zero,$t0
|
|
/* f041ab4: 1180000e */ beqz $t4,.PB0f041af0
|
|
/* f041ab8: 03004025 */ move $t0,$t8
|
|
/* f041abc: 25aefffe */ addiu $t6,$t5,-2
|
|
/* f041ac0: 2dc1002a */ sltiu $at,$t6,0x2a
|
|
/* f041ac4: 10200009 */ beqz $at,.PB0f041aec
|
|
/* f041ac8: 000e7080 */ sll $t6,$t6,0x2
|
|
/* f041acc: 3c017f1b */ lui $at,0x7f1b
|
|
/* f041ad0: 002e0821 */ addu $at,$at,$t6
|
|
/* f041ad4: 8c2eadc4 */ lw $t6,-0x523c($at)
|
|
/* f041ad8: 01c00008 */ jr $t6
|
|
/* f041adc: 00000000 */ nop
|
|
/* f041ae0: 240a0001 */ li $t2,0x1
|
|
/* f041ae4: 10000002 */ b .PB0f041af0
|
|
/* f041ae8: afaa0250 */ sw $t2,0x250($sp)
|
|
.PB0f041aec:
|
|
/* f041aec: afa00250 */ sw $zero,0x250($sp)
|
|
.PB0f041af0:
|
|
/* f041af0: 11000004 */ beqz $t0,.PB0f041b04
|
|
/* f041af4: 01003825 */ move $a3,$t0
|
|
/* f041af8: 8fa70250 */ lw $a3,0x250($sp)
|
|
/* f041afc: 0007c82b */ sltu $t9,$zero,$a3
|
|
/* f041b00: 03203825 */ move $a3,$t9
|
|
.PB0f041b04:
|
|
/* f041b04: 27af0244 */ addiu $t7,$sp,0x244
|
|
/* f041b08: 27ab0228 */ addiu $t3,$sp,0x228
|
|
/* f041b0c: afab0014 */ sw $t3,0x14($sp)
|
|
/* f041b10: afaf0010 */ sw $t7,0x10($sp)
|
|
/* f041b14: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041b18: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041b1c: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f041b20: 0fc0f8eb */ jal chrCreateFireslot
|
|
/* f041b24: afa80054 */ sw $t0,0x54($sp)
|
|
/* f041b28: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f041b2c: 8fa80054 */ lw $t0,0x54($sp)
|
|
/* f041b30: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041b34: 13000015 */ beqz $t8,.PB0f041b8c
|
|
/* f041b38: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041b3c: 1100000a */ beqz $t0,.PB0f041b68
|
|
/* f041b40: 01003025 */ move $a2,$t0
|
|
/* f041b44: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f041b48: 8fae027c */ lw $t6,0x27c($sp)
|
|
/* f041b4c: 8d8d02d4 */ lw $t5,0x2d4($t4)
|
|
/* f041b50: 000e5080 */ sll $t2,$t6,0x2
|
|
/* f041b54: 01aa1021 */ addu $v0,$t5,$t2
|
|
/* f041b58: 8c430024 */ lw $v1,0x24($v0)
|
|
/* f041b5c: 18600002 */ blez $v1,.PB0f041b68
|
|
/* f041b60: 2479ffff */ addiu $t9,$v1,-1
|
|
/* f041b64: ac590024 */ sw $t9,0x24($v0)
|
|
.PB0f041b68:
|
|
/* f041b68: 11000004 */ beqz $t0,.PB0f041b7c
|
|
/* f041b6c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041b70: 93a6026e */ lbu $a2,0x26e($sp)
|
|
/* f041b74: 0006782b */ sltu $t7,$zero,$a2
|
|
/* f041b78: 01e03025 */ move $a2,$t7
|
|
.PB0f041b7c:
|
|
/* f041b7c: 0fc0fe56 */ jal chrSetFiring
|
|
/* f041b80: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041b84: 10000004 */ b .PB0f041b98
|
|
/* f041b88: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.PB0f041b8c:
|
|
/* f041b8c: 0fc0fe56 */ jal chrSetFiring
|
|
/* f041b90: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f041b94: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.PB0f041b98:
|
|
/* f041b98: 27bd0278 */ addiu $sp,$sp,0x278
|
|
/* f041b9c: 03e00008 */ jr $ra
|
|
/* f041ba0: 00000000 */ nop
|
|
);
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
GLOBAL_ASM(
|
|
glabel chrShoot
|
|
.late_rodata
|
|
glabel var7f1a90c8
|
|
.word 0x3d638e39
|
|
glabel var7f1a90cc
|
|
.word 0x481c4000
|
|
glabel var7f1a90d0
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d4
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d8
|
|
.word 0x3fd55555
|
|
glabel var7f1a90dc
|
|
.word 0x461c4000
|
|
glabel var7f1a90e0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a90e4
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a90e8
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a90ec
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a90f0
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a90f4
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a90f8
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a90fc
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9100
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9104
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9108
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a910c
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9110
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9114
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9118
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a911c
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9120
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9124
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9128
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a912c
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9130
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9134
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9138
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a913c
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9140
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9144
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9148
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a914c
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9150
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9154
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9158
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a915c
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9160
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9164
|
|
.word chrShoot+0x14e8 # f0419bc
|
|
glabel var7f1a9168
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a916c
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9170
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9174
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9178
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a917c
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9180
|
|
.word chrShoot+0x14dc # f0419b0
|
|
glabel var7f1a9184
|
|
.word chrShoot+0x14dc # f0419b0
|
|
.text
|
|
/* f0404d4: 27bdfd88 */ addiu $sp,$sp,-632
|
|
/* f0404d8: afbf0044 */ sw $ra,0x44($sp)
|
|
/* f0404dc: afa5027c */ sw $a1,0x27c($sp)
|
|
/* f0404e0: 8c8e001c */ lw $t6,0x1c($a0)
|
|
/* f0404e4: 240f0001 */ addiu $t7,$zero,0x1
|
|
/* f0404e8: a3af026e */ sb $t7,0x26e($sp)
|
|
/* f0404ec: afae0274 */ sw $t6,0x274($sp)
|
|
/* f0404f0: 8c9802d4 */ lw $t8,0x2d4($a0)
|
|
/* f0404f4: 00001025 */ or $v0,$zero,$zero
|
|
/* f0404f8: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f0404fc: 53000003 */ beqzl $t8,.L0f04050c
|
|
/* f040500: a3a2026f */ sb $v0,0x26f($sp)
|
|
/* f040504: 24020001 */ addiu $v0,$zero,0x1
|
|
/* f040508: a3a2026f */ sb $v0,0x26f($sp)
|
|
.L0f04050c:
|
|
/* f04050c: 0fc0a209 */ jal chrGetHeldProp
|
|
/* f040510: afa40278 */ sw $a0,0x278($sp)
|
|
/* f040514: 50400554 */ beqzl $v0,.L0f041a68
|
|
/* f040518: 8fbf0044 */ lw $ra,0x44($sp)
|
|
/* f04051c: afa00268 */ sw $zero,0x268($sp)
|
|
/* f040520: 8c590004 */ lw $t9,0x4($v0)
|
|
/* f040524: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040528: 0fc0a221 */ jal chrGetTargetProp
|
|
/* f04052c: afb90264 */ sw $t9,0x264($sp)
|
|
/* f040530: 8fab0264 */ lw $t3,0x264($sp)
|
|
/* f040534: afa2025c */ sw $v0,0x25c($sp)
|
|
/* f040538: 8fa70278 */ lw $a3,0x278($sp)
|
|
/* f04053c: 8961005c */ lwl $at,0x5c($t3)
|
|
/* f040540: 9961005f */ lwr $at,0x5f($t3)
|
|
/* f040544: 27aa0260 */ addiu $t2,$sp,0x260
|
|
/* f040548: 24080200 */ addiu $t0,$zero,0x200
|
|
/* f04054c: ad410000 */ sw $at,0x0($t2)
|
|
/* f040550: 80e30007 */ lb $v1,0x7($a3)
|
|
/* f040554: 24010008 */ addiu $at,$zero,0x8
|
|
/* f040558: 10610007 */ beq $v1,$at,.L0f040578
|
|
/* f04055c: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f040560: 10610005 */ beq $v1,$at,.L0f040578
|
|
/* f040564: 2401001c */ addiu $at,$zero,0x1c
|
|
/* f040568: 10610003 */ beq $v1,$at,.L0f040578
|
|
/* f04056c: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f040570: 54610003 */ bnel $v1,$at,.L0f040580
|
|
/* f040574: afa00250 */ sw $zero,0x250($sp)
|
|
.L0f040578:
|
|
/* f040578: 8ce8004c */ lw $t0,0x4c($a3)
|
|
/* f04057c: afa00250 */ sw $zero,0x250($sp)
|
|
.L0f040580:
|
|
/* f040580: afa00224 */ sw $zero,0x224($sp)
|
|
/* f040584: afa00210 */ sw $zero,0x210($sp)
|
|
/* f040588: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f04058c: 93a50263 */ lbu $a1,0x263($sp)
|
|
/* f040590: afa00254 */ sw $zero,0x254($sp)
|
|
/* f040594: 0fc2c7ba */ jal weaponGetNumTicksPerShot
|
|
/* f040598: afa80258 */ sw $t0,0x258($sp)
|
|
/* f04059c: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f0405a0: 1c400005 */ bgtz $v0,.L0f0405b8
|
|
/* f0405a4: 00402025 */ or $a0,$v0,$zero
|
|
/* f0405a8: 240f0001 */ addiu $t7,$zero,0x1
|
|
/* f0405ac: 24060001 */ addiu $a2,$zero,0x1
|
|
/* f0405b0: 10000055 */ b .L0f040708
|
|
/* f0405b4: afaf0250 */ sw $t7,0x250($sp)
|
|
.L0f0405b8:
|
|
/* f0405b8: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f0405bc: 8f0302d4 */ lw $v1,0x2d4($t8)
|
|
/* f0405c0: 5060001d */ beqzl $v1,.L0f040638
|
|
/* f0405c4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f0405c8: 8c790020 */ lw $t9,0x20($v1)
|
|
/* f0405cc: 24010014 */ addiu $at,$zero,0x14
|
|
/* f0405d0: 57210019 */ bnel $t9,$at,.L0f040638
|
|
/* f0405d4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f0405d8: 8c6d004c */ lw $t5,0x4c($v1)
|
|
/* f0405dc: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f0405e0: 000d5080 */ sll $t2,$t5,0x2
|
|
/* f0405e4: 05400013 */ bltz $t2,.L0f040634
|
|
/* f0405e8: 000b7040 */ sll $t6,$t3,0x1
|
|
/* f0405ec: 006e7821 */ addu $t7,$v1,$t6
|
|
/* f0405f0: 85f800e0 */ lh $t8,0xe0($t7)
|
|
/* f0405f4: 2419005a */ addiu $t9,$zero,0x5a
|
|
/* f0405f8: 3c017f1b */ lui $at,%hi(var7f1a90c8)
|
|
/* f0405fc: 03386823 */ subu $t5,$t9,$t8
|
|
/* f040600: 448d2000 */ mtc1 $t5,$f4
|
|
/* f040604: c42890c8 */ lwc1 $f8,%lo(var7f1a90c8)($at)
|
|
/* f040608: 44825000 */ mtc1 $v0,$f10
|
|
/* f04060c: 468021a0 */ cvt.s.w $f6,$f4
|
|
/* f040610: 3c013f80 */ lui $at,0x3f80
|
|
/* f040614: 44819000 */ mtc1 $at,$f18
|
|
/* f040618: 46805420 */ cvt.s.w $f16,$f10
|
|
/* f04061c: 46083002 */ mul.s $f0,$f6,$f8
|
|
/* f040620: 46009100 */ add.s $f4,$f18,$f0
|
|
/* f040624: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f040628: 4600320d */ trunc.w.s $f8,$f6
|
|
/* f04062c: 44044000 */ mfc1 $a0,$f8
|
|
/* f040630: 00000000 */ nop
|
|
.L0f040634:
|
|
/* f040634: 8faa0278 */ lw $t2,0x278($sp)
|
|
.L0f040638:
|
|
/* f040638: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f04063c: 3c0f800a */ lui $t7,%hi(g_Vars+0x38)
|
|
/* f040640: 8def9ff8 */ lw $t7,%lo(g_Vars+0x38)($t7)
|
|
/* f040644: 014b1821 */ addu $v1,$t2,$t3
|
|
/* f040648: 906e0004 */ lbu $t6,0x4($v1)
|
|
/* f04064c: 01cfc821 */ addu $t9,$t6,$t7
|
|
/* f040650: 333800ff */ andi $t8,$t9,0xff
|
|
/* f040654: 0304082a */ slt $at,$t8,$a0
|
|
/* f040658: 1420002b */ bnez $at,.L0f040708
|
|
/* f04065c: a0790004 */ sb $t9,0x4($v1)
|
|
/* f040660: a0600004 */ sb $zero,0x4($v1)
|
|
/* f040664: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f040668: 8fad027c */ lw $t5,0x27c($sp)
|
|
/* f04066c: 240c0001 */ addiu $t4,$zero,0x1
|
|
/* f040670: 8d4b032c */ lw $t3,0x32c($t2)
|
|
/* f040674: 01ac1004 */ sllv $v0,$t4,$t5
|
|
/* f040678: 24060001 */ addiu $a2,$zero,0x1
|
|
/* f04067c: 000b7300 */ sll $t6,$t3,0xc
|
|
/* f040680: 914b032d */ lbu $t3,0x32d($t2)
|
|
/* f040684: 000e7f82 */ srl $t7,$t6,0x1e
|
|
/* f040688: 01e2c026 */ xor $t8,$t7,$v0
|
|
/* f04068c: 00186080 */ sll $t4,$t8,0x2
|
|
/* f040690: 318d000c */ andi $t5,$t4,0xc
|
|
/* f040694: 316efff3 */ andi $t6,$t3,0xfff3
|
|
/* f040698: 01ae7825 */ or $t7,$t5,$t6
|
|
/* f04069c: a14f032d */ sb $t7,0x32d($t2)
|
|
/* f0406a0: 8d59032c */ lw $t9,0x32c($t2)
|
|
/* f0406a4: 93ad0260 */ lbu $t5,0x260($sp)
|
|
/* f0406a8: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f0406ac: 0019c300 */ sll $t8,$t9,0xc
|
|
/* f0406b0: 00186782 */ srl $t4,$t8,0x1e
|
|
/* f0406b4: 01825824 */ and $t3,$t4,$v0
|
|
/* f0406b8: 15600003 */ bnez $t3,.L0f0406c8
|
|
/* f0406bc: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f0406c0: 55a10003 */ bnel $t5,$at,.L0f0406d0
|
|
/* f0406c4: 8faf0278 */ lw $t7,0x278($sp)
|
|
.L0f0406c8:
|
|
/* f0406c8: afae0250 */ sw $t6,0x250($sp)
|
|
/* f0406cc: 8faf0278 */ lw $t7,0x278($sp)
|
|
.L0f0406d0:
|
|
/* f0406d0: 24010008 */ addiu $at,$zero,0x8
|
|
/* f0406d4: 81ea0007 */ lb $t2,0x7($t7)
|
|
/* f0406d8: 1541000b */ bne $t2,$at,.L0f040708
|
|
/* f0406dc: 00000000 */ nop
|
|
/* f0406e0: 8de40020 */ lw $a0,0x20($t7)
|
|
/* f0406e4: 0c00744f */ jal modelGetAnimNum
|
|
/* f0406e8: afa60254 */ sw $a2,0x254($sp)
|
|
/* f0406ec: 2401026a */ addiu $at,$zero,0x26a
|
|
/* f0406f0: 14410005 */ bne $v0,$at,.L0f040708
|
|
/* f0406f4: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f0406f8: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f0406fc: 83380033 */ lb $t8,0x33($t9)
|
|
/* f040700: 270c0001 */ addiu $t4,$t8,0x1
|
|
/* f040704: a32c0033 */ sb $t4,0x33($t9)
|
|
.L0f040708:
|
|
/* f040708: 50c0049b */ beqzl $a2,.L0f041978
|
|
/* f04070c: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f040710: 0fc0f97c */ jal chrGetAimAngle
|
|
/* f040714: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040718: e7a00204 */ swc1 $f0,0x204($sp)
|
|
/* f04071c: 0fc0f9d5 */ jal func0f03e754
|
|
/* f040720: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040724: 93ab026f */ lbu $t3,0x26f($sp)
|
|
/* f040728: e7a00200 */ swc1 $f0,0x200($sp)
|
|
/* f04072c: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f040730: 11600004 */ beqz $t3,.L0f040744
|
|
/* f040734: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f040738: 240d0004 */ addiu $t5,$zero,0x4
|
|
/* f04073c: 10000002 */ b .L0f040748
|
|
/* f040740: afad01fc */ sw $t5,0x1fc($sp)
|
|
.L0f040744:
|
|
/* f040744: afa001fc */ sw $zero,0x1fc($sp)
|
|
.L0f040748:
|
|
/* f040748: afae0268 */ sw $t6,0x268($sp)
|
|
/* f04074c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040750: 0fc0ff79 */ jal chrGetGunPos
|
|
/* f040754: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f040758: 54400032 */ bnezl $v0,.L0f040824
|
|
/* f04075c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040760: 8fa20274 */ lw $v0,0x274($sp)
|
|
/* f040764: 3c0141f0 */ lui $at,0x41f0
|
|
/* f040768: 44818000 */ mtc1 $at,$f16
|
|
/* f04076c: c44a0008 */ lwc1 $f10,0x8($v0)
|
|
/* f040770: 8faa027c */ lw $t2,0x27c($sp)
|
|
/* f040774: 24010001 */ addiu $at,$zero,0x1
|
|
/* f040778: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f04077c: c452000c */ lwc1 $f18,0xc($v0)
|
|
/* f040780: 46109100 */ add.s $f4,$f18,$f16
|
|
/* f040784: e7a40248 */ swc1 $f4,0x248($sp)
|
|
/* f040788: c4460010 */ lwc1 $f6,0x10($v0)
|
|
/* f04078c: 15410013 */ bne $t2,$at,.L0f0407dc
|
|
/* f040790: e7a6024c */ swc1 $f6,0x24c($sp)
|
|
/* f040794: 0c0068f4 */ jal cosf
|
|
/* f040798: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f04079c: 3c014120 */ lui $at,0x4120
|
|
/* f0407a0: 44815000 */ mtc1 $at,$f10
|
|
/* f0407a4: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f0407a8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0407ac: 460a0482 */ mul.s $f18,$f0,$f10
|
|
/* f0407b0: 46124400 */ add.s $f16,$f8,$f18
|
|
/* f0407b4: 0c0068f7 */ jal sinf
|
|
/* f0407b8: e7b00244 */ swc1 $f16,0x244($sp)
|
|
/* f0407bc: 3c014120 */ lui $at,0x4120
|
|
/* f0407c0: 44813000 */ mtc1 $at,$f6
|
|
/* f0407c4: 46000107 */ neg.s $f4,$f0
|
|
/* f0407c8: c7a8024c */ lwc1 $f8,0x24c($sp)
|
|
/* f0407cc: 46062282 */ mul.s $f10,$f4,$f6
|
|
/* f0407d0: 460a4480 */ add.s $f18,$f8,$f10
|
|
/* f0407d4: 10000012 */ b .L0f040820
|
|
/* f0407d8: e7b2024c */ swc1 $f18,0x24c($sp)
|
|
.L0f0407dc:
|
|
/* f0407dc: 0c0068f4 */ jal cosf
|
|
/* f0407e0: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0407e4: 3c014120 */ lui $at,0x4120
|
|
/* f0407e8: 44812000 */ mtc1 $at,$f4
|
|
/* f0407ec: 46000407 */ neg.s $f16,$f0
|
|
/* f0407f0: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f0407f4: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f0407f8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0407fc: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040800: 0c0068f7 */ jal sinf
|
|
/* f040804: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f040808: 3c014120 */ lui $at,0x4120
|
|
/* f04080c: 44818000 */ mtc1 $at,$f16
|
|
/* f040810: c7b2024c */ lwc1 $f18,0x24c($sp)
|
|
/* f040814: 46100102 */ mul.s $f4,$f0,$f16
|
|
/* f040818: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f04081c: e7a8024c */ swc1 $f8,0x24c($sp)
|
|
.L0f040820:
|
|
/* f040820: 8fa40278 */ lw $a0,0x278($sp)
|
|
.L0f040824:
|
|
/* f040824: 0fc079ef */ jal chrSetPerimEnabled
|
|
/* f040828: 00002825 */ or $a1,$zero,$zero
|
|
/* f04082c: 8fb801fc */ lw $t8,0x1fc($sp)
|
|
/* f040830: 8faf0274 */ lw $t7,0x274($sp)
|
|
/* f040834: 24190010 */ addiu $t9,$zero,0x10
|
|
/* f040838: 370c082a */ ori $t4,$t8,0x82a
|
|
/* f04083c: afac0010 */ sw $t4,0x10($sp)
|
|
/* f040840: afb90014 */ sw $t9,0x14($sp)
|
|
/* f040844: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f040848: 27a70234 */ addiu $a3,$sp,0x234
|
|
/* f04084c: 25e40008 */ addiu $a0,$t7,0x8
|
|
/* f040850: 0c00b78d */ jal cd0002de34
|
|
/* f040854: 25e50028 */ addiu $a1,$t7,0x28
|
|
/* f040858: 14400002 */ bnez $v0,.L0f040864
|
|
/* f04085c: 24050001 */ addiu $a1,$zero,0x1
|
|
/* f040860: afa00268 */ sw $zero,0x268($sp)
|
|
.L0f040864:
|
|
/* f040864: 0fc079ef */ jal chrSetPerimEnabled
|
|
/* f040868: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f04086c: 8fab0268 */ lw $t3,0x268($sp)
|
|
/* f040870: 240d0001 */ addiu $t5,$zero,0x1
|
|
/* f040874: 51600440 */ beqzl $t3,.L0f041978
|
|
/* f040878: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f04087c: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f040880: afa001f8 */ sw $zero,0x1f8($sp)
|
|
/* f040884: afa001f4 */ sw $zero,0x1f4($sp)
|
|
/* f040888: afad01f0 */ sw $t5,0x1f0($sp)
|
|
/* f04088c: 11c00004 */ beqz $t6,.L0f0408a0
|
|
/* f040890: afa001cc */ sw $zero,0x1cc($sp)
|
|
/* f040894: 240a083f */ addiu $t2,$zero,0x83f
|
|
/* f040898: 10000003 */ b .L0f0408a8
|
|
/* f04089c: afaa01c8 */ sw $t2,0x1c8($sp)
|
|
.L0f0408a0:
|
|
/* f0408a0: 240f083b */ addiu $t7,$zero,0x83b
|
|
/* f0408a4: afaf01c8 */ sw $t7,0x1c8($sp)
|
|
.L0f0408a8:
|
|
/* f0408a8: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f0408ac: 8ce20004 */ lw $v0,0x4($a3)
|
|
/* f0408b0: 50400004 */ beqzl $v0,.L0f0408c4
|
|
/* f0408b4: 00004825 */ or $t1,$zero,$zero
|
|
/* f0408b8: 10000002 */ b .L0f0408c4
|
|
/* f0408bc: 904902fe */ lbu $t1,0x2fe($v0)
|
|
/* f0408c0: 00004825 */ or $t1,$zero,$zero
|
|
.L0f0408c4:
|
|
/* f0408c4: 39220003 */ xori $v0,$t1,0x3
|
|
/* f0408c8: 2c420001 */ sltiu $v0,$v0,0x1
|
|
/* f0408cc: 1040000f */ beqz $v0,.L0f04090c
|
|
/* f0408d0: 00401825 */ or $v1,$v0,$zero
|
|
/* f0408d4: afa2005c */ sw $v0,0x5c($sp)
|
|
/* f0408d8: 0fc12472 */ jal chrGetDistanceToTarget
|
|
/* f0408dc: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0408e0: 3c014316 */ lui $at,0x4316
|
|
/* f0408e4: 44813000 */ mtc1 $at,$f6
|
|
/* f0408e8: 0000c025 */ or $t8,$zero,$zero
|
|
/* f0408ec: 4600303c */ c.lt.s $f6,$f0
|
|
/* f0408f0: 00000000 */ nop
|
|
/* f0408f4: 45020003 */ bc1fl .L0f040904
|
|
/* f0408f8: afb8005c */ sw $t8,0x5c($sp)
|
|
/* f0408fc: 24180001 */ addiu $t8,$zero,0x1
|
|
/* f040900: afb8005c */ sw $t8,0x5c($sp)
|
|
.L0f040904:
|
|
/* f040904: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f040908: 03001825 */ or $v1,$t8,$zero
|
|
.L0f04090c:
|
|
/* f04090c: afa301c0 */ sw $v1,0x1c0($sp)
|
|
/* f040910: 10600016 */ beqz $v1,.L0f04096c
|
|
/* f040914: afa001bc */ sw $zero,0x1bc($sp)
|
|
/* f040918: c4ea0008 */ lwc1 $f10,0x8($a3)
|
|
/* f04091c: c7b00244 */ lwc1 $f16,0x244($sp)
|
|
/* f040920: c7a80248 */ lwc1 $f8,0x248($sp)
|
|
/* f040924: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040928: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f04092c: c7b0024c */ lwc1 $f16,0x24c($sp)
|
|
/* f040930: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040934: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040938: e7b201e0 */ swc1 $f18,0x1e0($sp)
|
|
/* f04093c: c4e4000c */ lwc1 $f4,0xc($a3)
|
|
/* f040940: 46082181 */ sub.s $f6,$f4,$f8
|
|
/* f040944: e7a601e4 */ swc1 $f6,0x1e4($sp)
|
|
/* f040948: c4ea0010 */ lwc1 $f10,0x10($a3)
|
|
/* f04094c: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f040950: 0c0011e4 */ jal guNormalize
|
|
/* f040954: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
/* f040958: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f04095c: 0fc1905e */ jal propSetPerimEnabled
|
|
/* f040960: 24050001 */ addiu $a1,$zero,0x1
|
|
/* f040964: 1000002f */ b .L0f040a24
|
|
/* f040968: 8fab0278 */ lw $t3,0x278($sp)
|
|
.L0f04096c:
|
|
/* f04096c: 0c0068f4 */ jal cosf
|
|
/* f040970: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040974: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f040978: 0c0068f7 */ jal sinf
|
|
/* f04097c: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040980: c7a40060 */ lwc1 $f4,0x60($sp)
|
|
/* f040984: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040988: 46040202 */ mul.s $f8,$f0,$f4
|
|
/* f04098c: 0c0068f7 */ jal sinf
|
|
/* f040990: e7a801e0 */ swc1 $f8,0x1e0($sp)
|
|
/* f040994: e7a001e4 */ swc1 $f0,0x1e4($sp)
|
|
/* f040998: 0c0068f4 */ jal cosf
|
|
/* f04099c: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f0409a0: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f0409a4: 0c0068f4 */ jal cosf
|
|
/* f0409a8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0409ac: c7a60060 */ lwc1 $f6,0x60($sp)
|
|
/* f0409b0: 93ac026f */ lbu $t4,0x26f($sp)
|
|
/* f0409b4: 46060282 */ mul.s $f10,$f0,$f6
|
|
/* f0409b8: 11800019 */ beqz $t4,.L0f040a20
|
|
/* f0409bc: e7aa01e8 */ swc1 $f10,0x1e8($sp)
|
|
/* f0409c0: 0fc644fe */ jal botGuessCrouchPos
|
|
/* f0409c4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0409c8: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f0409cc: 00404825 */ or $t1,$v0,$zero
|
|
/* f0409d0: 8fae0278 */ lw $t6,0x278($sp)
|
|
/* f0409d4: 8f280170 */ lw $t0,0x170($t9)
|
|
/* f0409d8: 0008582b */ sltu $t3,$zero,$t0
|
|
/* f0409dc: 11600004 */ beqz $t3,.L0f0409f0
|
|
/* f0409e0: 01604025 */ or $t0,$t3,$zero
|
|
/* f0409e4: 8f280174 */ lw $t0,0x174($t9)
|
|
/* f0409e8: 0008682b */ sltu $t5,$zero,$t0
|
|
/* f0409ec: 01a04025 */ or $t0,$t5,$zero
|
|
.L0f0409f0:
|
|
/* f0409f0: 8dc302d4 */ lw $v1,0x2d4($t6)
|
|
/* f0409f4: 8fb8027c */ lw $t8,0x27c($sp)
|
|
/* f0409f8: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f0409fc: 8c66004c */ lw $a2,0x4c($v1)
|
|
/* f040a00: 00786021 */ addu $t4,$v1,$t8
|
|
/* f040a04: 9187004d */ lbu $a3,0x4d($t4)
|
|
/* f040a08: 8c650020 */ lw $a1,0x20($v1)
|
|
/* f040a0c: 00065080 */ sll $t2,$a2,0x2
|
|
/* f040a10: 000a37c2 */ srl $a2,$t2,0x1f
|
|
/* f040a14: afa80014 */ sw $t0,0x14($sp)
|
|
/* f040a18: 0fc283eb */ jal bgunCalculateBotShotSpread
|
|
/* f040a1c: afa90010 */ sw $t1,0x10($sp)
|
|
.L0f040a20:
|
|
/* f040a20: 8fab0278 */ lw $t3,0x278($sp)
|
|
.L0f040a24:
|
|
/* f040a24: 93b90260 */ lbu $t9,0x260($sp)
|
|
/* f040a28: 24010016 */ addiu $at,$zero,0x16
|
|
/* f040a2c: 8d6302d4 */ lw $v1,0x2d4($t3)
|
|
/* f040a30: 50600018 */ beqzl $v1,.L0f040a94
|
|
/* f040a34: 3c014780 */ lui $at,0x4780
|
|
/* f040a38: 57210016 */ bnel $t9,$at,.L0f040a94
|
|
/* f040a3c: 3c014780 */ lui $at,0x4780
|
|
/* f040a40: 8c6d0128 */ lw $t5,0x128($v1)
|
|
/* f040a44: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f040a48: 01602025 */ or $a0,$t3,$zero
|
|
/* f040a4c: 15a00010 */ bnez $t5,.L0f040a90
|
|
/* f040a50: 00002825 */ or $a1,$zero,$zero
|
|
/* f040a54: afae0250 */ sw $t6,0x250($sp)
|
|
/* f040a58: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f040a5c: 0fc667e1 */ jal botactShootFarsight
|
|
/* f040a60: 27a70244 */ addiu $a3,$sp,0x244
|
|
/* f040a64: 24010002 */ addiu $at,$zero,0x2
|
|
/* f040a68: 5441000a */ bnel $v0,$at,.L0f040a94
|
|
/* f040a6c: 3c014780 */ lui $at,0x4780
|
|
/* f040a70: 0c004b70 */ jal random
|
|
/* f040a74: 00000000 */ nop
|
|
/* f040a78: 240100ff */ addiu $at,$zero,0xff
|
|
/* f040a7c: 0041001b */ divu $zero,$v0,$at
|
|
/* f040a80: 00005010 */ mfhi $t2
|
|
/* f040a84: 2d4f00c9 */ sltiu $t7,$t2,0xc9
|
|
/* f040a88: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f040a8c: a3af026e */ sb $t7,0x26e($sp)
|
|
.L0f040a90:
|
|
/* f040a90: 3c014780 */ lui $at,0x4780
|
|
.L0f040a94:
|
|
/* f040a94: 44810000 */ mtc1 $at,$f0
|
|
/* f040a98: c7b001e0 */ lwc1 $f16,0x1e0($sp)
|
|
/* f040a9c: c7a40244 */ lwc1 $f4,0x244($sp)
|
|
/* f040aa0: c7a601e4 */ lwc1 $f6,0x1e4($sp)
|
|
/* f040aa4: 46008482 */ mul.s $f18,$f16,$f0
|
|
/* f040aa8: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f040aac: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040ab0: 46003282 */ mul.s $f10,$f6,$f0
|
|
/* f040ab4: c7a6024c */ lwc1 $f6,0x24c($sp)
|
|
/* f040ab8: 00002825 */ or $a1,$zero,$zero
|
|
/* f040abc: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f040ac0: c7a401e8 */ lwc1 $f4,0x1e8($sp)
|
|
/* f040ac4: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f040ac8: e7a80228 */ swc1 $f8,0x228($sp)
|
|
/* f040acc: 46002202 */ mul.s $f8,$f4,$f0
|
|
/* f040ad0: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f040ad4: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040ad8: 0fc079ef */ jal chrSetPerimEnabled
|
|
/* f040adc: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f040ae0: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040ae4: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040ae8: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f040aec: 13000004 */ beqz $t8,.L0f040b00
|
|
/* f040af0: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f040af4: 240c0001 */ addiu $t4,$zero,0x1
|
|
/* f040af8: 3c01800a */ lui $at,%hi(g_Vars+0x48c)
|
|
/* f040afc: ac2ca44c */ sw $t4,%lo(g_Vars+0x48c)($at)
|
|
.L0f040b00:
|
|
/* f040b00: 24190010 */ addiu $t9,$zero,0x10
|
|
/* f040b04: afb90010 */ sw $t9,0x10($sp)
|
|
/* f040b08: 0c00b764 */ jal cdTestAToB4
|
|
/* f040b0c: 8fa701c8 */ lw $a3,0x1c8($sp)
|
|
/* f040b10: 1440000a */ bnez $v0,.L0f040b3c
|
|
/* f040b14: 240d0001 */ addiu $t5,$zero,0x1
|
|
/* f040b18: 3c067f1b */ lui $a2,%hi(var7f1a8af4)
|
|
/* f040b1c: afad0224 */ sw $t5,0x224($sp)
|
|
/* f040b20: 24c68af4 */ addiu $a2,$a2,%lo(var7f1a8af4)
|
|
/* f040b24: 27a40228 */ addiu $a0,$sp,0x228
|
|
/* f040b28: 0c0093af */ jal cdGetPos
|
|
/* f040b2c: 24052f28 */ addiu $a1,$zero,0x2f28
|
|
/* f040b30: 0c0093ac */ jal cdGetObstacle
|
|
/* f040b34: 00000000 */ nop
|
|
/* f040b38: afa201cc */ sw $v0,0x1cc($sp)
|
|
.L0f040b3c:
|
|
/* f040b3c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040b40: 0fc079ef */ jal chrSetPerimEnabled
|
|
/* f040b44: 24050001 */ addiu $a1,$zero,0x1
|
|
/* f040b48: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f040b4c: 3c01800a */ lui $at,%hi(g_Vars+0x48c)
|
|
/* f040b50: 51c00003 */ beqzl $t6,.L0f040b60
|
|
/* f040b54: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
/* f040b58: ac20a44c */ sw $zero,%lo(g_Vars+0x48c)($at)
|
|
/* f040b5c: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
.L0f040b60:
|
|
/* f040b60: 8faa01c0 */ lw $t2,0x1c0($sp)
|
|
/* f040b64: 55600015 */ bnezl $t3,.L0f040bbc
|
|
/* f040b68: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f040b6c: 51400013 */ beqzl $t2,.L0f040bbc
|
|
/* f040b70: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f040b74: 0c004b70 */ jal random
|
|
/* f040b78: 00000000 */ nop
|
|
/* f040b7c: 24010064 */ addiu $at,$zero,0x64
|
|
/* f040b80: 0041001b */ divu $zero,$v0,$at
|
|
/* f040b84: 00001810 */ mfhi $v1
|
|
/* f040b88: 2c6f0033 */ sltiu $t7,$v1,0x33
|
|
/* f040b8c: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f040b90: 11e00009 */ beqz $t7,.L0f040bb8
|
|
/* f040b94: afaf01bc */ sw $t7,0x1bc($sp)
|
|
/* f040b98: 8fb8025c */ lw $t8,0x25c($sp)
|
|
/* f040b9c: afb801cc */ sw $t8,0x1cc($sp)
|
|
/* f040ba0: c7100008 */ lwc1 $f16,0x8($t8)
|
|
/* f040ba4: e7b00228 */ swc1 $f16,0x228($sp)
|
|
/* f040ba8: c712000c */ lwc1 $f18,0xc($t8)
|
|
/* f040bac: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f040bb0: c7040010 */ lwc1 $f4,0x10($t8)
|
|
/* f040bb4: e7a40230 */ swc1 $f4,0x230($sp)
|
|
.L0f040bb8:
|
|
/* f040bb8: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
.L0f040bbc:
|
|
/* f040bbc: c7a60244 */ lwc1 $f6,0x244($sp)
|
|
/* f040bc0: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f040bc4: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f040bc8: 46064001 */ sub.s $f0,$f8,$f6
|
|
/* f040bcc: c7b20230 */ lwc1 $f18,0x230($sp)
|
|
/* f040bd0: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f040bd4: 46105081 */ sub.s $f2,$f10,$f16
|
|
/* f040bd8: 46000202 */ mul.s $f8,$f0,$f0
|
|
/* f040bdc: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040be0: 46049301 */ sub.s $f12,$f18,$f4
|
|
/* f040be4: 46021182 */ mul.s $f6,$f2,$f2
|
|
/* f040be8: 24010018 */ addiu $at,$zero,0x18
|
|
/* f040bec: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f040bf0: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f040bf4: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f040bf8: 1081000f */ beq $a0,$at,.L0f040c38
|
|
/* f040bfc: e7b201d0 */ swc1 $f18,0x1d0($sp)
|
|
/* f040c00: 24010019 */ addiu $at,$zero,0x19
|
|
/* f040c04: 1081000c */ beq $a0,$at,.L0f040c38
|
|
/* f040c08: 24010012 */ addiu $at,$zero,0x12
|
|
/* f040c0c: 14810003 */ bne $a0,$at,.L0f040c1c
|
|
/* f040c10: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f040c14: 24010001 */ addiu $at,$zero,0x1
|
|
/* f040c18: 11810007 */ beq $t4,$at,.L0f040c38
|
|
.L0f040c1c:
|
|
/* f040c1c: 24010017 */ addiu $at,$zero,0x17
|
|
/* f040c20: 10810005 */ beq $a0,$at,.L0f040c38
|
|
/* f040c24: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f040c28: 10810003 */ beq $a0,$at,.L0f040c38
|
|
/* f040c2c: 24010034 */ addiu $at,$zero,0x34
|
|
/* f040c30: 54810171 */ bnel $a0,$at,.L0f0411f8
|
|
/* f040c34: 24010006 */ addiu $at,$zero,0x6
|
|
.L0f040c38:
|
|
/* f040c38: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f040c3c: afa00250 */ sw $zero,0x250($sp)
|
|
/* f040c40: 3c017f1b */ lui $at,%hi(var7f1a90cc)
|
|
/* f040c44: 17200006 */ bnez $t9,.L0f040c60
|
|
/* f040c48: c7a801d0 */ lwc1 $f8,0x1d0($sp)
|
|
/* f040c4c: c42490cc */ lwc1 $f4,%lo(var7f1a90cc)($at)
|
|
/* f040c50: 4608203c */ c.lt.s $f4,$f8
|
|
/* f040c54: 00000000 */ nop
|
|
/* f040c58: 45020164 */ bc1fl .L0f0411ec
|
|
/* f040c5c: afa00268 */ sw $zero,0x268($sp)
|
|
.L0f040c60:
|
|
/* f040c60: 0fc2c3f4 */ jal weaponFindById
|
|
/* f040c64: 00000000 */ nop
|
|
/* f040c68: 93ad0263 */ lbu $t5,0x263($sp)
|
|
/* f040c6c: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040c70: 24010018 */ addiu $at,$zero,0x18
|
|
/* f040c74: 000d7080 */ sll $t6,$t5,0x2
|
|
/* f040c78: 004e5821 */ addu $t3,$v0,$t6
|
|
/* f040c7c: 10810006 */ beq $a0,$at,.L0f040c98
|
|
/* f040c80: 8d630014 */ lw $v1,0x14($t3)
|
|
/* f040c84: 24010034 */ addiu $at,$zero,0x34
|
|
/* f040c88: 10810003 */ beq $a0,$at,.L0f040c98
|
|
/* f040c8c: 24010019 */ addiu $at,$zero,0x19
|
|
/* f040c90: 5481000e */ bnel $a0,$at,.L0f040ccc
|
|
/* f040c94: 2401001b */ addiu $at,$zero,0x1b
|
|
.L0f040c98:
|
|
/* f040c98: 8c6a0010 */ lw $t2,0x10($v1)
|
|
/* f040c9c: 24050053 */ addiu $a1,$zero,0x53
|
|
/* f040ca0: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040ca4: 000a7840 */ sll $t7,$t2,0x1
|
|
/* f040ca8: 05e30003 */ bgezl $t7,.L0f040cb8
|
|
/* f040cac: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040cb0: 24050054 */ addiu $a1,$zero,0x54
|
|
/* f040cb4: 8c640040 */ lw $a0,0x40($v1)
|
|
.L0f040cb8:
|
|
/* f040cb8: 0fc22e20 */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040cbc: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040cc0: 1000002e */ b .L0f040d7c
|
|
/* f040cc4: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040cc8: 2401001b */ addiu $at,$zero,0x1b
|
|
.L0f040ccc:
|
|
/* f040ccc: 1481000a */ bne $a0,$at,.L0f040cf8
|
|
/* f040cd0: 24050056 */ addiu $a1,$zero,0x56
|
|
/* f040cd4: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040cd8: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040cdc: 0fc22e20 */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040ce0: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040ce4: 10400025 */ beqz $v0,.L0f040d7c
|
|
/* f040ce8: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040cec: 93b80263 */ lbu $t8,0x263($sp)
|
|
/* f040cf0: 10000022 */ b .L0f040d7c
|
|
/* f040cf4: a058005f */ sb $t8,0x5f($v0)
|
|
.L0f040cf8:
|
|
/* f040cf8: 24010017 */ addiu $at,$zero,0x17
|
|
/* f040cfc: 1481000a */ bne $a0,$at,.L0f040d28
|
|
/* f040d00: 24050055 */ addiu $a1,$zero,0x55
|
|
/* f040d04: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040d08: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040d0c: 0fc22e20 */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040d10: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040d14: 10400019 */ beqz $v0,.L0f040d7c
|
|
/* f040d18: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040d1c: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f040d20: 10000016 */ b .L0f040d7c
|
|
/* f040d24: a04c005f */ sb $t4,0x5f($v0)
|
|
.L0f040d28:
|
|
/* f040d28: 24010012 */ addiu $at,$zero,0x12
|
|
/* f040d2c: 1481000b */ bne $a0,$at,.L0f040d5c
|
|
/* f040d30: 3c0d800a */ lui $t5,%hi(g_Vars+0x284)
|
|
/* f040d34: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040d38: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040d3c: 24050055 */ addiu $a1,$zero,0x55
|
|
/* f040d40: 0fc22e20 */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040d44: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040d48: 1040000c */ beqz $v0,.L0f040d7c
|
|
/* f040d4c: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040d50: 24190002 */ addiu $t9,$zero,0x2
|
|
/* f040d54: 10000009 */ b .L0f040d7c
|
|
/* f040d58: a059005f */ sb $t9,0x5f($v0)
|
|
.L0f040d5c:
|
|
/* f040d5c: 8dada244 */ lw $t5,%lo(g_Vars+0x284)($t5)
|
|
/* f040d60: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040d64: 27a50260 */ addiu $a1,$sp,0x260
|
|
/* f040d68: 8dae00bc */ lw $t6,0xbc($t5)
|
|
/* f040d6c: 8dc60004 */ lw $a2,0x4($t6)
|
|
/* f040d70: 0fc22d96 */ jal weaponCreateProjectileFromGset
|
|
/* f040d74: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040d78: afa201b8 */ sw $v0,0x1b8($sp)
|
|
.L0f040d7c:
|
|
/* f040d7c: 1040011b */ beqz $v0,.L0f0411ec
|
|
/* f040d80: 8fab00d4 */ lw $t3,0xd4($sp)
|
|
/* f040d84: 8d6a004c */ lw $t2,0x4c($t3)
|
|
/* f040d88: 3c017f1b */ lui $at,%hi(var7f1a90d0)
|
|
/* f040d8c: c43090d0 */ lwc1 $f16,%lo(var7f1a90d0)($at)
|
|
/* f040d90: 448a3000 */ mtc1 $t2,$f6
|
|
/* f040d94: 3c014270 */ lui $at,0x4270
|
|
/* f040d98: 44812000 */ mtc1 $at,$f4
|
|
/* f040d9c: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f040da0: 3c017f1b */ lui $at,%hi(var7f1a90d4)
|
|
/* f040da4: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040da8: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040dac: 2405001e */ addiu $a1,$zero,0x1e
|
|
/* f040db0: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f040db4: c43090d4 */ lwc1 $f16,%lo(var7f1a90d4)($at)
|
|
/* f040db8: 46049203 */ div.s $f8,$f18,$f4
|
|
/* f040dbc: e7a80168 */ swc1 $f8,0x168($sp)
|
|
/* f040dc0: 8d6f0054 */ lw $t7,0x54($t3)
|
|
/* f040dc4: 448f3000 */ mtc1 $t7,$f6
|
|
/* f040dc8: 00000000 */ nop
|
|
/* f040dcc: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f040dd0: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f040dd4: 13000080 */ beqz $t8,.L0f040fd8
|
|
/* f040dd8: e7b200cc */ swc1 $f18,0xcc($sp)
|
|
/* f040ddc: 0fc1241a */ jal chrIsTargetInFov
|
|
/* f040de0: 00003025 */ or $a2,$zero,$zero
|
|
/* f040de4: 1040007c */ beqz $v0,.L0f040fd8
|
|
/* f040de8: 00000000 */ nop
|
|
/* f040dec: 93a20263 */ lbu $v0,0x263($sp)
|
|
/* f040df0: 00001825 */ or $v1,$zero,$zero
|
|
/* f040df4: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040df8: 14400025 */ bnez $v0,.L0f040e90
|
|
/* f040dfc: 24010018 */ addiu $at,$zero,0x18
|
|
/* f040e00: 10810006 */ beq $a0,$at,.L0f040e1c
|
|
/* f040e04: 8fac025c */ lw $t4,0x25c($sp)
|
|
/* f040e08: 24010034 */ addiu $at,$zero,0x34
|
|
/* f040e0c: 10810003 */ beq $a0,$at,.L0f040e1c
|
|
/* f040e10: 24010019 */ addiu $at,$zero,0x19
|
|
/* f040e14: 5481001f */ bnel $a0,$at,.L0f040e94
|
|
/* f040e18: 93a40260 */ lbu $a0,0x260($sp)
|
|
.L0f040e1c:
|
|
/* f040e1c: 91820000 */ lbu $v0,0x0($t4)
|
|
/* f040e20: 24010003 */ addiu $at,$zero,0x3
|
|
/* f040e24: 8fb9025c */ lw $t9,0x25c($sp)
|
|
/* f040e28: 10410003 */ beq $v0,$at,.L0f040e38
|
|
/* f040e2c: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040e30: 14410051 */ bne $v0,$at,.L0f040f78
|
|
/* f040e34: 00000000 */ nop
|
|
.L0f040e38:
|
|
/* f040e38: c7240008 */ lwc1 $f4,0x8($t9)
|
|
/* f040e3c: c7aa0244 */ lwc1 $f10,0x244($sp)
|
|
/* f040e40: c7b20248 */ lwc1 $f18,0x248($sp)
|
|
/* f040e44: e7a400b8 */ swc1 $f4,0xb8($sp)
|
|
/* f040e48: 8f2d0004 */ lw $t5,0x4($t9)
|
|
/* f040e4c: 460a2401 */ sub.s $f16,$f4,$f10
|
|
/* f040e50: c7aa024c */ lwc1 $f10,0x24c($sp)
|
|
/* f040e54: c5a800b4 */ lwc1 $f8,0xb4($t5)
|
|
/* f040e58: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040e5c: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040e60: e7a800bc */ swc1 $f8,0xbc($sp)
|
|
/* f040e64: c7260010 */ lwc1 $f6,0x10($t9)
|
|
/* f040e68: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f040e6c: 46124101 */ sub.s $f4,$f8,$f18
|
|
/* f040e70: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040e74: e7a600c0 */ swc1 $f6,0xc0($sp)
|
|
/* f040e78: 460a3401 */ sub.s $f16,$f6,$f10
|
|
/* f040e7c: e7a401e4 */ swc1 $f4,0x1e4($sp)
|
|
/* f040e80: 0c0011e4 */ jal guNormalize
|
|
/* f040e84: e7b001e8 */ swc1 $f16,0x1e8($sp)
|
|
/* f040e88: 1000003b */ b .L0f040f78
|
|
/* f040e8c: 24030001 */ addiu $v1,$zero,0x1
|
|
.L0f040e90:
|
|
/* f040e90: 93a40260 */ lbu $a0,0x260($sp)
|
|
.L0f040e94:
|
|
/* f040e94: 24050017 */ addiu $a1,$zero,0x17
|
|
/* f040e98: 24010012 */ addiu $at,$zero,0x12
|
|
/* f040e9c: 14a40003 */ bne $a1,$a0,.L0f040eac
|
|
/* f040ea0: 00000000 */ nop
|
|
/* f040ea4: 50400004 */ beqzl $v0,.L0f040eb8
|
|
/* f040ea8: 8fae025c */ lw $t6,0x25c($sp)
|
|
.L0f040eac:
|
|
/* f040eac: 14810017 */ bne $a0,$at,.L0f040f0c
|
|
/* f040eb0: 00000000 */ nop
|
|
/* f040eb4: 8fae025c */ lw $t6,0x25c($sp)
|
|
.L0f040eb8:
|
|
/* f040eb8: 24010003 */ addiu $at,$zero,0x3
|
|
/* f040ebc: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f040ec0: 91c20000 */ lbu $v0,0x0($t6)
|
|
/* f040ec4: 10410003 */ beq $v0,$at,.L0f040ed4
|
|
/* f040ec8: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040ecc: 1441002a */ bne $v0,$at,.L0f040f78
|
|
/* f040ed0: 00000000 */ nop
|
|
.L0f040ed4:
|
|
/* f040ed4: c5480008 */ lwc1 $f8,0x8($t2)
|
|
/* f040ed8: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040edc: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f040ee0: e7a800b8 */ swc1 $f8,0xb8($sp)
|
|
/* f040ee4: 8d4b0004 */ lw $t3,0x4($t2)
|
|
/* f040ee8: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f040eec: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f040ef0: c57200b4 */ lwc1 $f18,0xb4($t3)
|
|
/* f040ef4: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
/* f040ef8: c5440010 */ lwc1 $f4,0x10($t2)
|
|
/* f040efc: 0fc100c7 */ jal chrCalculateTrajectory
|
|
/* f040f00: e7a400c0 */ swc1 $f4,0xc0($sp)
|
|
/* f040f04: 1000001c */ b .L0f040f78
|
|
/* f040f08: 24030001 */ addiu $v1,$zero,0x1
|
|
.L0f040f0c:
|
|
/* f040f0c: 14a40002 */ bne $a1,$a0,.L0f040f18
|
|
/* f040f10: 24010001 */ addiu $at,$zero,0x1
|
|
/* f040f14: 10410003 */ beq $v0,$at,.L0f040f24
|
|
.L0f040f18:
|
|
/* f040f18: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f040f1c: 14810016 */ bne $a0,$at,.L0f040f78
|
|
/* f040f20: 00000000 */ nop
|
|
.L0f040f24:
|
|
/* f040f24: 8faf025c */ lw $t7,0x25c($sp)
|
|
/* f040f28: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040f2c: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040f30: c5e60008 */ lwc1 $f6,0x8($t7)
|
|
/* f040f34: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f040f38: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f040f3c: e7a600b8 */ swc1 $f6,0xb8($sp)
|
|
/* f040f40: c5ea000c */ lwc1 $f10,0xc($t7)
|
|
/* f040f44: e7aa00bc */ swc1 $f10,0xbc($sp)
|
|
/* f040f48: c5f00010 */ lwc1 $f16,0x10($t7)
|
|
/* f040f4c: e7b000c0 */ swc1 $f16,0xc0($sp)
|
|
/* f040f50: 91f80000 */ lbu $t8,0x0($t7)
|
|
/* f040f54: 17010005 */ bne $t8,$at,.L0f040f6c
|
|
/* f040f58: 3c0141c8 */ lui $at,0x41c8
|
|
/* f040f5c: 44814000 */ mtc1 $at,$f8
|
|
/* f040f60: 00000000 */ nop
|
|
/* f040f64: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f040f68: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
.L0f040f6c:
|
|
/* f040f6c: 0fc100c7 */ jal chrCalculateTrajectory
|
|
/* f040f70: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f040f74: 24030001 */ addiu $v1,$zero,0x1
|
|
.L0f040f78:
|
|
/* f040f78: 10600017 */ beqz $v1,.L0f040fd8
|
|
/* f040f7c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040f80: 0fc122a1 */ jal chrGetAngleToPos
|
|
/* f040f84: 27a500b8 */ addiu $a1,$sp,0xb8
|
|
/* f040f88: e7a000b4 */ swc1 $f0,0xb4($sp)
|
|
/* f040f8c: 0c0068f4 */ jal cosf
|
|
/* f040f90: 46000306 */ mov.s $f12,$f0
|
|
/* f040f94: c7ac00b4 */ lwc1 $f12,0xb4($sp)
|
|
/* f040f98: 0c0068f7 */ jal sinf
|
|
/* f040f9c: e7a000b0 */ swc1 $f0,0xb0($sp)
|
|
/* f040fa0: c7ac01e8 */ lwc1 $f12,0x1e8($sp)
|
|
/* f040fa4: c7ae00b0 */ lwc1 $f14,0xb0($sp)
|
|
/* f040fa8: c7a201e0 */ lwc1 $f2,0x1e0($sp)
|
|
/* f040fac: 460c0102 */ mul.s $f4,$f0,$f12
|
|
/* f040fb0: 00000000 */ nop
|
|
/* f040fb4: 46027182 */ mul.s $f6,$f14,$f2
|
|
/* f040fb8: 00000000 */ nop
|
|
/* f040fbc: 460c7282 */ mul.s $f10,$f14,$f12
|
|
/* f040fc0: 00000000 */ nop
|
|
/* f040fc4: 46020202 */ mul.s $f8,$f0,$f2
|
|
/* f040fc8: 46062400 */ add.s $f16,$f4,$f6
|
|
/* f040fcc: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f040fd0: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f040fd4: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
.L0f040fd8:
|
|
/* f040fd8: 0c00566c */ jal mtx4LoadIdentity
|
|
/* f040fdc: 27a40178 */ addiu $a0,$sp,0x178
|
|
/* f040fe0: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040fe4: 0c0058ba */ jal mtx4LoadXRotation
|
|
/* f040fe8: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f040fec: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040ff0: 0c0058dd */ jal mtx4LoadYRotation
|
|
/* f040ff4: 27a500dc */ addiu $a1,$sp,0xdc
|
|
/* f040ff8: 27a400dc */ addiu $a0,$sp,0xdc
|
|
/* f040ffc: 0c0056f8 */ jal mtx00015be0
|
|
/* f041000: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f041004: c7ac0168 */ lwc1 $f12,0x168($sp)
|
|
/* f041008: c7a401e0 */ lwc1 $f4,0x1e0($sp)
|
|
/* f04100c: c7b001e4 */ lwc1 $f16,0x1e4($sp)
|
|
/* f041010: c7a801e8 */ lwc1 $f8,0x1e8($sp)
|
|
/* f041014: 460c2182 */ mul.s $f6,$f4,$f12
|
|
/* f041018: c7a200cc */ lwc1 $f2,0xcc($sp)
|
|
/* f04101c: 3c01800a */ lui $at,%hi(g_Vars+0x4c)
|
|
/* f041020: 460c8282 */ mul.s $f10,$f16,$f12
|
|
/* f041024: c420a00c */ lwc1 $f0,%lo(g_Vars+0x4c)($at)
|
|
/* f041028: 8fac00d4 */ lw $t4,0xd4($sp)
|
|
/* f04102c: 460c4482 */ mul.s $f18,$f8,$f12
|
|
/* f041030: e7a6015c */ swc1 $f6,0x15c($sp)
|
|
/* f041034: 8fa401b8 */ lw $a0,0x1b8($sp)
|
|
/* f041038: 46022102 */ mul.s $f4,$f4,$f2
|
|
/* f04103c: e7aa0160 */ swc1 $f10,0x160($sp)
|
|
/* f041040: 2401ffff */ addiu $at,$zero,-1
|
|
/* f041044: 46003182 */ mul.s $f6,$f6,$f0
|
|
/* f041048: e7b20164 */ swc1 $f18,0x164($sp)
|
|
/* f04104c: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f041050: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f041054: 27a7011c */ addiu $a3,$sp,0x11c
|
|
/* f041058: 27ae016c */ addiu $t6,$sp,0x16c
|
|
/* f04105c: 27ab0178 */ addiu $t3,$sp,0x178
|
|
/* f041060: 46062100 */ add.s $f4,$f4,$f6
|
|
/* f041064: 46028182 */ mul.s $f6,$f16,$f2
|
|
/* f041068: e7a4016c */ swc1 $f4,0x16c($sp)
|
|
/* f04106c: 46005102 */ mul.s $f4,$f10,$f0
|
|
/* f041070: 46043400 */ add.s $f16,$f6,$f4
|
|
/* f041074: 46024282 */ mul.s $f10,$f8,$f2
|
|
/* f041078: 00000000 */ nop
|
|
/* f04107c: 46009182 */ mul.s $f6,$f18,$f0
|
|
/* f041080: e7b00170 */ swc1 $f16,0x170($sp)
|
|
/* f041084: 46065100 */ add.s $f4,$f10,$f6
|
|
/* f041088: e7a40174 */ swc1 $f4,0x174($sp)
|
|
/* f04108c: 8d8d0058 */ lw $t5,0x58($t4)
|
|
/* f041090: a48d0062 */ sh $t5,0x62($a0)
|
|
/* f041094: 84820062 */ lh $v0,0x62($a0)
|
|
/* f041098: 10410002 */ beq $v0,$at,.L0f0410a4
|
|
/* f04109c: 0002c880 */ sll $t9,$v0,0x2
|
|
/* f0410a0: a4990062 */ sh $t9,0x62($a0)
|
|
.L0f0410a4:
|
|
/* f0410a4: 8faa0274 */ lw $t2,0x274($sp)
|
|
/* f0410a8: afae0010 */ sw $t6,0x10($sp)
|
|
/* f0410ac: afab0014 */ sw $t3,0x14($sp)
|
|
/* f0410b0: afa5001c */ sw $a1,0x1c($sp)
|
|
/* f0410b4: 0fc27af3 */ jal bgun0f09ebcc
|
|
/* f0410b8: afaa0018 */ sw $t2,0x18($sp)
|
|
/* f0410bc: 8fa301b8 */ lw $v1,0x1b8($sp)
|
|
/* f0410c0: 8fac00d4 */ lw $t4,0xd4($sp)
|
|
/* f0410c4: 8c6f0040 */ lw $t7,0x40($v1)
|
|
/* f0410c8: 31f80080 */ andi $t8,$t7,0x80
|
|
/* f0410cc: 13000047 */ beqz $t8,.L0f0411ec
|
|
/* f0410d0: 00000000 */ nop
|
|
/* f0410d4: 8d820010 */ lw $v0,0x10($t4)
|
|
/* f0410d8: 00026800 */ sll $t5,$v0,0x0
|
|
/* f0410dc: 05a10007 */ bgez $t5,.L0f0410fc
|
|
/* f0410e0: 00025900 */ sll $t3,$v0,0x4
|
|
/* f0410e4: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f0410e8: 3c014000 */ lui $at,0x4000
|
|
/* f0410ec: 8c590000 */ lw $t9,0x0($v0)
|
|
/* f0410f0: 03217025 */ or $t6,$t9,$at
|
|
/* f0410f4: 10000007 */ b .L0f041114
|
|
/* f0410f8: ac4e0000 */ sw $t6,0x0($v0)
|
|
.L0f0410fc:
|
|
/* f0410fc: 05630006 */ bgezl $t3,.L0f041118
|
|
/* f041100: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
/* f041104: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f041108: 8c4a0000 */ lw $t2,0x0($v0)
|
|
/* f04110c: 354f0010 */ ori $t7,$t2,0x10
|
|
/* f041110: ac4f0000 */ sw $t7,0x0($v0)
|
|
.L0f041114:
|
|
/* f041114: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
.L0f041118:
|
|
/* f041118: 8c780048 */ lw $t8,0x48($v1)
|
|
/* f04111c: 241900f0 */ addiu $t9,$zero,0xf0
|
|
/* f041120: 3c017f1b */ lui $at,%hi(var7f1a90d8)
|
|
/* f041124: e7100010 */ swc1 $f16,0x10($t8)
|
|
/* f041128: 8c6c0048 */ lw $t4,0x48($v1)
|
|
/* f04112c: c7a80160 */ lwc1 $f8,0x160($sp)
|
|
/* f041130: e5880014 */ swc1 $f8,0x14($t4)
|
|
/* f041134: 8c6d0048 */ lw $t5,0x48($v1)
|
|
/* f041138: c7b20164 */ lwc1 $f18,0x164($sp)
|
|
/* f04113c: e5b20018 */ swc1 $f18,0x18($t5)
|
|
/* f041140: 8c6e0048 */ lw $t6,0x48($v1)
|
|
/* f041144: add900b4 */ sw $t9,0xb4($t6)
|
|
/* f041148: 8fab00d4 */ lw $t3,0xd4($sp)
|
|
/* f04114c: 8c6a0048 */ lw $t2,0x48($v1)
|
|
/* f041150: c56a005c */ lwc1 $f10,0x5c($t3)
|
|
/* f041154: e54a008c */ swc1 $f10,0x8c($t2)
|
|
/* f041158: 8faf00d4 */ lw $t7,0xd4($sp)
|
|
/* f04115c: c42490d8 */ lwc1 $f4,%lo(var7f1a90d8)($at)
|
|
/* f041160: 8c780048 */ lw $t8,0x48($v1)
|
|
/* f041164: c5e60050 */ lwc1 $f6,0x50($t7)
|
|
/* f041168: 46043402 */ mul.s $f16,$f6,$f4
|
|
/* f04116c: e7100098 */ swc1 $f16,0x98($t8)
|
|
/* f041170: 0fc0a221 */ jal chrGetTargetProp
|
|
/* f041174: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041178: 8fac01b8 */ lw $t4,0x1b8($sp)
|
|
/* f04117c: 3c01bf80 */ lui $at,0xbf80
|
|
/* f041180: 00002025 */ or $a0,$zero,$zero
|
|
/* f041184: 8d8d0048 */ lw $t5,0x48($t4)
|
|
/* f041188: 2407ffff */ addiu $a3,$zero,-1
|
|
/* f04118c: 240effff */ addiu $t6,$zero,-1
|
|
/* f041190: ada200e8 */ sw $v0,0xe8($t5)
|
|
/* f041194: 8fb900d4 */ lw $t9,0xd4($sp)
|
|
/* f041198: 240bffff */ addiu $t3,$zero,-1
|
|
/* f04119c: 87260060 */ lh $a2,0x60($t9)
|
|
/* f0411a0: 18c00012 */ blez $a2,.L0f0411ec
|
|
/* f0411a4: 00000000 */ nop
|
|
/* f0411a8: 8d850014 */ lw $a1,0x14($t4)
|
|
/* f0411ac: 44810000 */ mtc1 $at,$f0
|
|
/* f0411b0: afab002c */ sw $t3,0x2c($sp)
|
|
/* f0411b4: afa00028 */ sw $zero,0x28($sp)
|
|
/* f0411b8: afa00020 */ sw $zero,0x20($sp)
|
|
/* f0411bc: afa0001c */ sw $zero,0x1c($sp)
|
|
/* f0411c0: afa00018 */ sw $zero,0x18($sp)
|
|
/* f0411c4: afa00014 */ sw $zero,0x14($sp)
|
|
/* f0411c8: afae0010 */ sw $t6,0x10($sp)
|
|
/* f0411cc: e7a00024 */ swc1 $f0,0x24($sp)
|
|
/* f0411d0: e7a00030 */ swc1 $f0,0x30($sp)
|
|
/* f0411d4: e7a00034 */ swc1 $f0,0x34($sp)
|
|
/* f0411d8: 0fc24e7e */ jal propsnd0f0939f8
|
|
/* f0411dc: e7a00038 */ swc1 $f0,0x38($sp)
|
|
/* f0411e0: 10000002 */ b .L0f0411ec
|
|
/* f0411e4: 00000000 */ nop
|
|
/* f0411e8: afa00268 */ sw $zero,0x268($sp)
|
|
.L0f0411ec:
|
|
/* f0411ec: 10000019 */ b .L0f041254
|
|
/* f0411f0: a3a0026e */ sb $zero,0x26e($sp)
|
|
/* f0411f4: 24010006 */ addiu $at,$zero,0x6
|
|
.L0f0411f8:
|
|
/* f0411f8: 14810016 */ bne $a0,$at,.L0f041254
|
|
/* f0411fc: 93aa026f */ lbu $t2,0x26f($sp)
|
|
/* f041200: 11400014 */ beqz $t2,.L0f041254
|
|
/* f041204: 93af0263 */ lbu $t7,0x263($sp)
|
|
/* f041208: 24010001 */ addiu $at,$zero,0x1
|
|
/* f04120c: 15e10011 */ bne $t7,$at,.L0f041254
|
|
/* f041210: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f041214: 8fa2027c */ lw $v0,0x27c($sp)
|
|
/* f041218: 8db902d4 */ lw $t9,0x2d4($t5)
|
|
/* f04121c: 3c014120 */ lui $at,0x4120
|
|
/* f041220: 0002c080 */ sll $t8,$v0,0x2
|
|
/* f041224: 03386021 */ addu $t4,$t9,$t8
|
|
/* f041228: c58800e4 */ lwc1 $f8,0xe4($t4)
|
|
/* f04122c: 44819000 */ mtc1 $at,$f18
|
|
/* f041230: 44802000 */ mtc1 $zero,$f4
|
|
/* f041234: 46124282 */ mul.s $f10,$f8,$f18
|
|
/* f041238: 4600518d */ trunc.w.s $f6,$f10
|
|
/* f04123c: 440b3000 */ mfc1 $t3,$f6
|
|
/* f041240: 00000000 */ nop
|
|
/* f041244: a3ab0262 */ sb $t3,0x262($sp)
|
|
/* f041248: 8daa02d4 */ lw $t2,0x2d4($t5)
|
|
/* f04124c: 01587821 */ addu $t7,$t2,$t8
|
|
/* f041250: e5e400e4 */ swc1 $f4,0xe4($t7)
|
|
.L0f041254:
|
|
/* f041254: 93b8026e */ lbu $t8,0x26e($sp)
|
|
/* f041258: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f04125c: 530001c0 */ beqzl $t8,.L0f041960
|
|
/* f041260: 8fae01c0 */ lw $t6,0x1c0($sp)
|
|
/* f041264: 172000d6 */ bnez $t9,.L0f0415c0
|
|
/* f041268: 8fac0258 */ lw $t4,0x258($sp)
|
|
/* f04126c: 318e0200 */ andi $t6,$t4,0x200
|
|
/* f041270: 11c0004c */ beqz $t6,.L0f0413a4
|
|
/* f041274: 8fab025c */ lw $t3,0x25c($sp)
|
|
/* f041278: 916d0000 */ lbu $t5,0x0($t3)
|
|
/* f04127c: 24010006 */ addiu $at,$zero,0x6
|
|
/* f041280: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041284: 15a10047 */ bne $t5,$at,.L0f0413a4
|
|
/* f041288: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f04128c: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f041290: 0fc0e47b */ jal chrCanSeeAttackTarget
|
|
/* f041294: 00003825 */ or $a3,$zero,$zero
|
|
/* f041298: 10400042 */ beqz $v0,.L0f0413a4
|
|
/* f04129c: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f0412a0: 8d440004 */ lw $a0,0x4($t2)
|
|
/* f0412a4: 8fa50278 */ lw $a1,0x278($sp)
|
|
/* f0412a8: 0fc12aa3 */ jal chrCompareTeams
|
|
/* f0412ac: 24060002 */ addiu $a2,$zero,0x2
|
|
/* f0412b0: 1040003c */ beqz $v0,.L0f0413a4
|
|
/* f0412b4: 3c014170 */ lui $at,0x4170
|
|
/* f0412b8: 44817000 */ mtc1 $at,$f14
|
|
/* f0412bc: 8faf025c */ lw $t7,0x25c($sp)
|
|
/* f0412c0: c7aa01e0 */ lwc1 $f10,0x1e0($sp)
|
|
/* f0412c4: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f0412c8: c5f00008 */ lwc1 $f16,0x8($t7)
|
|
/* f0412cc: 460e5182 */ mul.s $f6,$f10,$f14
|
|
/* f0412d0: c7aa01e4 */ lwc1 $f10,0x1e4($sp)
|
|
/* f0412d4: 46088481 */ sub.s $f18,$f16,$f8
|
|
/* f0412d8: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f0412dc: c5e4000c */ lwc1 $f4,0xc($t7)
|
|
/* f0412e0: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0412e4: 27a501f8 */ addiu $a1,$sp,0x1f8
|
|
/* f0412e8: 46069001 */ sub.s $f0,$f18,$f6
|
|
/* f0412ec: 460e5482 */ mul.s $f18,$f10,$f14
|
|
/* f0412f0: c7aa01e8 */ lwc1 $f10,0x1e8($sp)
|
|
/* f0412f4: 46102201 */ sub.s $f8,$f4,$f16
|
|
/* f0412f8: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f0412fc: c5e60010 */ lwc1 $f6,0x10($t7)
|
|
/* f041300: 27a601f4 */ addiu $a2,$sp,0x1f4
|
|
/* f041304: 46124081 */ sub.s $f2,$f8,$f18
|
|
/* f041308: 460e5202 */ mul.s $f8,$f10,$f14
|
|
/* f04130c: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f041310: 46043401 */ sub.s $f16,$f6,$f4
|
|
/* f041314: 46000182 */ mul.s $f6,$f0,$f0
|
|
/* f041318: 00000000 */ nop
|
|
/* f04131c: 46021102 */ mul.s $f4,$f2,$f2
|
|
/* f041320: 46088301 */ sub.s $f12,$f16,$f8
|
|
/* f041324: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f041328: 46043280 */ add.s $f10,$f6,$f4
|
|
/* f04132c: 46105200 */ add.s $f8,$f10,$f16
|
|
/* f041330: 4612403e */ c.le.s $f8,$f18
|
|
/* f041334: 00000000 */ nop
|
|
/* f041338: 4500002b */ bc1f .L0f0413e8
|
|
/* f04133c: 00000000 */ nop
|
|
/* f041340: 0fc0feac */ jal chrCalculateHit
|
|
/* f041344: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f041348: 8fb801f4 */ lw $t8,0x1f4($sp)
|
|
/* f04134c: 8fac01f8 */ lw $t4,0x1f8($sp)
|
|
/* f041350: 8fae0278 */ lw $t6,0x278($sp)
|
|
/* f041354: 2f190001 */ sltiu $t9,$t8,0x1
|
|
/* f041358: 11800023 */ beqz $t4,.L0f0413e8
|
|
/* f04135c: afb901f0 */ sw $t9,0x1f0($sp)
|
|
/* f041360: 81c30007 */ lb $v1,0x7($t6)
|
|
/* f041364: 24010008 */ addiu $at,$zero,0x8
|
|
/* f041368: 3c0b800a */ lui $t3,%hi(g_Vars+0x8)
|
|
/* f04136c: 1061000a */ beq $v1,$at,.L0f041398
|
|
/* f041370: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f041374: 2401000a */ addiu $at,$zero,0xa
|
|
/* f041378: 10610007 */ beq $v1,$at,.L0f041398
|
|
/* f04137c: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f041380: 10610005 */ beq $v1,$at,.L0f041398
|
|
/* f041384: 2401001c */ addiu $at,$zero,0x1c
|
|
/* f041388: 10610003 */ beq $v1,$at,.L0f041398
|
|
/* f04138c: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f041390: 54610016 */ bnel $v1,$at,.L0f0413ec
|
|
/* f041394: 8fb901f4 */ lw $t9,0x1f4($sp)
|
|
.L0f041398:
|
|
/* f041398: 8d6b9fc8 */ lw $t3,%lo(g_Vars+0x8)($t3)
|
|
/* f04139c: 10000012 */ b .L0f0413e8
|
|
/* f0413a0: adab0048 */ sw $t3,0x48($t5)
|
|
.L0f0413a4:
|
|
/* f0413a4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f0413a8: 24010008 */ addiu $at,$zero,0x8
|
|
/* f0413ac: 3c0f800a */ lui $t7,%hi(g_Vars+0x8)
|
|
/* f0413b0: 81430007 */ lb $v1,0x7($t2)
|
|
/* f0413b4: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f0413b8: 10610009 */ beq $v1,$at,.L0f0413e0
|
|
/* f0413bc: 2401000a */ addiu $at,$zero,0xa
|
|
/* f0413c0: 10610007 */ beq $v1,$at,.L0f0413e0
|
|
/* f0413c4: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f0413c8: 10610005 */ beq $v1,$at,.L0f0413e0
|
|
/* f0413cc: 2401001c */ addiu $at,$zero,0x1c
|
|
/* f0413d0: 10610003 */ beq $v1,$at,.L0f0413e0
|
|
/* f0413d4: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f0413d8: 54610004 */ bnel $v1,$at,.L0f0413ec
|
|
/* f0413dc: 8fb901f4 */ lw $t9,0x1f4($sp)
|
|
.L0f0413e0:
|
|
/* f0413e0: 8def9fc8 */ lw $t7,%lo(g_Vars+0x8)($t7)
|
|
/* f0413e4: af0f0048 */ sw $t7,0x48($t8)
|
|
.L0f0413e8:
|
|
/* f0413e8: 8fb901f4 */ lw $t9,0x1f4($sp)
|
|
.L0f0413ec:
|
|
/* f0413ec: 8faa01cc */ lw $t2,0x1cc($sp)
|
|
/* f0413f0: 13200065 */ beqz $t9,.L0f041588
|
|
/* f0413f4: 00000000 */ nop
|
|
/* f0413f8: 0fc2c74a */ jal gsetGetDamage
|
|
/* f0413fc: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041400: 8fab025c */ lw $t3,0x25c($sp)
|
|
/* f041404: 240cffff */ addiu $t4,$zero,-1
|
|
/* f041408: 240e00c8 */ addiu $t6,$zero,0xc8
|
|
/* f04140c: e7a0009c */ swc1 $f0,0x9c($sp)
|
|
/* f041410: afa00098 */ sw $zero,0x98($sp)
|
|
/* f041414: afa00094 */ sw $zero,0x94($sp)
|
|
/* f041418: afac0090 */ sw $t4,0x90($sp)
|
|
/* f04141c: afae008c */ sw $t6,0x8c($sp)
|
|
/* f041420: 8d6d0004 */ lw $t5,0x4($t3)
|
|
/* f041424: afad0088 */ sw $t5,0x88($sp)
|
|
/* f041428: c5660008 */ lwc1 $f6,0x8($t3)
|
|
/* f04142c: e7a60228 */ swc1 $f6,0x228($sp)
|
|
/* f041430: c564000c */ lwc1 $f4,0xc($t3)
|
|
/* f041434: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
/* f041438: c56a0010 */ lwc1 $f10,0x10($t3)
|
|
/* f04143c: 0c004b70 */ jal random
|
|
/* f041440: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f041444: 304a0001 */ andi $t2,$v0,0x1
|
|
/* f041448: 11400012 */ beqz $t2,.L0f041494
|
|
/* f04144c: 00000000 */ nop
|
|
/* f041450: 0c004b70 */ jal random
|
|
/* f041454: 00000000 */ nop
|
|
/* f041458: 2401000a */ addiu $at,$zero,0xa
|
|
/* f04145c: 0041001b */ divu $zero,$v0,$at
|
|
/* f041460: 00007810 */ mfhi $t7
|
|
/* f041464: 25f80002 */ addiu $t8,$t7,0x2
|
|
/* f041468: 44989000 */ mtc1 $t8,$f18
|
|
/* f04146c: c7b0022c */ lwc1 $f16,0x22c($sp)
|
|
/* f041470: 07010005 */ bgez $t8,.L0f041488
|
|
/* f041474: 46809220 */ cvt.s.w $f8,$f18
|
|
/* f041478: 3c014f80 */ lui $at,0x4f80
|
|
/* f04147c: 44813000 */ mtc1 $at,$f6
|
|
/* f041480: 00000000 */ nop
|
|
/* f041484: 46064200 */ add.s $f8,$f8,$f6
|
|
.L0f041488:
|
|
/* f041488: 46088100 */ add.s $f4,$f16,$f8
|
|
/* f04148c: 10000011 */ b .L0f0414d4
|
|
/* f041490: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
.L0f041494:
|
|
/* f041494: 0c004b70 */ jal random
|
|
/* f041498: 00000000 */ nop
|
|
/* f04149c: 2401000a */ addiu $at,$zero,0xa
|
|
/* f0414a0: 0041001b */ divu $zero,$v0,$at
|
|
/* f0414a4: 0000c810 */ mfhi $t9
|
|
/* f0414a8: 272c0002 */ addiu $t4,$t9,0x2
|
|
/* f0414ac: 448c9000 */ mtc1 $t4,$f18
|
|
/* f0414b0: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f0414b4: 05810005 */ bgez $t4,.L0f0414cc
|
|
/* f0414b8: 468091a0 */ cvt.s.w $f6,$f18
|
|
/* f0414bc: 3c014f80 */ lui $at,0x4f80
|
|
/* f0414c0: 44818000 */ mtc1 $at,$f16
|
|
/* f0414c4: 00000000 */ nop
|
|
/* f0414c8: 46103180 */ add.s $f6,$f6,$f16
|
|
.L0f0414cc:
|
|
/* f0414cc: 46065201 */ sub.s $f8,$f10,$f6
|
|
/* f0414d0: e7a8022c */ swc1 $f8,0x22c($sp)
|
|
.L0f0414d4:
|
|
/* f0414d4: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f0414d8: 8fa5025c */ lw $a1,0x25c($sp)
|
|
/* f0414dc: 0fc29f66 */ jal bgunPlayPropHitSound
|
|
/* f0414e0: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f0414e4: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f0414e8: 8c8e0020 */ lw $t6,0x20($a0)
|
|
/* f0414ec: 51c00012 */ beqzl $t6,.L0f041538
|
|
/* f0414f0: 8faf0278 */ lw $t7,0x278($sp)
|
|
/* f0414f4: 0fc0cfe8 */ jal chrGetShield
|
|
/* f0414f8: 00000000 */ nop
|
|
/* f0414fc: 44802000 */ mtc1 $zero,$f4
|
|
/* f041500: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f041504: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041508: 4600203c */ c.lt.s $f4,$f0
|
|
/* f04150c: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041510: 27a70098 */ addiu $a3,$sp,0x98
|
|
/* f041514: 27ad008c */ addiu $t5,$sp,0x8c
|
|
/* f041518: 45000006 */ bc1f .L0f041534
|
|
/* f04151c: 27ab0094 */ addiu $t3,$sp,0x94
|
|
/* f041520: 27aa0090 */ addiu $t2,$sp,0x90
|
|
/* f041524: afaa0018 */ sw $t2,0x18($sp)
|
|
/* f041528: afad0010 */ sw $t5,0x10($sp)
|
|
/* f04152c: 0fc0ffcb */ jal chrCalculateShieldHit
|
|
/* f041530: afab0014 */ sw $t3,0x14($sp)
|
|
.L0f041534:
|
|
/* f041534: 8faf0278 */ lw $t7,0x278($sp)
|
|
.L0f041538:
|
|
/* f041538: 8fac025c */ lw $t4,0x25c($sp)
|
|
/* f04153c: 8fae0098 */ lw $t6,0x98($sp)
|
|
/* f041540: 8df8001c */ lw $t8,0x1c($t7)
|
|
/* f041544: 8fad0094 */ lw $t5,0x94($sp)
|
|
/* f041548: 8fab0090 */ lw $t3,0x90($sp)
|
|
/* f04154c: 241900c8 */ addiu $t9,$zero,0xc8
|
|
/* f041550: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f041554: afb90014 */ sw $t9,0x14($sp)
|
|
/* f041558: afa00028 */ sw $zero,0x28($sp)
|
|
/* f04155c: 8fa5009c */ lw $a1,0x9c($sp)
|
|
/* f041560: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041564: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f041568: afac0018 */ sw $t4,0x18($sp)
|
|
/* f04156c: afae001c */ sw $t6,0x1c($sp)
|
|
/* f041570: afb80010 */ sw $t8,0x10($sp)
|
|
/* f041574: afad0020 */ sw $t5,0x20($sp)
|
|
/* f041578: 0fc0d077 */ jal func0f0341dc
|
|
/* f04157c: afab0024 */ sw $t3,0x24($sp)
|
|
/* f041580: 10000010 */ b .L0f0415c4
|
|
/* f041584: 8faf01f0 */ lw $t7,0x1f0($sp)
|
|
.L0f041588:
|
|
/* f041588: 11400006 */ beqz $t2,.L0f0415a4
|
|
/* f04158c: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f041590: 91420000 */ lbu $v0,0x0($t2)
|
|
/* f041594: 24010003 */ addiu $at,$zero,0x3
|
|
/* f041598: 10410009 */ beq $v0,$at,.L0f0415c0
|
|
/* f04159c: 24010006 */ addiu $at,$zero,0x6
|
|
/* f0415a0: 10410007 */ beq $v0,$at,.L0f0415c0
|
|
.L0f0415a4:
|
|
/* f0415a4: 3c017f1b */ lui $at,%hi(var7f1a90dc)
|
|
/* f0415a8: c43090dc */ lwc1 $f16,%lo(var7f1a90dc)($at)
|
|
/* f0415ac: 4610903c */ c.lt.s $f18,$f16
|
|
/* f0415b0: 00000000 */ nop
|
|
/* f0415b4: 45020003 */ bc1fl .L0f0415c4
|
|
/* f0415b8: 8faf01f0 */ lw $t7,0x1f0($sp)
|
|
/* f0415bc: afa001f0 */ sw $zero,0x1f0($sp)
|
|
.L0f0415c0:
|
|
/* f0415c0: 8faf01f0 */ lw $t7,0x1f0($sp)
|
|
.L0f0415c4:
|
|
/* f0415c4: 8fb801cc */ lw $t8,0x1cc($sp)
|
|
/* f0415c8: 51e000e5 */ beqzl $t7,.L0f041960
|
|
/* f0415cc: 8fae01c0 */ lw $t6,0x1c0($sp)
|
|
/* f0415d0: 130000a2 */ beqz $t8,.L0f04185c
|
|
/* f0415d4: 8fae0224 */ lw $t6,0x224($sp)
|
|
/* f0415d8: 93020000 */ lbu $v0,0x0($t8)
|
|
/* f0415dc: 24010006 */ addiu $at,$zero,0x6
|
|
/* f0415e0: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f0415e4: 10410003 */ beq $v0,$at,.L0f0415f4
|
|
/* f0415e8: 24010003 */ addiu $at,$zero,0x3
|
|
/* f0415ec: 54410053 */ bnel $v0,$at,.L0f04173c
|
|
/* f0415f0: 24010001 */ addiu $at,$zero,0x1
|
|
.L0f0415f4:
|
|
/* f0415f4: 1720000c */ bnez $t9,.L0f041628
|
|
/* f0415f8: 8fac01bc */ lw $t4,0x1bc($sp)
|
|
/* f0415fc: 1580000a */ bnez $t4,.L0f041628
|
|
/* f041600: 8fae0278 */ lw $t6,0x278($sp)
|
|
/* f041604: 8dcd0018 */ lw $t5,0x18($t6)
|
|
/* f041608: 8faa01cc */ lw $t2,0x1cc($sp)
|
|
/* f04160c: 01c02825 */ or $a1,$t6,$zero
|
|
/* f041610: 31ab0040 */ andi $t3,$t5,0x40
|
|
/* f041614: 11600045 */ beqz $t3,.L0f04172c
|
|
/* f041618: 24060002 */ addiu $a2,$zero,0x2
|
|
/* f04161c: 0fc12aa3 */ jal chrCompareTeams
|
|
/* f041620: 8d440004 */ lw $a0,0x4($t2)
|
|
/* f041624: 10400041 */ beqz $v0,.L0f04172c
|
|
.L0f041628:
|
|
/* f041628: 240fffff */ addiu $t7,$zero,-1
|
|
/* f04162c: 241800c8 */ addiu $t8,$zero,0xc8
|
|
/* f041630: afa00084 */ sw $zero,0x84($sp)
|
|
/* f041634: afa00080 */ sw $zero,0x80($sp)
|
|
/* f041638: afaf007c */ sw $t7,0x7c($sp)
|
|
/* f04163c: afb80078 */ sw $t8,0x78($sp)
|
|
/* f041640: 0fc2c74a */ jal gsetGetDamage
|
|
/* f041644: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041648: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f04164c: e7a00074 */ swc1 $f0,0x74($sp)
|
|
/* f041650: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041654: 8cac0004 */ lw $t4,0x4($a1)
|
|
/* f041658: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f04165c: 0fc29f66 */ jal bgunPlayPropHitSound
|
|
/* f041660: afac0070 */ sw $t4,0x70($sp)
|
|
/* f041664: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041668: 8c8d0020 */ lw $t5,0x20($a0)
|
|
/* f04166c: 51a00012 */ beqzl $t5,.L0f0416b8
|
|
/* f041670: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f041674: 0fc0cfe8 */ jal chrGetShield
|
|
/* f041678: 00000000 */ nop
|
|
/* f04167c: 44805000 */ mtc1 $zero,$f10
|
|
/* f041680: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041684: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041688: 4600503c */ c.lt.s $f10,$f0
|
|
/* f04168c: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041690: 27a70084 */ addiu $a3,$sp,0x84
|
|
/* f041694: 27ab0078 */ addiu $t3,$sp,0x78
|
|
/* f041698: 45000006 */ bc1f .L0f0416b4
|
|
/* f04169c: 27aa0080 */ addiu $t2,$sp,0x80
|
|
/* f0416a0: 27ae007c */ addiu $t6,$sp,0x7c
|
|
/* f0416a4: afae0018 */ sw $t6,0x18($sp)
|
|
/* f0416a8: afab0010 */ sw $t3,0x10($sp)
|
|
/* f0416ac: 0fc0ffcb */ jal chrCalculateShieldHit
|
|
/* f0416b0: afaa0014 */ sw $t2,0x14($sp)
|
|
.L0f0416b4:
|
|
/* f0416b4: 8fb80278 */ lw $t8,0x278($sp)
|
|
.L0f0416b8:
|
|
/* f0416b8: 27af01e0 */ addiu $t7,$sp,0x1e0
|
|
/* f0416bc: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f0416c0: afaf0010 */ sw $t7,0x10($sp)
|
|
/* f0416c4: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0416c8: 8fa60078 */ lw $a2,0x78($sp)
|
|
/* f0416cc: 27a70228 */ addiu $a3,$sp,0x228
|
|
/* f0416d0: 0fc097a9 */ jal chrEmitSparks
|
|
/* f0416d4: afb80014 */ sw $t8,0x14($sp)
|
|
/* f0416d8: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f0416dc: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
/* f0416e0: 8faa0084 */ lw $t2,0x84($sp)
|
|
/* f0416e4: 8d99001c */ lw $t9,0x1c($t4)
|
|
/* f0416e8: 8fae0080 */ lw $t6,0x80($sp)
|
|
/* f0416ec: 8faf007c */ lw $t7,0x7c($sp)
|
|
/* f0416f0: 240d00c8 */ addiu $t5,$zero,0xc8
|
|
/* f0416f4: afad0014 */ sw $t5,0x14($sp)
|
|
/* f0416f8: afa00028 */ sw $zero,0x28($sp)
|
|
/* f0416fc: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f041700: 8fa50074 */ lw $a1,0x74($sp)
|
|
/* f041704: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f041708: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f04170c: afab0018 */ sw $t3,0x18($sp)
|
|
/* f041710: afaa001c */ sw $t2,0x1c($sp)
|
|
/* f041714: afb90010 */ sw $t9,0x10($sp)
|
|
/* f041718: afae0020 */ sw $t6,0x20($sp)
|
|
/* f04171c: 0fc0d077 */ jal func0f0341dc
|
|
/* f041720: afaf0024 */ sw $t7,0x24($sp)
|
|
/* f041724: 1000006f */ b .L0f0418e4
|
|
/* f041728: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f04172c:
|
|
/* f04172c: afa00250 */ sw $zero,0x250($sp)
|
|
/* f041730: 1000006b */ b .L0f0418e0
|
|
/* f041734: afa00268 */ sw $zero,0x268($sp)
|
|
/* f041738: 24010001 */ addiu $at,$zero,0x1
|
|
.L0f04173c:
|
|
/* f04173c: 10410005 */ beq $v0,$at,.L0f041754
|
|
/* f041740: 8fb801cc */ lw $t8,0x1cc($sp)
|
|
/* f041744: 24010004 */ addiu $at,$zero,0x4
|
|
/* f041748: 10410002 */ beq $v0,$at,.L0f041754
|
|
/* f04174c: 24010002 */ addiu $at,$zero,0x2
|
|
/* f041750: 14410063 */ bne $v0,$at,.L0f0418e0
|
|
.L0f041754:
|
|
/* f041754: 3c0d800a */ lui $t5,%hi(g_Vars+0x314)
|
|
/* f041758: 8dada2d4 */ lw $t5,%lo(g_Vars+0x314)($t5)
|
|
/* f04175c: 8f0c0004 */ lw $t4,0x4($t8)
|
|
/* f041760: 2419ffff */ addiu $t9,$zero,-1
|
|
/* f041764: afb90068 */ sw $t9,0x68($sp)
|
|
/* f041768: 11a00004 */ beqz $t5,.L0f04177c
|
|
/* f04176c: afac006c */ sw $t4,0x6c($sp)
|
|
/* f041770: 0fc633fe */ jal mpPlayerGetIndex
|
|
/* f041774: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041778: afa20068 */ sw $v0,0x68($sp)
|
|
.L0f04177c:
|
|
/* f04177c: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041780: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f041784: 0fc29f66 */ jal bgunPlayPropHitSound
|
|
/* f041788: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f04178c: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041790: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041794: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041798: 0fc1979d */ jal func0f065e74
|
|
/* f04179c: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f0417a0: 240b0001 */ addiu $t3,$zero,0x1
|
|
/* f0417a4: afab0210 */ sw $t3,0x210($sp)
|
|
/* f0417a8: 0fc4f92a */ jal chrIsUsingPaintball
|
|
/* f0417ac: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0417b0: 1040000b */ beqz $v0,.L0f0417e0
|
|
/* f0417b4: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0417b8: 240a0019 */ addiu $t2,$zero,0x19
|
|
/* f0417bc: afaa0014 */ sw $t2,0x14($sp)
|
|
/* f0417c0: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0417c4: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0417c8: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0417cc: 00003825 */ or $a3,$zero,$zero
|
|
/* f0417d0: 0fc4be7c */ jal sparksCreate
|
|
/* f0417d4: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0417d8: 10000007 */ b .L0f0417f8
|
|
/* f0417dc: 00000000 */ nop
|
|
.L0f0417e0:
|
|
/* f0417e0: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f0417e4: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0417e8: 00003825 */ or $a3,$zero,$zero
|
|
/* f0417ec: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0417f0: 0fc4be7c */ jal sparksCreate
|
|
/* f0417f4: afa00014 */ sw $zero,0x14($sp)
|
|
.L0f0417f8:
|
|
/* f0417f8: 3c0e800a */ lui $t6,%hi(g_MissionConfig+0x3)
|
|
/* f0417fc: 81cfdfeb */ lb $t7,%lo(g_MissionConfig+0x3)($t6)
|
|
/* f041800: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f041804: 05e1000a */ bgez $t7,.L0f041830
|
|
/* f041808: 00000000 */ nop
|
|
/* f04180c: 930c0125 */ lbu $t4,0x125($t8)
|
|
/* f041810: 24010010 */ addiu $at,$zero,0x10
|
|
/* f041814: 8fb9006c */ lw $t9,0x6c($sp)
|
|
/* f041818: 15810005 */ bne $t4,$at,.L0f041830
|
|
/* f04181c: 00000000 */ nop
|
|
/* f041820: 8f2d000c */ lw $t5,0xc($t9)
|
|
/* f041824: 31ab0001 */ andi $t3,$t5,0x1
|
|
/* f041828: 5560002e */ bnezl $t3,.L0f0418e4
|
|
/* f04182c: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f041830:
|
|
/* f041830: 0fc2c74a */ jal gsetGetDamage
|
|
/* f041834: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041838: 8faa0068 */ lw $t2,0x68($sp)
|
|
/* f04183c: 44050000 */ mfc1 $a1,$f0
|
|
/* f041840: 8fa4006c */ lw $a0,0x6c($sp)
|
|
/* f041844: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041848: 93a70260 */ lbu $a3,0x260($sp)
|
|
/* f04184c: 0fc2149c */ jal objTakeGunfire
|
|
/* f041850: afaa0010 */ sw $t2,0x10($sp)
|
|
/* f041854: 10000023 */ b .L0f0418e4
|
|
/* f041858: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f04185c:
|
|
/* f04185c: 11c00020 */ beqz $t6,.L0f0418e0
|
|
/* f041860: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041864: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041868: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f04186c: 0fc1979d */ jal func0f065e74
|
|
/* f041870: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041874: 240f0001 */ addiu $t7,$zero,0x1
|
|
/* f041878: afaf0210 */ sw $t7,0x210($sp)
|
|
/* f04187c: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041880: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041884: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f041888: 0fc2a132 */ jal bgunPlayBgHitSound
|
|
/* f04188c: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041890: 0fc4f92a */ jal chrIsUsingPaintball
|
|
/* f041894: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041898: 1040000b */ beqz $v0,.L0f0418c8
|
|
/* f04189c: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0418a0: 24180019 */ addiu $t8,$zero,0x19
|
|
/* f0418a4: afb80014 */ sw $t8,0x14($sp)
|
|
/* f0418a8: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f0418ac: 00002825 */ or $a1,$zero,$zero
|
|
/* f0418b0: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0418b4: 00003825 */ or $a3,$zero,$zero
|
|
/* f0418b8: 0fc4be7c */ jal sparksCreate
|
|
/* f0418bc: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0418c0: 10000008 */ b .L0f0418e4
|
|
/* f0418c4: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f0418c8:
|
|
/* f0418c8: 00002825 */ or $a1,$zero,$zero
|
|
/* f0418cc: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0418d0: 00003825 */ or $a3,$zero,$zero
|
|
/* f0418d4: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0418d8: 0fc4be7c */ jal sparksCreate
|
|
/* f0418dc: afa00014 */ sw $zero,0x14($sp)
|
|
.L0f0418e0:
|
|
/* f0418e0: 93ac0260 */ lbu $t4,0x260($sp)
|
|
.L0f0418e4:
|
|
/* f0418e4: 24010007 */ addiu $at,$zero,0x7
|
|
/* f0418e8: 93b90263 */ lbu $t9,0x263($sp)
|
|
/* f0418ec: 1581001b */ bne $t4,$at,.L0f04195c
|
|
/* f0418f0: 24010001 */ addiu $at,$zero,0x1
|
|
/* f0418f4: 17210019 */ bne $t9,$at,.L0f04195c
|
|
/* f0418f8: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f0418fc: 8dab02d4 */ lw $t3,0x2d4($t5)
|
|
/* f041900: 3c03800a */ lui $v1,%hi(g_Vars+0x28c)
|
|
/* f041904: 11600005 */ beqz $t3,.L0f04191c
|
|
/* f041908: 00000000 */ nop
|
|
/* f04190c: 0fc633fe */ jal mpPlayerGetIndex
|
|
/* f041910: 01a02025 */ or $a0,$t5,$zero
|
|
/* f041914: 10000002 */ b .L0f041920
|
|
/* f041918: 00401825 */ or $v1,$v0,$zero
|
|
.L0f04191c:
|
|
/* f04191c: 8c63a24c */ lw $v1,%lo(g_Vars+0x28c)($v1)
|
|
.L0f041920:
|
|
/* f041920: 8faa0210 */ lw $t2,0x210($sp)
|
|
/* f041924: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f041928: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f04192c: 15400005 */ bnez $t2,.L0f041944
|
|
/* f041930: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041934: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041938: 0fc1979d */ jal func0f065e74
|
|
/* f04193c: afa30064 */ sw $v1,0x64($sp)
|
|
/* f041940: 8fa30064 */ lw $v1,0x64($sp)
|
|
.L0f041944:
|
|
/* f041944: 00002025 */ or $a0,$zero,$zero
|
|
/* f041948: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f04194c: 27a60214 */ addiu $a2,$sp,0x214
|
|
/* f041950: 24070016 */ addiu $a3,$zero,0x16
|
|
/* f041954: 0fc4a640 */ jal explosionCreateSimple
|
|
/* f041958: afa30010 */ sw $v1,0x10($sp)
|
|
.L0f04195c:
|
|
/* f04195c: 8fae01c0 */ lw $t6,0x1c0($sp)
|
|
.L0f041960:
|
|
/* f041960: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f041964: 51c00004 */ beqzl $t6,.L0f041978
|
|
/* f041968: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f04196c: 0fc1905e */ jal propSetPerimEnabled
|
|
/* f041970: 00002825 */ or $a1,$zero,$zero
|
|
/* f041974: 8fa80268 */ lw $t0,0x268($sp)
|
|
.L0f041978:
|
|
/* f041978: 8fb80250 */ lw $t8,0x250($sp)
|
|
/* f04197c: 93ac0260 */ lbu $t4,0x260($sp)
|
|
/* f041980: 0008782b */ sltu $t7,$zero,$t0
|
|
/* f041984: 1300000e */ beqz $t8,.L0f0419c0
|
|
/* f041988: 01e04025 */ or $t0,$t7,$zero
|
|
/* f04198c: 2599fffe */ addiu $t9,$t4,-2
|
|
/* f041990: 2f21002a */ sltiu $at,$t9,0x2a
|
|
/* f041994: 10200009 */ beqz $at,.L0f0419bc
|
|
/* f041998: 0019c880 */ sll $t9,$t9,0x2
|
|
/* f04199c: 3c017f1b */ lui $at,%hi(var7f1a90e0)
|
|
/* f0419a0: 00390821 */ addu $at,$at,$t9
|
|
/* f0419a4: 8c3990e0 */ lw $t9,%lo(var7f1a90e0)($at)
|
|
/* f0419a8: 03200008 */ jr $t9
|
|
/* f0419ac: 00000000 */ nop
|
|
/* f0419b0: 240b0001 */ addiu $t3,$zero,0x1
|
|
/* f0419b4: 10000002 */ b .L0f0419c0
|
|
/* f0419b8: afab0250 */ sw $t3,0x250($sp)
|
|
.L0f0419bc:
|
|
/* f0419bc: afa00250 */ sw $zero,0x250($sp)
|
|
.L0f0419c0:
|
|
/* f0419c0: 11000004 */ beqz $t0,.L0f0419d4
|
|
/* f0419c4: 01003825 */ or $a3,$t0,$zero
|
|
/* f0419c8: 8fa70250 */ lw $a3,0x250($sp)
|
|
/* f0419cc: 0007682b */ sltu $t5,$zero,$a3
|
|
/* f0419d0: 01a03825 */ or $a3,$t5,$zero
|
|
.L0f0419d4:
|
|
/* f0419d4: 27aa0244 */ addiu $t2,$sp,0x244
|
|
/* f0419d8: 27ae0228 */ addiu $t6,$sp,0x228
|
|
/* f0419dc: afae0014 */ sw $t6,0x14($sp)
|
|
/* f0419e0: afaa0010 */ sw $t2,0x10($sp)
|
|
/* f0419e4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0419e8: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f0419ec: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f0419f0: 0fc0f8a7 */ jal chrCreateFireslot
|
|
/* f0419f4: afa80054 */ sw $t0,0x54($sp)
|
|
/* f0419f8: 93af026f */ lbu $t7,0x26f($sp)
|
|
/* f0419fc: 8fa80054 */ lw $t0,0x54($sp)
|
|
/* f041a00: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041a04: 11e00015 */ beqz $t7,.L0f041a5c
|
|
/* f041a08: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041a0c: 1100000a */ beqz $t0,.L0f041a38
|
|
/* f041a10: 01003025 */ or $a2,$t0,$zero
|
|
/* f041a14: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f041a18: 8fb9027c */ lw $t9,0x27c($sp)
|
|
/* f041a1c: 8f0c02d4 */ lw $t4,0x2d4($t8)
|
|
/* f041a20: 00195880 */ sll $t3,$t9,0x2
|
|
/* f041a24: 018b1021 */ addu $v0,$t4,$t3
|
|
/* f041a28: 8c430024 */ lw $v1,0x24($v0)
|
|
/* f041a2c: 18600002 */ blez $v1,.L0f041a38
|
|
/* f041a30: 246dffff */ addiu $t5,$v1,-1
|
|
/* f041a34: ac4d0024 */ sw $t5,0x24($v0)
|
|
.L0f041a38:
|
|
/* f041a38: 11000004 */ beqz $t0,.L0f041a4c
|
|
/* f041a3c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041a40: 93a6026e */ lbu $a2,0x26e($sp)
|
|
/* f041a44: 0006502b */ sltu $t2,$zero,$a2
|
|
/* f041a48: 01403025 */ or $a2,$t2,$zero
|
|
.L0f041a4c:
|
|
/* f041a4c: 0fc0fe12 */ jal chrSetFiring
|
|
/* f041a50: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f041a54: 10000004 */ b .L0f041a68
|
|
/* f041a58: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.L0f041a5c:
|
|
/* f041a5c: 0fc0fe12 */ jal chrSetFiring
|
|
/* f041a60: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f041a64: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.L0f041a68:
|
|
/* f041a68: 27bd0278 */ addiu $sp,$sp,0x278
|
|
/* f041a6c: 03e00008 */ jr $ra
|
|
/* f041a70: 00000000 */ nop
|
|
);
|
|
#else
|
|
GLOBAL_ASM(
|
|
glabel chrShoot
|
|
.late_rodata
|
|
glabel var7f1a90c8
|
|
.word 0x3d638e39
|
|
glabel var7f1a90cc
|
|
.word 0x481c4000
|
|
glabel var7f1a90d0
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d4
|
|
.word 0x3fd55555
|
|
glabel var7f1a90d8
|
|
.word 0x3fd55555
|
|
glabel var7f1a90dc
|
|
.word 0x461c4000
|
|
glabel var7f1a90e0
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a90e4
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a90e8
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a90ec
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a90f0
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a90f4
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a90f8
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a90fc
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9100
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9104
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9108
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a910c
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9110
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9114
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9118
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a911c
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9120
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9124
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9128
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a912c
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9130
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9134
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9138
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a913c
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9140
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9144
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9148
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a914c
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9150
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9154
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9158
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a915c
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9160
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9164
|
|
.word chrShoot+0x14d0
|
|
glabel var7f1a9168
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a916c
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9170
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9174
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9178
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a917c
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9180
|
|
.word chrShoot+0x14c4
|
|
glabel var7f1a9184
|
|
.word chrShoot+0x14c4
|
|
.text
|
|
/* f03fcb4: 27bdfd88 */ addiu $sp,$sp,-632
|
|
/* f03fcb8: afbf0044 */ sw $ra,0x44($sp)
|
|
/* f03fcbc: afa5027c */ sw $a1,0x27c($sp)
|
|
/* f03fcc0: 8c8e001c */ lw $t6,0x1c($a0)
|
|
/* f03fcc4: 240f0001 */ addiu $t7,$zero,0x1
|
|
/* f03fcc8: a3af026e */ sb $t7,0x26e($sp)
|
|
/* f03fccc: afae0274 */ sw $t6,0x274($sp)
|
|
/* f03fcd0: 8c9802d4 */ lw $t8,0x2d4($a0)
|
|
/* f03fcd4: 00001025 */ or $v0,$zero,$zero
|
|
/* f03fcd8: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f03fcdc: 53000003 */ beqzl $t8,.NB0f03fcec
|
|
/* f03fce0: a3a2026f */ sb $v0,0x26f($sp)
|
|
/* f03fce4: 24020001 */ addiu $v0,$zero,0x1
|
|
/* f03fce8: a3a2026f */ sb $v0,0x26f($sp)
|
|
.NB0f03fcec:
|
|
/* f03fcec: 0fc0a074 */ jal chrGetHeldProp
|
|
/* f03fcf0: afa40278 */ sw $a0,0x278($sp)
|
|
/* f03fcf4: 5040054e */ beqzl $v0,.NB0f041230
|
|
/* f03fcf8: 8fbf0044 */ lw $ra,0x44($sp)
|
|
/* f03fcfc: afa00268 */ sw $zero,0x268($sp)
|
|
/* f03fd00: 8c590004 */ lw $t9,0x4($v0)
|
|
/* f03fd04: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f03fd08: 0fc0a08c */ jal chrGetTargetProp
|
|
/* f03fd0c: afb90264 */ sw $t9,0x264($sp)
|
|
/* f03fd10: 8fab0264 */ lw $t3,0x264($sp)
|
|
/* f03fd14: afa2025c */ sw $v0,0x25c($sp)
|
|
/* f03fd18: 8fa70278 */ lw $a3,0x278($sp)
|
|
/* f03fd1c: 8961005c */ lwl $at,0x5c($t3)
|
|
/* f03fd20: 9961005f */ lwr $at,0x5f($t3)
|
|
/* f03fd24: 27aa0260 */ addiu $t2,$sp,0x260
|
|
/* f03fd28: 24080200 */ addiu $t0,$zero,0x200
|
|
/* f03fd2c: ad410000 */ sw $at,0x0($t2)
|
|
/* f03fd30: 80e30007 */ lb $v1,0x7($a3)
|
|
/* f03fd34: 24010008 */ addiu $at,$zero,0x8
|
|
/* f03fd38: 10610007 */ beq $v1,$at,.NB0f03fd58
|
|
/* f03fd3c: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f03fd40: 10610005 */ beq $v1,$at,.NB0f03fd58
|
|
/* f03fd44: 2401001c */ addiu $at,$zero,0x1c
|
|
/* f03fd48: 10610003 */ beq $v1,$at,.NB0f03fd58
|
|
/* f03fd4c: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f03fd50: 54610003 */ bnel $v1,$at,.NB0f03fd60
|
|
/* f03fd54: afa00250 */ sw $zero,0x250($sp)
|
|
.NB0f03fd58:
|
|
/* f03fd58: 8ce8004c */ lw $t0,0x4c($a3)
|
|
/* f03fd5c: afa00250 */ sw $zero,0x250($sp)
|
|
.NB0f03fd60:
|
|
/* f03fd60: afa00224 */ sw $zero,0x224($sp)
|
|
/* f03fd64: afa00210 */ sw $zero,0x210($sp)
|
|
/* f03fd68: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f03fd6c: 93a50263 */ lbu $a1,0x263($sp)
|
|
/* f03fd70: afa00254 */ sw $zero,0x254($sp)
|
|
/* f03fd74: 0fc2bf12 */ jal weaponGetNumTicksPerShot
|
|
/* f03fd78: afa80258 */ sw $t0,0x258($sp)
|
|
/* f03fd7c: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f03fd80: 1c400005 */ bgtz $v0,.NB0f03fd98
|
|
/* f03fd84: 00402025 */ or $a0,$v0,$zero
|
|
/* f03fd88: 240f0001 */ addiu $t7,$zero,0x1
|
|
/* f03fd8c: 24060001 */ addiu $a2,$zero,0x1
|
|
/* f03fd90: 10000055 */ beqz $zero,.NB0f03fee8
|
|
/* f03fd94: afaf0250 */ sw $t7,0x250($sp)
|
|
.NB0f03fd98:
|
|
/* f03fd98: 8fb80278 */ lw $t8,0x278($sp)
|
|
/* f03fd9c: 8f0302d4 */ lw $v1,0x2d4($t8)
|
|
/* f03fda0: 5060001d */ beqzl $v1,.NB0f03fe18
|
|
/* f03fda4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f03fda8: 8c790020 */ lw $t9,0x20($v1)
|
|
/* f03fdac: 24010014 */ addiu $at,$zero,0x14
|
|
/* f03fdb0: 57210019 */ bnel $t9,$at,.NB0f03fe18
|
|
/* f03fdb4: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f03fdb8: 8c6d004c */ lw $t5,0x4c($v1)
|
|
/* f03fdbc: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f03fdc0: 000d5080 */ sll $t2,$t5,0x2
|
|
/* f03fdc4: 05400013 */ bltz $t2,.NB0f03fe14
|
|
/* f03fdc8: 000b7040 */ sll $t6,$t3,0x1
|
|
/* f03fdcc: 006e7821 */ addu $t7,$v1,$t6
|
|
/* f03fdd0: 85f800e0 */ lh $t8,0xe0($t7)
|
|
/* f03fdd4: 2419005a */ addiu $t9,$zero,0x5a
|
|
/* f03fdd8: 3c017f1a */ lui $at,0x7f1a
|
|
/* f03fddc: 03386823 */ subu $t5,$t9,$t8
|
|
/* f03fde0: 448d2000 */ mtc1 $t5,$f4
|
|
/* f03fde4: c42833fc */ lwc1 $f8,0x33fc($at)
|
|
/* f03fde8: 44825000 */ mtc1 $v0,$f10
|
|
/* f03fdec: 468021a0 */ cvt.s.w $f6,$f4
|
|
/* f03fdf0: 3c013f80 */ lui $at,0x3f80
|
|
/* f03fdf4: 44819000 */ mtc1 $at,$f18
|
|
/* f03fdf8: 46805420 */ cvt.s.w $f16,$f10
|
|
/* f03fdfc: 46083002 */ mul.s $f0,$f6,$f8
|
|
/* f03fe00: 46009100 */ add.s $f4,$f18,$f0
|
|
/* f03fe04: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f03fe08: 4600320d */ trunc.w.s $f8,$f6
|
|
/* f03fe0c: 44044000 */ mfc1 $a0,$f8
|
|
/* f03fe10: 00000000 */ sll $zero,$zero,0x0
|
|
.NB0f03fe14:
|
|
/* f03fe14: 8faa0278 */ lw $t2,0x278($sp)
|
|
.NB0f03fe18:
|
|
/* f03fe18: 8fab027c */ lw $t3,0x27c($sp)
|
|
/* f03fe1c: 3c0f800a */ lui $t7,0x800a
|
|
/* f03fe20: 8defe6f8 */ lw $t7,-0x1908($t7)
|
|
/* f03fe24: 014b1821 */ addu $v1,$t2,$t3
|
|
/* f03fe28: 906e0004 */ lbu $t6,0x4($v1)
|
|
/* f03fe2c: 01cfc821 */ addu $t9,$t6,$t7
|
|
/* f03fe30: 333800ff */ andi $t8,$t9,0xff
|
|
/* f03fe34: 0304082a */ slt $at,$t8,$a0
|
|
/* f03fe38: 1420002b */ bnez $at,.NB0f03fee8
|
|
/* f03fe3c: a0790004 */ sb $t9,0x4($v1)
|
|
/* f03fe40: a0600004 */ sb $zero,0x4($v1)
|
|
/* f03fe44: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f03fe48: 8fad027c */ lw $t5,0x27c($sp)
|
|
/* f03fe4c: 240c0001 */ addiu $t4,$zero,0x1
|
|
/* f03fe50: 8d4b032c */ lw $t3,0x32c($t2)
|
|
/* f03fe54: 01ac1004 */ sllv $v0,$t4,$t5
|
|
/* f03fe58: 24060001 */ addiu $a2,$zero,0x1
|
|
/* f03fe5c: 000b7300 */ sll $t6,$t3,0xc
|
|
/* f03fe60: 914b032d */ lbu $t3,0x32d($t2)
|
|
/* f03fe64: 000e7f82 */ srl $t7,$t6,0x1e
|
|
/* f03fe68: 01e2c026 */ xor $t8,$t7,$v0
|
|
/* f03fe6c: 00186080 */ sll $t4,$t8,0x2
|
|
/* f03fe70: 318d000c */ andi $t5,$t4,0xc
|
|
/* f03fe74: 316efff3 */ andi $t6,$t3,0xfff3
|
|
/* f03fe78: 01ae7825 */ or $t7,$t5,$t6
|
|
/* f03fe7c: a14f032d */ sb $t7,0x32d($t2)
|
|
/* f03fe80: 8d59032c */ lw $t9,0x32c($t2)
|
|
/* f03fe84: 93ad0260 */ lbu $t5,0x260($sp)
|
|
/* f03fe88: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f03fe8c: 0019c300 */ sll $t8,$t9,0xc
|
|
/* f03fe90: 00186782 */ srl $t4,$t8,0x1e
|
|
/* f03fe94: 01825824 */ and $t3,$t4,$v0
|
|
/* f03fe98: 15600003 */ bnez $t3,.NB0f03fea8
|
|
/* f03fe9c: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f03fea0: 55a10003 */ bnel $t5,$at,.NB0f03feb0
|
|
/* f03fea4: 8faf0278 */ lw $t7,0x278($sp)
|
|
.NB0f03fea8:
|
|
/* f03fea8: afae0250 */ sw $t6,0x250($sp)
|
|
/* f03feac: 8faf0278 */ lw $t7,0x278($sp)
|
|
.NB0f03feb0:
|
|
/* f03feb0: 24010008 */ addiu $at,$zero,0x8
|
|
/* f03feb4: 81ea0007 */ lb $t2,0x7($t7)
|
|
/* f03feb8: 1541000b */ bne $t2,$at,.NB0f03fee8
|
|
/* f03febc: 00000000 */ sll $zero,$zero,0x0
|
|
/* f03fec0: 8de40020 */ lw $a0,0x20($t7)
|
|
/* f03fec4: 0c00786f */ jal modelGetAnimNum
|
|
/* f03fec8: afa60254 */ sw $a2,0x254($sp)
|
|
/* f03fecc: 2401026a */ addiu $at,$zero,0x26a
|
|
/* f03fed0: 14410005 */ bne $v0,$at,.NB0f03fee8
|
|
/* f03fed4: 8fa60254 */ lw $a2,0x254($sp)
|
|
/* f03fed8: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f03fedc: 83380033 */ lb $t8,0x33($t9)
|
|
/* f03fee0: 270c0001 */ addiu $t4,$t8,0x1
|
|
/* f03fee4: a32c0033 */ sb $t4,0x33($t9)
|
|
.NB0f03fee8:
|
|
/* f03fee8: 50c00495 */ beqzl $a2,.NB0f041140
|
|
/* f03feec: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f03fef0: 0fc0f779 */ jal chrGetAimAngle
|
|
/* f03fef4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f03fef8: e7a00204 */ swc1 $f0,0x204($sp)
|
|
/* f03fefc: 0fc0f7d2 */ jal func0f03e754
|
|
/* f03ff00: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f03ff04: 93ab026f */ lbu $t3,0x26f($sp)
|
|
/* f03ff08: e7a00200 */ swc1 $f0,0x200($sp)
|
|
/* f03ff0c: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f03ff10: 11600004 */ beqz $t3,.NB0f03ff24
|
|
/* f03ff14: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f03ff18: 240d0004 */ addiu $t5,$zero,0x4
|
|
/* f03ff1c: 10000002 */ beqz $zero,.NB0f03ff28
|
|
/* f03ff20: afad01fc */ sw $t5,0x1fc($sp)
|
|
.NB0f03ff24:
|
|
/* f03ff24: afa001fc */ sw $zero,0x1fc($sp)
|
|
.NB0f03ff28:
|
|
/* f03ff28: afae0268 */ sw $t6,0x268($sp)
|
|
/* f03ff2c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f03ff30: 0fc0fd76 */ jal chrGetGunPos
|
|
/* f03ff34: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f03ff38: 54400032 */ bnezl $v0,.NB0f040004
|
|
/* f03ff3c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f03ff40: 8fa20274 */ lw $v0,0x274($sp)
|
|
/* f03ff44: 3c0141f0 */ lui $at,0x41f0
|
|
/* f03ff48: 44818000 */ mtc1 $at,$f16
|
|
/* f03ff4c: c44a0008 */ lwc1 $f10,0x8($v0)
|
|
/* f03ff50: 8faa027c */ lw $t2,0x27c($sp)
|
|
/* f03ff54: 24010001 */ addiu $at,$zero,0x1
|
|
/* f03ff58: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f03ff5c: c452000c */ lwc1 $f18,0xc($v0)
|
|
/* f03ff60: 46109100 */ add.s $f4,$f18,$f16
|
|
/* f03ff64: e7a40248 */ swc1 $f4,0x248($sp)
|
|
/* f03ff68: c4460010 */ lwc1 $f6,0x10($v0)
|
|
/* f03ff6c: 15410013 */ bne $t2,$at,.NB0f03ffbc
|
|
/* f03ff70: e7a6024c */ swc1 $f6,0x24c($sp)
|
|
/* f03ff74: 0c006d52 */ jal cosf
|
|
/* f03ff78: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f03ff7c: 3c014120 */ lui $at,0x4120
|
|
/* f03ff80: 44815000 */ mtc1 $at,$f10
|
|
/* f03ff84: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f03ff88: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f03ff8c: 460a0482 */ mul.s $f18,$f0,$f10
|
|
/* f03ff90: 46124400 */ add.s $f16,$f8,$f18
|
|
/* f03ff94: 0c006d55 */ jal sinf
|
|
/* f03ff98: e7b00244 */ swc1 $f16,0x244($sp)
|
|
/* f03ff9c: 3c014120 */ lui $at,0x4120
|
|
/* f03ffa0: 44813000 */ mtc1 $at,$f6
|
|
/* f03ffa4: 46000107 */ neg.s $f4,$f0
|
|
/* f03ffa8: c7a8024c */ lwc1 $f8,0x24c($sp)
|
|
/* f03ffac: 46062282 */ mul.s $f10,$f4,$f6
|
|
/* f03ffb0: 460a4480 */ add.s $f18,$f8,$f10
|
|
/* f03ffb4: 10000012 */ beqz $zero,.NB0f040000
|
|
/* f03ffb8: e7b2024c */ swc1 $f18,0x24c($sp)
|
|
.NB0f03ffbc:
|
|
/* f03ffbc: 0c006d52 */ jal cosf
|
|
/* f03ffc0: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f03ffc4: 3c014120 */ lui $at,0x4120
|
|
/* f03ffc8: 44812000 */ mtc1 $at,$f4
|
|
/* f03ffcc: 46000407 */ neg.s $f16,$f0
|
|
/* f03ffd0: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f03ffd4: 46048182 */ mul.s $f6,$f16,$f4
|
|
/* f03ffd8: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f03ffdc: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f03ffe0: 0c006d55 */ jal sinf
|
|
/* f03ffe4: e7aa0244 */ swc1 $f10,0x244($sp)
|
|
/* f03ffe8: 3c014120 */ lui $at,0x4120
|
|
/* f03ffec: 44818000 */ mtc1 $at,$f16
|
|
/* f03fff0: c7b2024c */ lwc1 $f18,0x24c($sp)
|
|
/* f03fff4: 46100102 */ mul.s $f4,$f0,$f16
|
|
/* f03fff8: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f03fffc: e7a8024c */ swc1 $f8,0x24c($sp)
|
|
.NB0f040000:
|
|
/* f040000: 8fa40278 */ lw $a0,0x278($sp)
|
|
.NB0f040004:
|
|
/* f040004: 0fc07927 */ jal chrSetPerimEnabled
|
|
/* f040008: 00002825 */ or $a1,$zero,$zero
|
|
/* f04000c: 8fb801fc */ lw $t8,0x1fc($sp)
|
|
/* f040010: 8faf0274 */ lw $t7,0x274($sp)
|
|
/* f040014: 24190010 */ addiu $t9,$zero,0x10
|
|
/* f040018: 370c082a */ ori $t4,$t8,0x82a
|
|
/* f04001c: afac0010 */ sw $t4,0x10($sp)
|
|
/* f040020: afb90014 */ sw $t9,0x14($sp)
|
|
/* f040024: 27a60244 */ addiu $a2,$sp,0x244
|
|
/* f040028: 27a70234 */ addiu $a3,$sp,0x234
|
|
/* f04002c: 25e40008 */ addiu $a0,$t7,0x8
|
|
/* f040030: 0c00bc8f */ jal cd0002de34
|
|
/* f040034: 25e50028 */ addiu $a1,$t7,0x28
|
|
/* f040038: 14400002 */ bnez $v0,.NB0f040044
|
|
/* f04003c: 24050001 */ addiu $a1,$zero,0x1
|
|
/* f040040: afa00268 */ sw $zero,0x268($sp)
|
|
.NB0f040044:
|
|
/* f040044: 0fc07927 */ jal chrSetPerimEnabled
|
|
/* f040048: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f04004c: 8fab0268 */ lw $t3,0x268($sp)
|
|
/* f040050: 240d0001 */ addiu $t5,$zero,0x1
|
|
/* f040054: 5160043a */ beqzl $t3,.NB0f041140
|
|
/* f040058: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f04005c: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f040060: afa001f8 */ sw $zero,0x1f8($sp)
|
|
/* f040064: afa001f4 */ sw $zero,0x1f4($sp)
|
|
/* f040068: afad01f0 */ sw $t5,0x1f0($sp)
|
|
/* f04006c: 11c00004 */ beqz $t6,.NB0f040080
|
|
/* f040070: afa001cc */ sw $zero,0x1cc($sp)
|
|
/* f040074: 240a083f */ addiu $t2,$zero,0x83f
|
|
/* f040078: 10000003 */ beqz $zero,.NB0f040088
|
|
/* f04007c: afaa01c8 */ sw $t2,0x1c8($sp)
|
|
.NB0f040080:
|
|
/* f040080: 240f083b */ addiu $t7,$zero,0x83b
|
|
/* f040084: afaf01c8 */ sw $t7,0x1c8($sp)
|
|
.NB0f040088:
|
|
/* f040088: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f04008c: 8ce20004 */ lw $v0,0x4($a3)
|
|
/* f040090: 50400004 */ beqzl $v0,.NB0f0400a4
|
|
/* f040094: 00004825 */ or $t1,$zero,$zero
|
|
/* f040098: 10000002 */ beqz $zero,.NB0f0400a4
|
|
/* f04009c: 904902fe */ lbu $t1,0x2fe($v0)
|
|
/* f0400a0: 00004825 */ or $t1,$zero,$zero
|
|
.NB0f0400a4:
|
|
/* f0400a4: 39220003 */ xori $v0,$t1,0x3
|
|
/* f0400a8: 2c420001 */ sltiu $v0,$v0,0x1
|
|
/* f0400ac: 1040000f */ beqz $v0,.NB0f0400ec
|
|
/* f0400b0: 00401825 */ or $v1,$v0,$zero
|
|
/* f0400b4: afa2005c */ sw $v0,0x5c($sp)
|
|
/* f0400b8: 0fc121b6 */ jal chrGetDistanceToTarget
|
|
/* f0400bc: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0400c0: 3c014316 */ lui $at,0x4316
|
|
/* f0400c4: 44813000 */ mtc1 $at,$f6
|
|
/* f0400c8: 0000c025 */ or $t8,$zero,$zero
|
|
/* f0400cc: 4600303c */ c.lt.s $f6,$f0
|
|
/* f0400d0: 00000000 */ sll $zero,$zero,0x0
|
|
/* f0400d4: 45020003 */ bc1fl .NB0f0400e4
|
|
/* f0400d8: afb8005c */ sw $t8,0x5c($sp)
|
|
/* f0400dc: 24180001 */ addiu $t8,$zero,0x1
|
|
/* f0400e0: afb8005c */ sw $t8,0x5c($sp)
|
|
.NB0f0400e4:
|
|
/* f0400e4: 8fa7025c */ lw $a3,0x25c($sp)
|
|
/* f0400e8: 03001825 */ or $v1,$t8,$zero
|
|
.NB0f0400ec:
|
|
/* f0400ec: afa301c0 */ sw $v1,0x1c0($sp)
|
|
/* f0400f0: 10600016 */ beqz $v1,.NB0f04014c
|
|
/* f0400f4: afa001bc */ sw $zero,0x1bc($sp)
|
|
/* f0400f8: c4ea0008 */ lwc1 $f10,0x8($a3)
|
|
/* f0400fc: c7b00244 */ lwc1 $f16,0x244($sp)
|
|
/* f040100: c7a80248 */ lwc1 $f8,0x248($sp)
|
|
/* f040104: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f040108: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f04010c: c7b0024c */ lwc1 $f16,0x24c($sp)
|
|
/* f040110: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040114: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040118: e7b201e0 */ swc1 $f18,0x1e0($sp)
|
|
/* f04011c: c4e4000c */ lwc1 $f4,0xc($a3)
|
|
/* f040120: 46082181 */ sub.s $f6,$f4,$f8
|
|
/* f040124: e7a601e4 */ swc1 $f6,0x1e4($sp)
|
|
/* f040128: c4ea0010 */ lwc1 $f10,0x10($a3)
|
|
/* f04012c: 46105481 */ sub.s $f18,$f10,$f16
|
|
/* f040130: 0c0012a8 */ jal guNormalize
|
|
/* f040134: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
/* f040138: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f04013c: 0fc18cfb */ jal propSetPerimEnabled
|
|
/* f040140: 24050001 */ addiu $a1,$zero,0x1
|
|
/* f040144: 1000002f */ beqz $zero,.NB0f040204
|
|
/* f040148: 8fab0278 */ lw $t3,0x278($sp)
|
|
.NB0f04014c:
|
|
/* f04014c: 0c006d52 */ jal cosf
|
|
/* f040150: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040154: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f040158: 0c006d55 */ jal sinf
|
|
/* f04015c: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f040160: c7a40060 */ lwc1 $f4,0x60($sp)
|
|
/* f040164: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040168: 46040202 */ mul.s $f8,$f0,$f4
|
|
/* f04016c: 0c006d55 */ jal sinf
|
|
/* f040170: e7a801e0 */ swc1 $f8,0x1e0($sp)
|
|
/* f040174: e7a001e4 */ swc1 $f0,0x1e4($sp)
|
|
/* f040178: 0c006d52 */ jal cosf
|
|
/* f04017c: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f040180: e7a00060 */ swc1 $f0,0x60($sp)
|
|
/* f040184: 0c006d52 */ jal cosf
|
|
/* f040188: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f04018c: c7a60060 */ lwc1 $f6,0x60($sp)
|
|
/* f040190: 93ac026f */ lbu $t4,0x26f($sp)
|
|
/* f040194: 46060282 */ mul.s $f10,$f0,$f6
|
|
/* f040198: 11800019 */ beqz $t4,.NB0f040200
|
|
/* f04019c: e7aa01e8 */ swc1 $f10,0x1e8($sp)
|
|
/* f0401a0: 0fc62d37 */ jal botGuessCrouchPos
|
|
/* f0401a4: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0401a8: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f0401ac: 00404825 */ or $t1,$v0,$zero
|
|
/* f0401b0: 8fae0278 */ lw $t6,0x278($sp)
|
|
/* f0401b4: 8f280170 */ lw $t0,0x170($t9)
|
|
/* f0401b8: 0008582b */ sltu $t3,$zero,$t0
|
|
/* f0401bc: 11600004 */ beqz $t3,.NB0f0401d0
|
|
/* f0401c0: 01604025 */ or $t0,$t3,$zero
|
|
/* f0401c4: 8f280174 */ lw $t0,0x174($t9)
|
|
/* f0401c8: 0008682b */ sltu $t5,$zero,$t0
|
|
/* f0401cc: 01a04025 */ or $t0,$t5,$zero
|
|
.NB0f0401d0:
|
|
/* f0401d0: 8dc302d4 */ lw $v1,0x2d4($t6)
|
|
/* f0401d4: 8fb8027c */ lw $t8,0x27c($sp)
|
|
/* f0401d8: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f0401dc: 8c66004c */ lw $a2,0x4c($v1)
|
|
/* f0401e0: 00786021 */ addu $t4,$v1,$t8
|
|
/* f0401e4: 9187004d */ lbu $a3,0x4d($t4)
|
|
/* f0401e8: 8c650020 */ lw $a1,0x20($v1)
|
|
/* f0401ec: 00065080 */ sll $t2,$a2,0x2
|
|
/* f0401f0: 000a37c2 */ srl $a2,$t2,0x1f
|
|
/* f0401f4: afa80014 */ sw $t0,0x14($sp)
|
|
/* f0401f8: 0fc27b58 */ jal bgunCalculateBotShotSpread
|
|
/* f0401fc: afa90010 */ sw $t1,0x10($sp)
|
|
.NB0f040200:
|
|
/* f040200: 8fab0278 */ lw $t3,0x278($sp)
|
|
.NB0f040204:
|
|
/* f040204: 93b90260 */ lbu $t9,0x260($sp)
|
|
/* f040208: 24010016 */ addiu $at,$zero,0x16
|
|
/* f04020c: 8d6302d4 */ lw $v1,0x2d4($t3)
|
|
/* f040210: 50600018 */ beqzl $v1,.NB0f040274
|
|
/* f040214: 3c014780 */ lui $at,0x4780
|
|
/* f040218: 57210016 */ bnel $t9,$at,.NB0f040274
|
|
/* f04021c: 3c014780 */ lui $at,0x4780
|
|
/* f040220: 8c6d0128 */ lw $t5,0x128($v1)
|
|
/* f040224: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f040228: 01602025 */ or $a0,$t3,$zero
|
|
/* f04022c: 15a00010 */ bnez $t5,.NB0f040270
|
|
/* f040230: 00002825 */ or $a1,$zero,$zero
|
|
/* f040234: afae0250 */ sw $t6,0x250($sp)
|
|
/* f040238: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f04023c: 0fc64fd9 */ jal botactShootFarsight
|
|
/* f040240: 27a70244 */ addiu $a3,$sp,0x244
|
|
/* f040244: 24010002 */ addiu $at,$zero,0x2
|
|
/* f040248: 5441000a */ bnel $v0,$at,.NB0f040274
|
|
/* f04024c: 3c014780 */ lui $at,0x4780
|
|
/* f040250: 0c004d84 */ jal random
|
|
/* f040254: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040258: 240100ff */ addiu $at,$zero,0xff
|
|
/* f04025c: 0041001b */ divu $zero,$v0,$at
|
|
/* f040260: 00005010 */ mfhi $t2
|
|
/* f040264: 2d4f00c9 */ sltiu $t7,$t2,0xc9
|
|
/* f040268: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f04026c: a3af026e */ sb $t7,0x26e($sp)
|
|
.NB0f040270:
|
|
/* f040270: 3c014780 */ lui $at,0x4780
|
|
.NB0f040274:
|
|
/* f040274: 44810000 */ mtc1 $at,$f0
|
|
/* f040278: c7b001e0 */ lwc1 $f16,0x1e0($sp)
|
|
/* f04027c: c7a40244 */ lwc1 $f4,0x244($sp)
|
|
/* f040280: c7a601e4 */ lwc1 $f6,0x1e4($sp)
|
|
/* f040284: 46008482 */ mul.s $f18,$f16,$f0
|
|
/* f040288: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f04028c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040290: 46003282 */ mul.s $f10,$f6,$f0
|
|
/* f040294: c7a6024c */ lwc1 $f6,0x24c($sp)
|
|
/* f040298: 00002825 */ or $a1,$zero,$zero
|
|
/* f04029c: 46049200 */ add.s $f8,$f18,$f4
|
|
/* f0402a0: c7a401e8 */ lwc1 $f4,0x1e8($sp)
|
|
/* f0402a4: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f0402a8: e7a80228 */ swc1 $f8,0x228($sp)
|
|
/* f0402ac: 46002202 */ mul.s $f8,$f4,$f0
|
|
/* f0402b0: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f0402b4: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f0402b8: 0fc07927 */ jal chrSetPerimEnabled
|
|
/* f0402bc: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f0402c0: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f0402c4: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f0402c8: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f0402cc: 13000004 */ beqz $t8,.NB0f0402e0
|
|
/* f0402d0: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0402d4: 240c0001 */ addiu $t4,$zero,0x1
|
|
/* f0402d8: 3c01800a */ lui $at,0x800a
|
|
/* f0402dc: ac2ceb4c */ sw $t4,-0x14b4($at)
|
|
.NB0f0402e0:
|
|
/* f0402e0: 24190010 */ addiu $t9,$zero,0x10
|
|
/* f0402e4: afb90010 */ sw $t9,0x10($sp)
|
|
/* f0402e8: 0c00bc66 */ jal cdTestAToB4
|
|
/* f0402ec: 8fa701c8 */ lw $a3,0x1c8($sp)
|
|
/* f0402f0: 1440000a */ bnez $v0,.NB0f04031c
|
|
/* f0402f4: 240d0001 */ addiu $t5,$zero,0x1
|
|
/* f0402f8: 3c067f1a */ lui $a2,0x7f1a
|
|
/* f0402fc: afad0224 */ sw $t5,0x224($sp)
|
|
/* f040300: 24c62e9c */ addiu $a2,$a2,0x2e9c
|
|
/* f040304: 27a40228 */ addiu $a0,$sp,0x228
|
|
/* f040308: 0c0098a7 */ jal cdGetPos
|
|
/* f04030c: 24052f36 */ addiu $a1,$zero,0x2f36
|
|
/* f040310: 0c0098a4 */ jal cdGetObstacle
|
|
/* f040314: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040318: afa201cc */ sw $v0,0x1cc($sp)
|
|
.NB0f04031c:
|
|
/* f04031c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040320: 0fc07927 */ jal chrSetPerimEnabled
|
|
/* f040324: 24050001 */ addiu $a1,$zero,0x1
|
|
/* f040328: 93ae026f */ lbu $t6,0x26f($sp)
|
|
/* f04032c: 3c01800a */ lui $at,0x800a
|
|
/* f040330: 51c00003 */ beqzl $t6,.NB0f040340
|
|
/* f040334: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
/* f040338: ac20eb4c */ sw $zero,-0x14b4($at)
|
|
/* f04033c: 8fab01cc */ lw $t3,0x1cc($sp)
|
|
.NB0f040340:
|
|
/* f040340: 8faa01c0 */ lw $t2,0x1c0($sp)
|
|
/* f040344: 55600015 */ bnezl $t3,.NB0f04039c
|
|
/* f040348: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f04034c: 51400013 */ beqzl $t2,.NB0f04039c
|
|
/* f040350: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
/* f040354: 0c004d84 */ jal random
|
|
/* f040358: 00000000 */ sll $zero,$zero,0x0
|
|
/* f04035c: 24010064 */ addiu $at,$zero,0x64
|
|
/* f040360: 0041001b */ divu $zero,$v0,$at
|
|
/* f040364: 00001810 */ mfhi $v1
|
|
/* f040368: 2c6f0033 */ sltiu $t7,$v1,0x33
|
|
/* f04036c: 39ef0001 */ xori $t7,$t7,0x1
|
|
/* f040370: 11e00009 */ beqz $t7,.NB0f040398
|
|
/* f040374: afaf01bc */ sw $t7,0x1bc($sp)
|
|
/* f040378: 8fb8025c */ lw $t8,0x25c($sp)
|
|
/* f04037c: afb801cc */ sw $t8,0x1cc($sp)
|
|
/* f040380: c7100008 */ lwc1 $f16,0x8($t8)
|
|
/* f040384: e7b00228 */ swc1 $f16,0x228($sp)
|
|
/* f040388: c712000c */ lwc1 $f18,0xc($t8)
|
|
/* f04038c: e7b2022c */ swc1 $f18,0x22c($sp)
|
|
/* f040390: c7040010 */ lwc1 $f4,0x10($t8)
|
|
/* f040394: e7a40230 */ swc1 $f4,0x230($sp)
|
|
.NB0f040398:
|
|
/* f040398: c7a80228 */ lwc1 $f8,0x228($sp)
|
|
.NB0f04039c:
|
|
/* f04039c: c7a60244 */ lwc1 $f6,0x244($sp)
|
|
/* f0403a0: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f0403a4: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f0403a8: 46064001 */ sub.s $f0,$f8,$f6
|
|
/* f0403ac: c7b20230 */ lwc1 $f18,0x230($sp)
|
|
/* f0403b0: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f0403b4: 46105081 */ sub.s $f2,$f10,$f16
|
|
/* f0403b8: 46000202 */ mul.s $f8,$f0,$f0
|
|
/* f0403bc: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f0403c0: 46049301 */ sub.s $f12,$f18,$f4
|
|
/* f0403c4: 46021182 */ mul.s $f6,$f2,$f2
|
|
/* f0403c8: 24010018 */ addiu $at,$zero,0x18
|
|
/* f0403cc: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f0403d0: 46064280 */ add.s $f10,$f8,$f6
|
|
/* f0403d4: 46105480 */ add.s $f18,$f10,$f16
|
|
/* f0403d8: 1081000f */ beq $a0,$at,.NB0f040418
|
|
/* f0403dc: e7b201d0 */ swc1 $f18,0x1d0($sp)
|
|
/* f0403e0: 24010019 */ addiu $at,$zero,0x19
|
|
/* f0403e4: 1081000c */ beq $a0,$at,.NB0f040418
|
|
/* f0403e8: 24010012 */ addiu $at,$zero,0x12
|
|
/* f0403ec: 14810003 */ bne $a0,$at,.NB0f0403fc
|
|
/* f0403f0: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f0403f4: 24010001 */ addiu $at,$zero,0x1
|
|
/* f0403f8: 11810007 */ beq $t4,$at,.NB0f040418
|
|
.NB0f0403fc:
|
|
/* f0403fc: 24010017 */ addiu $at,$zero,0x17
|
|
/* f040400: 10810005 */ beq $a0,$at,.NB0f040418
|
|
/* f040404: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f040408: 10810003 */ beq $a0,$at,.NB0f040418
|
|
/* f04040c: 24010034 */ addiu $at,$zero,0x34
|
|
/* f040410: 54810171 */ bnel $a0,$at,.NB0f0409d8
|
|
/* f040414: 24010006 */ addiu $at,$zero,0x6
|
|
.NB0f040418:
|
|
/* f040418: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f04041c: afa00250 */ sw $zero,0x250($sp)
|
|
/* f040420: 3c017f1a */ lui $at,0x7f1a
|
|
/* f040424: 17200006 */ bnez $t9,.NB0f040440
|
|
/* f040428: c7a801d0 */ lwc1 $f8,0x1d0($sp)
|
|
/* f04042c: c4243400 */ lwc1 $f4,0x3400($at)
|
|
/* f040430: 4608203c */ c.lt.s $f4,$f8
|
|
/* f040434: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040438: 45020164 */ bc1fl .NB0f0409cc
|
|
/* f04043c: afa00268 */ sw $zero,0x268($sp)
|
|
.NB0f040440:
|
|
/* f040440: 0fc2bb4c */ jal weaponFindById
|
|
/* f040444: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040448: 93ad0263 */ lbu $t5,0x263($sp)
|
|
/* f04044c: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f040450: 24010018 */ addiu $at,$zero,0x18
|
|
/* f040454: 000d7080 */ sll $t6,$t5,0x2
|
|
/* f040458: 004e5821 */ addu $t3,$v0,$t6
|
|
/* f04045c: 10810006 */ beq $a0,$at,.NB0f040478
|
|
/* f040460: 8d630014 */ lw $v1,0x14($t3)
|
|
/* f040464: 24010034 */ addiu $at,$zero,0x34
|
|
/* f040468: 10810003 */ beq $a0,$at,.NB0f040478
|
|
/* f04046c: 24010019 */ addiu $at,$zero,0x19
|
|
/* f040470: 5481000e */ bnel $a0,$at,.NB0f0404ac
|
|
/* f040474: 2401001b */ addiu $at,$zero,0x1b
|
|
.NB0f040478:
|
|
/* f040478: 8c6a0010 */ lw $t2,0x10($v1)
|
|
/* f04047c: 24050052 */ addiu $a1,$zero,0x52
|
|
/* f040480: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040484: 000a7840 */ sll $t7,$t2,0x1
|
|
/* f040488: 05e30003 */ bgezl $t7,.NB0f040498
|
|
/* f04048c: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040490: 24050053 */ addiu $a1,$zero,0x53
|
|
/* f040494: 8c640040 */ lw $a0,0x40($v1)
|
|
.NB0f040498:
|
|
/* f040498: 0fc2282a */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f04049c: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f0404a0: 1000002e */ beqz $zero,.NB0f04055c
|
|
/* f0404a4: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f0404a8: 2401001b */ addiu $at,$zero,0x1b
|
|
.NB0f0404ac:
|
|
/* f0404ac: 1481000a */ bne $a0,$at,.NB0f0404d8
|
|
/* f0404b0: 24050055 */ addiu $a1,$zero,0x55
|
|
/* f0404b4: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f0404b8: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f0404bc: 0fc2282a */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f0404c0: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f0404c4: 10400025 */ beqz $v0,.NB0f04055c
|
|
/* f0404c8: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f0404cc: 93b80263 */ lbu $t8,0x263($sp)
|
|
/* f0404d0: 10000022 */ beqz $zero,.NB0f04055c
|
|
/* f0404d4: a058005f */ sb $t8,0x5f($v0)
|
|
.NB0f0404d8:
|
|
/* f0404d8: 24010017 */ addiu $at,$zero,0x17
|
|
/* f0404dc: 1481000a */ bne $a0,$at,.NB0f040508
|
|
/* f0404e0: 24050054 */ addiu $a1,$zero,0x54
|
|
/* f0404e4: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f0404e8: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f0404ec: 0fc2282a */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f0404f0: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f0404f4: 10400019 */ beqz $v0,.NB0f04055c
|
|
/* f0404f8: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f0404fc: 93ac0263 */ lbu $t4,0x263($sp)
|
|
/* f040500: 10000016 */ beqz $zero,.NB0f04055c
|
|
/* f040504: a04c005f */ sb $t4,0x5f($v0)
|
|
.NB0f040508:
|
|
/* f040508: 24010012 */ addiu $at,$zero,0x12
|
|
/* f04050c: 1481000b */ bne $a0,$at,.NB0f04053c
|
|
/* f040510: 3c0d800a */ lui $t5,0x800a
|
|
/* f040514: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040518: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f04051c: 24050054 */ addiu $a1,$zero,0x54
|
|
/* f040520: 0fc2282a */ jal weaponCreateProjectileFromWeaponNum
|
|
/* f040524: 8fa60278 */ lw $a2,0x278($sp)
|
|
/* f040528: 1040000c */ beqz $v0,.NB0f04055c
|
|
/* f04052c: afa201b8 */ sw $v0,0x1b8($sp)
|
|
/* f040530: 24190002 */ addiu $t9,$zero,0x2
|
|
/* f040534: 10000009 */ beqz $zero,.NB0f04055c
|
|
/* f040538: a059005f */ sb $t9,0x5f($v0)
|
|
.NB0f04053c:
|
|
/* f04053c: 8dade944 */ lw $t5,-0x16bc($t5)
|
|
/* f040540: 8c640040 */ lw $a0,0x40($v1)
|
|
/* f040544: 27a50260 */ addiu $a1,$sp,0x260
|
|
/* f040548: 8dae00bc */ lw $t6,0xbc($t5)
|
|
/* f04054c: 8dc60004 */ lw $a2,0x4($t6)
|
|
/* f040550: 0fc227a4 */ jal weaponCreateProjectileFromGset
|
|
/* f040554: afa300d4 */ sw $v1,0xd4($sp)
|
|
/* f040558: afa201b8 */ sw $v0,0x1b8($sp)
|
|
.NB0f04055c:
|
|
/* f04055c: 1040011b */ beqz $v0,.NB0f0409cc
|
|
/* f040560: 8fab00d4 */ lw $t3,0xd4($sp)
|
|
/* f040564: 8d6a004c */ lw $t2,0x4c($t3)
|
|
/* f040568: 3c017f1a */ lui $at,0x7f1a
|
|
/* f04056c: c4303404 */ lwc1 $f16,0x3404($at)
|
|
/* f040570: 448a3000 */ mtc1 $t2,$f6
|
|
/* f040574: 3c014270 */ lui $at,0x4270
|
|
/* f040578: 44812000 */ mtc1 $at,$f4
|
|
/* f04057c: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f040580: 3c017f1a */ lui $at,0x7f1a
|
|
/* f040584: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040588: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f04058c: 2405001e */ addiu $a1,$zero,0x1e
|
|
/* f040590: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f040594: c4303408 */ lwc1 $f16,0x3408($at)
|
|
/* f040598: 46049203 */ div.s $f8,$f18,$f4
|
|
/* f04059c: e7a80168 */ swc1 $f8,0x168($sp)
|
|
/* f0405a0: 8d6f0054 */ lw $t7,0x54($t3)
|
|
/* f0405a4: 448f3000 */ mtc1 $t7,$f6
|
|
/* f0405a8: 00000000 */ sll $zero,$zero,0x0
|
|
/* f0405ac: 468032a0 */ cvt.s.w $f10,$f6
|
|
/* f0405b0: 46105482 */ mul.s $f18,$f10,$f16
|
|
/* f0405b4: 13000080 */ beqz $t8,.NB0f0407b8
|
|
/* f0405b8: e7b200cc */ swc1 $f18,0xcc($sp)
|
|
/* f0405bc: 0fc1215e */ jal chrIsTargetInFov
|
|
/* f0405c0: 00003025 */ or $a2,$zero,$zero
|
|
/* f0405c4: 1040007c */ beqz $v0,.NB0f0407b8
|
|
/* f0405c8: 00000000 */ sll $zero,$zero,0x0
|
|
/* f0405cc: 93a20263 */ lbu $v0,0x263($sp)
|
|
/* f0405d0: 00001825 */ or $v1,$zero,$zero
|
|
/* f0405d4: 93a40260 */ lbu $a0,0x260($sp)
|
|
/* f0405d8: 14400025 */ bnez $v0,.NB0f040670
|
|
/* f0405dc: 24010018 */ addiu $at,$zero,0x18
|
|
/* f0405e0: 10810006 */ beq $a0,$at,.NB0f0405fc
|
|
/* f0405e4: 8fac025c */ lw $t4,0x25c($sp)
|
|
/* f0405e8: 24010034 */ addiu $at,$zero,0x34
|
|
/* f0405ec: 10810003 */ beq $a0,$at,.NB0f0405fc
|
|
/* f0405f0: 24010019 */ addiu $at,$zero,0x19
|
|
/* f0405f4: 5481001f */ bnel $a0,$at,.NB0f040674
|
|
/* f0405f8: 93a40260 */ lbu $a0,0x260($sp)
|
|
.NB0f0405fc:
|
|
/* f0405fc: 91820000 */ lbu $v0,0x0($t4)
|
|
/* f040600: 24010003 */ addiu $at,$zero,0x3
|
|
/* f040604: 8fb9025c */ lw $t9,0x25c($sp)
|
|
/* f040608: 10410003 */ beq $v0,$at,.NB0f040618
|
|
/* f04060c: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040610: 14410051 */ bne $v0,$at,.NB0f040758
|
|
/* f040614: 00000000 */ sll $zero,$zero,0x0
|
|
.NB0f040618:
|
|
/* f040618: c7240008 */ lwc1 $f4,0x8($t9)
|
|
/* f04061c: c7aa0244 */ lwc1 $f10,0x244($sp)
|
|
/* f040620: c7b20248 */ lwc1 $f18,0x248($sp)
|
|
/* f040624: e7a400b8 */ swc1 $f4,0xb8($sp)
|
|
/* f040628: 8f2d0004 */ lw $t5,0x4($t9)
|
|
/* f04062c: 460a2401 */ sub.s $f16,$f4,$f10
|
|
/* f040630: c7aa024c */ lwc1 $f10,0x24c($sp)
|
|
/* f040634: c5a800b4 */ lwc1 $f8,0xb4($t5)
|
|
/* f040638: 27a401e0 */ addiu $a0,$sp,0x1e0
|
|
/* f04063c: 27a501e4 */ addiu $a1,$sp,0x1e4
|
|
/* f040640: e7a800bc */ swc1 $f8,0xbc($sp)
|
|
/* f040644: c7260010 */ lwc1 $f6,0x10($t9)
|
|
/* f040648: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f04064c: 46124101 */ sub.s $f4,$f8,$f18
|
|
/* f040650: 27a601e8 */ addiu $a2,$sp,0x1e8
|
|
/* f040654: e7a600c0 */ swc1 $f6,0xc0($sp)
|
|
/* f040658: 460a3401 */ sub.s $f16,$f6,$f10
|
|
/* f04065c: e7a401e4 */ swc1 $f4,0x1e4($sp)
|
|
/* f040660: 0c0012a8 */ jal guNormalize
|
|
/* f040664: e7b001e8 */ swc1 $f16,0x1e8($sp)
|
|
/* f040668: 1000003b */ beqz $zero,.NB0f040758
|
|
/* f04066c: 24030001 */ addiu $v1,$zero,0x1
|
|
.NB0f040670:
|
|
/* f040670: 93a40260 */ lbu $a0,0x260($sp)
|
|
.NB0f040674:
|
|
/* f040674: 24050017 */ addiu $a1,$zero,0x17
|
|
/* f040678: 24010012 */ addiu $at,$zero,0x12
|
|
/* f04067c: 14a40003 */ bne $a1,$a0,.NB0f04068c
|
|
/* f040680: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040684: 50400004 */ beqzl $v0,.NB0f040698
|
|
/* f040688: 8fae025c */ lw $t6,0x25c($sp)
|
|
.NB0f04068c:
|
|
/* f04068c: 14810017 */ bne $a0,$at,.NB0f0406ec
|
|
/* f040690: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040694: 8fae025c */ lw $t6,0x25c($sp)
|
|
.NB0f040698:
|
|
/* f040698: 24010003 */ addiu $at,$zero,0x3
|
|
/* f04069c: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f0406a0: 91c20000 */ lbu $v0,0x0($t6)
|
|
/* f0406a4: 10410003 */ beq $v0,$at,.NB0f0406b4
|
|
/* f0406a8: 24010006 */ addiu $at,$zero,0x6
|
|
/* f0406ac: 1441002a */ bne $v0,$at,.NB0f040758
|
|
/* f0406b0: 00000000 */ sll $zero,$zero,0x0
|
|
.NB0f0406b4:
|
|
/* f0406b4: c5480008 */ lwc1 $f8,0x8($t2)
|
|
/* f0406b8: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f0406bc: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f0406c0: e7a800b8 */ swc1 $f8,0xb8($sp)
|
|
/* f0406c4: 8d4b0004 */ lw $t3,0x4($t2)
|
|
/* f0406c8: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f0406cc: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f0406d0: c57200b4 */ lwc1 $f18,0xb4($t3)
|
|
/* f0406d4: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
/* f0406d8: c5440010 */ lwc1 $f4,0x10($t2)
|
|
/* f0406dc: 0fc0febf */ jal chrCalculateTrajectory
|
|
/* f0406e0: e7a400c0 */ swc1 $f4,0xc0($sp)
|
|
/* f0406e4: 1000001c */ beqz $zero,.NB0f040758
|
|
/* f0406e8: 24030001 */ addiu $v1,$zero,0x1
|
|
.NB0f0406ec:
|
|
/* f0406ec: 14a40002 */ bne $a1,$a0,.NB0f0406f8
|
|
/* f0406f0: 24010001 */ addiu $at,$zero,0x1
|
|
/* f0406f4: 10410003 */ beq $v0,$at,.NB0f040704
|
|
.NB0f0406f8:
|
|
/* f0406f8: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f0406fc: 14810016 */ bne $a0,$at,.NB0f040758
|
|
/* f040700: 00000000 */ sll $zero,$zero,0x0
|
|
.NB0f040704:
|
|
/* f040704: 8faf025c */ lw $t7,0x25c($sp)
|
|
/* f040708: 24010006 */ addiu $at,$zero,0x6
|
|
/* f04070c: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040710: c5e60008 */ lwc1 $f6,0x8($t7)
|
|
/* f040714: 27a600b8 */ addiu $a2,$sp,0xb8
|
|
/* f040718: 27a701e0 */ addiu $a3,$sp,0x1e0
|
|
/* f04071c: e7a600b8 */ swc1 $f6,0xb8($sp)
|
|
/* f040720: c5ea000c */ lwc1 $f10,0xc($t7)
|
|
/* f040724: e7aa00bc */ swc1 $f10,0xbc($sp)
|
|
/* f040728: c5f00010 */ lwc1 $f16,0x10($t7)
|
|
/* f04072c: e7b000c0 */ swc1 $f16,0xc0($sp)
|
|
/* f040730: 91f80000 */ lbu $t8,0x0($t7)
|
|
/* f040734: 17010005 */ bne $t8,$at,.NB0f04074c
|
|
/* f040738: 3c0141c8 */ lui $at,0x41c8
|
|
/* f04073c: 44814000 */ mtc1 $at,$f8
|
|
/* f040740: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040744: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f040748: e7b200bc */ swc1 $f18,0xbc($sp)
|
|
.NB0f04074c:
|
|
/* f04074c: 0fc0febf */ jal chrCalculateTrajectory
|
|
/* f040750: 8fa500cc */ lw $a1,0xcc($sp)
|
|
/* f040754: 24030001 */ addiu $v1,$zero,0x1
|
|
.NB0f040758:
|
|
/* f040758: 10600017 */ beqz $v1,.NB0f0407b8
|
|
/* f04075c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040760: 0fc11fe5 */ jal chrGetAngleToPos
|
|
/* f040764: 27a500b8 */ addiu $a1,$sp,0xb8
|
|
/* f040768: e7a000b4 */ swc1 $f0,0xb4($sp)
|
|
/* f04076c: 0c006d52 */ jal cosf
|
|
/* f040770: 46000306 */ mov.s $f12,$f0
|
|
/* f040774: c7ac00b4 */ lwc1 $f12,0xb4($sp)
|
|
/* f040778: 0c006d55 */ jal sinf
|
|
/* f04077c: e7a000b0 */ swc1 $f0,0xb0($sp)
|
|
/* f040780: c7ac01e8 */ lwc1 $f12,0x1e8($sp)
|
|
/* f040784: c7ae00b0 */ lwc1 $f14,0xb0($sp)
|
|
/* f040788: c7a201e0 */ lwc1 $f2,0x1e0($sp)
|
|
/* f04078c: 460c0102 */ mul.s $f4,$f0,$f12
|
|
/* f040790: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040794: 46027182 */ mul.s $f6,$f14,$f2
|
|
/* f040798: 00000000 */ sll $zero,$zero,0x0
|
|
/* f04079c: 460c7282 */ mul.s $f10,$f14,$f12
|
|
/* f0407a0: 00000000 */ sll $zero,$zero,0x0
|
|
/* f0407a4: 46020202 */ mul.s $f8,$f0,$f2
|
|
/* f0407a8: 46062400 */ add.s $f16,$f4,$f6
|
|
/* f0407ac: e7b001e0 */ swc1 $f16,0x1e0($sp)
|
|
/* f0407b0: 46085481 */ sub.s $f18,$f10,$f8
|
|
/* f0407b4: e7b201e8 */ swc1 $f18,0x1e8($sp)
|
|
.NB0f0407b8:
|
|
/* f0407b8: 0c005a28 */ jal mtx4LoadIdentity
|
|
/* f0407bc: 27a40178 */ addiu $a0,$sp,0x178
|
|
/* f0407c0: c7ac0200 */ lwc1 $f12,0x200($sp)
|
|
/* f0407c4: 0c005c9e */ jal mtx4LoadXRotation
|
|
/* f0407c8: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f0407cc: c7ac0204 */ lwc1 $f12,0x204($sp)
|
|
/* f0407d0: 0c005cc1 */ jal mtx4LoadYRotation
|
|
/* f0407d4: 27a500dc */ addiu $a1,$sp,0xdc
|
|
/* f0407d8: 27a400dc */ addiu $a0,$sp,0xdc
|
|
/* f0407dc: 0c005ab4 */ jal mtx00015be0
|
|
/* f0407e0: 27a5011c */ addiu $a1,$sp,0x11c
|
|
/* f0407e4: c7ac0168 */ lwc1 $f12,0x168($sp)
|
|
/* f0407e8: c7a401e0 */ lwc1 $f4,0x1e0($sp)
|
|
/* f0407ec: c7b001e4 */ lwc1 $f16,0x1e4($sp)
|
|
/* f0407f0: c7a801e8 */ lwc1 $f8,0x1e8($sp)
|
|
/* f0407f4: 460c2182 */ mul.s $f6,$f4,$f12
|
|
/* f0407f8: c7a200cc */ lwc1 $f2,0xcc($sp)
|
|
/* f0407fc: 3c01800a */ lui $at,0x800a
|
|
/* f040800: 460c8282 */ mul.s $f10,$f16,$f12
|
|
/* f040804: c420e70c */ lwc1 $f0,-0x18f4($at)
|
|
/* f040808: 8fac00d4 */ lw $t4,0xd4($sp)
|
|
/* f04080c: 460c4482 */ mul.s $f18,$f8,$f12
|
|
/* f040810: e7a6015c */ swc1 $f6,0x15c($sp)
|
|
/* f040814: 8fa401b8 */ lw $a0,0x1b8($sp)
|
|
/* f040818: 46022102 */ mul.s $f4,$f4,$f2
|
|
/* f04081c: e7aa0160 */ swc1 $f10,0x160($sp)
|
|
/* f040820: 2401ffff */ addiu $at,$zero,-1
|
|
/* f040824: 46003182 */ mul.s $f6,$f6,$f0
|
|
/* f040828: e7b20164 */ swc1 $f18,0x164($sp)
|
|
/* f04082c: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f040830: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f040834: 27a7011c */ addiu $a3,$sp,0x11c
|
|
/* f040838: 27ae016c */ addiu $t6,$sp,0x16c
|
|
/* f04083c: 27ab0178 */ addiu $t3,$sp,0x178
|
|
/* f040840: 46062100 */ add.s $f4,$f4,$f6
|
|
/* f040844: 46028182 */ mul.s $f6,$f16,$f2
|
|
/* f040848: e7a4016c */ swc1 $f4,0x16c($sp)
|
|
/* f04084c: 46005102 */ mul.s $f4,$f10,$f0
|
|
/* f040850: 46043400 */ add.s $f16,$f6,$f4
|
|
/* f040854: 46024282 */ mul.s $f10,$f8,$f2
|
|
/* f040858: 00000000 */ sll $zero,$zero,0x0
|
|
/* f04085c: 46009182 */ mul.s $f6,$f18,$f0
|
|
/* f040860: e7b00170 */ swc1 $f16,0x170($sp)
|
|
/* f040864: 46065100 */ add.s $f4,$f10,$f6
|
|
/* f040868: e7a40174 */ swc1 $f4,0x174($sp)
|
|
/* f04086c: 8d8d0058 */ lw $t5,0x58($t4)
|
|
/* f040870: a48d0062 */ sh $t5,0x62($a0)
|
|
/* f040874: 84820062 */ lh $v0,0x62($a0)
|
|
/* f040878: 10410002 */ beq $v0,$at,.NB0f040884
|
|
/* f04087c: 0002c880 */ sll $t9,$v0,0x2
|
|
/* f040880: a4990062 */ sh $t9,0x62($a0)
|
|
.NB0f040884:
|
|
/* f040884: 8faa0274 */ lw $t2,0x274($sp)
|
|
/* f040888: afae0010 */ sw $t6,0x10($sp)
|
|
/* f04088c: afab0014 */ sw $t3,0x14($sp)
|
|
/* f040890: afa5001c */ sw $a1,0x1c($sp)
|
|
/* f040894: 0fc27298 */ jal bgun0f09ebcc
|
|
/* f040898: afaa0018 */ sw $t2,0x18($sp)
|
|
/* f04089c: 8fa301b8 */ lw $v1,0x1b8($sp)
|
|
/* f0408a0: 8fac00d4 */ lw $t4,0xd4($sp)
|
|
/* f0408a4: 8c6f0040 */ lw $t7,0x40($v1)
|
|
/* f0408a8: 31f80080 */ andi $t8,$t7,0x80
|
|
/* f0408ac: 13000047 */ beqz $t8,.NB0f0409cc
|
|
/* f0408b0: 00000000 */ sll $zero,$zero,0x0
|
|
/* f0408b4: 8d820010 */ lw $v0,0x10($t4)
|
|
/* f0408b8: 00026800 */ sll $t5,$v0,0x0
|
|
/* f0408bc: 05a10007 */ bgez $t5,.NB0f0408dc
|
|
/* f0408c0: 00025900 */ sll $t3,$v0,0x4
|
|
/* f0408c4: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f0408c8: 3c014000 */ lui $at,0x4000
|
|
/* f0408cc: 8c590000 */ lw $t9,0x0($v0)
|
|
/* f0408d0: 03217025 */ or $t6,$t9,$at
|
|
/* f0408d4: 10000007 */ beqz $zero,.NB0f0408f4
|
|
/* f0408d8: ac4e0000 */ sw $t6,0x0($v0)
|
|
.NB0f0408dc:
|
|
/* f0408dc: 05630006 */ bgezl $t3,.NB0f0408f8
|
|
/* f0408e0: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
/* f0408e4: 8c620048 */ lw $v0,0x48($v1)
|
|
/* f0408e8: 8c4a0000 */ lw $t2,0x0($v0)
|
|
/* f0408ec: 354f0010 */ ori $t7,$t2,0x10
|
|
/* f0408f0: ac4f0000 */ sw $t7,0x0($v0)
|
|
.NB0f0408f4:
|
|
/* f0408f4: c7b0015c */ lwc1 $f16,0x15c($sp)
|
|
.NB0f0408f8:
|
|
/* f0408f8: 8c780048 */ lw $t8,0x48($v1)
|
|
/* f0408fc: 241900f0 */ addiu $t9,$zero,0xf0
|
|
/* f040900: 3c017f1a */ lui $at,0x7f1a
|
|
/* f040904: e7100010 */ swc1 $f16,0x10($t8)
|
|
/* f040908: 8c6c0048 */ lw $t4,0x48($v1)
|
|
/* f04090c: c7a80160 */ lwc1 $f8,0x160($sp)
|
|
/* f040910: e5880014 */ swc1 $f8,0x14($t4)
|
|
/* f040914: 8c6d0048 */ lw $t5,0x48($v1)
|
|
/* f040918: c7b20164 */ lwc1 $f18,0x164($sp)
|
|
/* f04091c: e5b20018 */ swc1 $f18,0x18($t5)
|
|
/* f040920: 8c6e0048 */ lw $t6,0x48($v1)
|
|
/* f040924: add900b4 */ sw $t9,0xb4($t6)
|
|
/* f040928: 8fab00d4 */ lw $t3,0xd4($sp)
|
|
/* f04092c: 8c6a0048 */ lw $t2,0x48($v1)
|
|
/* f040930: c56a005c */ lwc1 $f10,0x5c($t3)
|
|
/* f040934: e54a008c */ swc1 $f10,0x8c($t2)
|
|
/* f040938: 8faf00d4 */ lw $t7,0xd4($sp)
|
|
/* f04093c: c424340c */ lwc1 $f4,0x340c($at)
|
|
/* f040940: 8c780048 */ lw $t8,0x48($v1)
|
|
/* f040944: c5e60050 */ lwc1 $f6,0x50($t7)
|
|
/* f040948: 46043402 */ mul.s $f16,$f6,$f4
|
|
/* f04094c: e7100098 */ swc1 $f16,0x98($t8)
|
|
/* f040950: 0fc0a08c */ jal chrGetTargetProp
|
|
/* f040954: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040958: 8fac01b8 */ lw $t4,0x1b8($sp)
|
|
/* f04095c: 3c01bf80 */ lui $at,0xbf80
|
|
/* f040960: 00002025 */ or $a0,$zero,$zero
|
|
/* f040964: 8d8d0048 */ lw $t5,0x48($t4)
|
|
/* f040968: 2407ffff */ addiu $a3,$zero,-1
|
|
/* f04096c: 240effff */ addiu $t6,$zero,-1
|
|
/* f040970: ada200e8 */ sw $v0,0xe8($t5)
|
|
/* f040974: 8fb900d4 */ lw $t9,0xd4($sp)
|
|
/* f040978: 240bffff */ addiu $t3,$zero,-1
|
|
/* f04097c: 87260060 */ lh $a2,0x60($t9)
|
|
/* f040980: 18c00012 */ blez $a2,.NB0f0409cc
|
|
/* f040984: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040988: 8d850014 */ lw $a1,0x14($t4)
|
|
/* f04098c: 44810000 */ mtc1 $at,$f0
|
|
/* f040990: afab002c */ sw $t3,0x2c($sp)
|
|
/* f040994: afa00028 */ sw $zero,0x28($sp)
|
|
/* f040998: afa00020 */ sw $zero,0x20($sp)
|
|
/* f04099c: afa0001c */ sw $zero,0x1c($sp)
|
|
/* f0409a0: afa00018 */ sw $zero,0x18($sp)
|
|
/* f0409a4: afa00014 */ sw $zero,0x14($sp)
|
|
/* f0409a8: afae0010 */ sw $t6,0x10($sp)
|
|
/* f0409ac: e7a00024 */ swc1 $f0,0x24($sp)
|
|
/* f0409b0: e7a00030 */ swc1 $f0,0x30($sp)
|
|
/* f0409b4: e7a00034 */ swc1 $f0,0x34($sp)
|
|
/* f0409b8: 0fc24762 */ jal propsnd0f0939f8
|
|
/* f0409bc: e7a00038 */ swc1 $f0,0x38($sp)
|
|
/* f0409c0: 10000002 */ beqz $zero,.NB0f0409cc
|
|
/* f0409c4: 00000000 */ sll $zero,$zero,0x0
|
|
/* f0409c8: afa00268 */ sw $zero,0x268($sp)
|
|
.NB0f0409cc:
|
|
/* f0409cc: 10000019 */ beqz $zero,.NB0f040a34
|
|
/* f0409d0: a3a0026e */ sb $zero,0x26e($sp)
|
|
/* f0409d4: 24010006 */ addiu $at,$zero,0x6
|
|
.NB0f0409d8:
|
|
/* f0409d8: 14810016 */ bne $a0,$at,.NB0f040a34
|
|
/* f0409dc: 93aa026f */ lbu $t2,0x26f($sp)
|
|
/* f0409e0: 11400014 */ beqz $t2,.NB0f040a34
|
|
/* f0409e4: 93af0263 */ lbu $t7,0x263($sp)
|
|
/* f0409e8: 24010001 */ addiu $at,$zero,0x1
|
|
/* f0409ec: 15e10011 */ bne $t7,$at,.NB0f040a34
|
|
/* f0409f0: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f0409f4: 8fa2027c */ lw $v0,0x27c($sp)
|
|
/* f0409f8: 8db902d4 */ lw $t9,0x2d4($t5)
|
|
/* f0409fc: 3c014120 */ lui $at,0x4120
|
|
/* f040a00: 0002c080 */ sll $t8,$v0,0x2
|
|
/* f040a04: 03386021 */ addu $t4,$t9,$t8
|
|
/* f040a08: c58800e4 */ lwc1 $f8,0xe4($t4)
|
|
/* f040a0c: 44819000 */ mtc1 $at,$f18
|
|
/* f040a10: 44802000 */ mtc1 $zero,$f4
|
|
/* f040a14: 46124282 */ mul.s $f10,$f8,$f18
|
|
/* f040a18: 4600518d */ trunc.w.s $f6,$f10
|
|
/* f040a1c: 440b3000 */ mfc1 $t3,$f6
|
|
/* f040a20: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040a24: a3ab0262 */ sb $t3,0x262($sp)
|
|
/* f040a28: 8daa02d4 */ lw $t2,0x2d4($t5)
|
|
/* f040a2c: 01587821 */ addu $t7,$t2,$t8
|
|
/* f040a30: e5e400e4 */ swc1 $f4,0xe4($t7)
|
|
.NB0f040a34:
|
|
/* f040a34: 93b8026e */ lbu $t8,0x26e($sp)
|
|
/* f040a38: 93b9026f */ lbu $t9,0x26f($sp)
|
|
/* f040a3c: 530001ba */ beqzl $t8,.NB0f041128
|
|
/* f040a40: 8fac01c0 */ lw $t4,0x1c0($sp)
|
|
/* f040a44: 172000d0 */ bnez $t9,.NB0f040d88
|
|
/* f040a48: 8fac0258 */ lw $t4,0x258($sp)
|
|
/* f040a4c: 318e0200 */ andi $t6,$t4,0x200
|
|
/* f040a50: 11c00046 */ beqz $t6,.NB0f040b6c
|
|
/* f040a54: 8fab025c */ lw $t3,0x25c($sp)
|
|
/* f040a58: 916d0000 */ lbu $t5,0x0($t3)
|
|
/* f040a5c: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040a60: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040a64: 15a10041 */ bne $t5,$at,.NB0f040b6c
|
|
/* f040a68: 27a50244 */ addiu $a1,$sp,0x244
|
|
/* f040a6c: 27a60234 */ addiu $a2,$sp,0x234
|
|
/* f040a70: 0fc0e2c1 */ jal chrCanSeeAttackTarget
|
|
/* f040a74: 00003825 */ or $a3,$zero,$zero
|
|
/* f040a78: 1040003c */ beqz $v0,.NB0f040b6c
|
|
/* f040a7c: 3c014170 */ lui $at,0x4170
|
|
/* f040a80: 44817000 */ mtc1 $at,$f14
|
|
/* f040a84: 8faa025c */ lw $t2,0x25c($sp)
|
|
/* f040a88: c7aa01e0 */ lwc1 $f10,0x1e0($sp)
|
|
/* f040a8c: c7a80244 */ lwc1 $f8,0x244($sp)
|
|
/* f040a90: c5500008 */ lwc1 $f16,0x8($t2)
|
|
/* f040a94: 460e5182 */ mul.s $f6,$f10,$f14
|
|
/* f040a98: c7aa01e4 */ lwc1 $f10,0x1e4($sp)
|
|
/* f040a9c: 46088481 */ sub.s $f18,$f16,$f8
|
|
/* f040aa0: c7b00248 */ lwc1 $f16,0x248($sp)
|
|
/* f040aa4: c544000c */ lwc1 $f4,0xc($t2)
|
|
/* f040aa8: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040aac: 27a501f8 */ addiu $a1,$sp,0x1f8
|
|
/* f040ab0: 46069001 */ sub.s $f0,$f18,$f6
|
|
/* f040ab4: 460e5482 */ mul.s $f18,$f10,$f14
|
|
/* f040ab8: c7aa01e8 */ lwc1 $f10,0x1e8($sp)
|
|
/* f040abc: 46102201 */ sub.s $f8,$f4,$f16
|
|
/* f040ac0: c7a4024c */ lwc1 $f4,0x24c($sp)
|
|
/* f040ac4: c5460010 */ lwc1 $f6,0x10($t2)
|
|
/* f040ac8: 27a601f4 */ addiu $a2,$sp,0x1f4
|
|
/* f040acc: 46124081 */ sub.s $f2,$f8,$f18
|
|
/* f040ad0: 460e5202 */ mul.s $f8,$f10,$f14
|
|
/* f040ad4: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f040ad8: 46043401 */ sub.s $f16,$f6,$f4
|
|
/* f040adc: 46000182 */ mul.s $f6,$f0,$f0
|
|
/* f040ae0: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040ae4: 46021102 */ mul.s $f4,$f2,$f2
|
|
/* f040ae8: 46088301 */ sub.s $f12,$f16,$f8
|
|
/* f040aec: 460c6402 */ mul.s $f16,$f12,$f12
|
|
/* f040af0: 46043280 */ add.s $f10,$f6,$f4
|
|
/* f040af4: 46105200 */ add.s $f8,$f10,$f16
|
|
/* f040af8: 4612403e */ c.le.s $f8,$f18
|
|
/* f040afc: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040b00: 4500002b */ bc1f .NB0f040bb0
|
|
/* f040b04: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040b08: 0fc0fca9 */ jal chrCalculateHit
|
|
/* f040b0c: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f040b10: 8faf01f4 */ lw $t7,0x1f4($sp)
|
|
/* f040b14: 8fb901f8 */ lw $t9,0x1f8($sp)
|
|
/* f040b18: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f040b1c: 2df80001 */ sltiu $t8,$t7,0x1
|
|
/* f040b20: 13200023 */ beqz $t9,.NB0f040bb0
|
|
/* f040b24: afb801f0 */ sw $t8,0x1f0($sp)
|
|
/* f040b28: 81830007 */ lb $v1,0x7($t4)
|
|
/* f040b2c: 24010008 */ addiu $at,$zero,0x8
|
|
/* f040b30: 3c0e800a */ lui $t6,0x800a
|
|
/* f040b34: 1061000a */ beq $v1,$at,.NB0f040b60
|
|
/* f040b38: 8fab0278 */ lw $t3,0x278($sp)
|
|
/* f040b3c: 2401000a */ addiu $at,$zero,0xa
|
|
/* f040b40: 10610007 */ beq $v1,$at,.NB0f040b60
|
|
/* f040b44: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f040b48: 10610005 */ beq $v1,$at,.NB0f040b60
|
|
/* f040b4c: 2401001c */ addiu $at,$zero,0x1c
|
|
/* f040b50: 10610003 */ beq $v1,$at,.NB0f040b60
|
|
/* f040b54: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f040b58: 54610016 */ bnel $v1,$at,.NB0f040bb4
|
|
/* f040b5c: 8fb801f4 */ lw $t8,0x1f4($sp)
|
|
.NB0f040b60:
|
|
/* f040b60: 8dcee6c8 */ lw $t6,-0x1938($t6)
|
|
/* f040b64: 10000012 */ beqz $zero,.NB0f040bb0
|
|
/* f040b68: ad6e0048 */ sw $t6,0x48($t3)
|
|
.NB0f040b6c:
|
|
/* f040b6c: 8fad0278 */ lw $t5,0x278($sp)
|
|
/* f040b70: 24010008 */ addiu $at,$zero,0x8
|
|
/* f040b74: 3c0a800a */ lui $t2,0x800a
|
|
/* f040b78: 81a30007 */ lb $v1,0x7($t5)
|
|
/* f040b7c: 8faf0278 */ lw $t7,0x278($sp)
|
|
/* f040b80: 10610009 */ beq $v1,$at,.NB0f040ba8
|
|
/* f040b84: 2401000a */ addiu $at,$zero,0xa
|
|
/* f040b88: 10610007 */ beq $v1,$at,.NB0f040ba8
|
|
/* f040b8c: 2401001b */ addiu $at,$zero,0x1b
|
|
/* f040b90: 10610005 */ beq $v1,$at,.NB0f040ba8
|
|
/* f040b94: 2401001c */ addiu $at,$zero,0x1c
|
|
/* f040b98: 10610003 */ beq $v1,$at,.NB0f040ba8
|
|
/* f040b9c: 2401001d */ addiu $at,$zero,0x1d
|
|
/* f040ba0: 54610004 */ bnel $v1,$at,.NB0f040bb4
|
|
/* f040ba4: 8fb801f4 */ lw $t8,0x1f4($sp)
|
|
.NB0f040ba8:
|
|
/* f040ba8: 8d4ae6c8 */ lw $t2,-0x1938($t2)
|
|
/* f040bac: adea0048 */ sw $t2,0x48($t7)
|
|
.NB0f040bb0:
|
|
/* f040bb0: 8fb801f4 */ lw $t8,0x1f4($sp)
|
|
.NB0f040bb4:
|
|
/* f040bb4: 8fad01cc */ lw $t5,0x1cc($sp)
|
|
/* f040bb8: 13000065 */ beqz $t8,.NB0f040d50
|
|
/* f040bbc: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040bc0: 0fc2bea2 */ jal gsetGetDamage
|
|
/* f040bc4: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f040bc8: 8fae025c */ lw $t6,0x25c($sp)
|
|
/* f040bcc: 2419ffff */ addiu $t9,$zero,-1
|
|
/* f040bd0: 240c00c8 */ addiu $t4,$zero,0xc8
|
|
/* f040bd4: e7a0009c */ swc1 $f0,0x9c($sp)
|
|
/* f040bd8: afa00098 */ sw $zero,0x98($sp)
|
|
/* f040bdc: afa00094 */ sw $zero,0x94($sp)
|
|
/* f040be0: afb90090 */ sw $t9,0x90($sp)
|
|
/* f040be4: afac008c */ sw $t4,0x8c($sp)
|
|
/* f040be8: 8dcb0004 */ lw $t3,0x4($t6)
|
|
/* f040bec: afab0088 */ sw $t3,0x88($sp)
|
|
/* f040bf0: c5c60008 */ lwc1 $f6,0x8($t6)
|
|
/* f040bf4: e7a60228 */ swc1 $f6,0x228($sp)
|
|
/* f040bf8: c5c4000c */ lwc1 $f4,0xc($t6)
|
|
/* f040bfc: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
/* f040c00: c5ca0010 */ lwc1 $f10,0x10($t6)
|
|
/* f040c04: 0c004d84 */ jal random
|
|
/* f040c08: e7aa0230 */ swc1 $f10,0x230($sp)
|
|
/* f040c0c: 304d0001 */ andi $t5,$v0,0x1
|
|
/* f040c10: 11a00012 */ beqz $t5,.NB0f040c5c
|
|
/* f040c14: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040c18: 0c004d84 */ jal random
|
|
/* f040c1c: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040c20: 2401000a */ addiu $at,$zero,0xa
|
|
/* f040c24: 0041001b */ divu $zero,$v0,$at
|
|
/* f040c28: 00005010 */ mfhi $t2
|
|
/* f040c2c: 254f0002 */ addiu $t7,$t2,0x2
|
|
/* f040c30: 448f9000 */ mtc1 $t7,$f18
|
|
/* f040c34: c7b0022c */ lwc1 $f16,0x22c($sp)
|
|
/* f040c38: 05e10005 */ bgez $t7,.NB0f040c50
|
|
/* f040c3c: 46809220 */ cvt.s.w $f8,$f18
|
|
/* f040c40: 3c014f80 */ lui $at,0x4f80
|
|
/* f040c44: 44813000 */ mtc1 $at,$f6
|
|
/* f040c48: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040c4c: 46064200 */ add.s $f8,$f8,$f6
|
|
.NB0f040c50:
|
|
/* f040c50: 46088100 */ add.s $f4,$f16,$f8
|
|
/* f040c54: 10000011 */ beqz $zero,.NB0f040c9c
|
|
/* f040c58: e7a4022c */ swc1 $f4,0x22c($sp)
|
|
.NB0f040c5c:
|
|
/* f040c5c: 0c004d84 */ jal random
|
|
/* f040c60: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040c64: 2401000a */ addiu $at,$zero,0xa
|
|
/* f040c68: 0041001b */ divu $zero,$v0,$at
|
|
/* f040c6c: 0000c010 */ mfhi $t8
|
|
/* f040c70: 27190002 */ addiu $t9,$t8,0x2
|
|
/* f040c74: 44999000 */ mtc1 $t9,$f18
|
|
/* f040c78: c7aa022c */ lwc1 $f10,0x22c($sp)
|
|
/* f040c7c: 07210005 */ bgez $t9,.NB0f040c94
|
|
/* f040c80: 468091a0 */ cvt.s.w $f6,$f18
|
|
/* f040c84: 3c014f80 */ lui $at,0x4f80
|
|
/* f040c88: 44818000 */ mtc1 $at,$f16
|
|
/* f040c8c: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040c90: 46103180 */ add.s $f6,$f6,$f16
|
|
.NB0f040c94:
|
|
/* f040c94: 46065201 */ sub.s $f8,$f10,$f6
|
|
/* f040c98: e7a8022c */ swc1 $f8,0x22c($sp)
|
|
.NB0f040c9c:
|
|
/* f040c9c: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f040ca0: 8fa5025c */ lw $a1,0x25c($sp)
|
|
/* f040ca4: 0fc296b1 */ jal bgunPlayPropHitSound
|
|
/* f040ca8: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f040cac: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f040cb0: 8c8c0020 */ lw $t4,0x20($a0)
|
|
/* f040cb4: 51800012 */ beqzl $t4,.NB0f040d00
|
|
/* f040cb8: 8faa0278 */ lw $t2,0x278($sp)
|
|
/* f040cbc: 0fc0ce2a */ jal chrGetShield
|
|
/* f040cc0: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040cc4: 44802000 */ mtc1 $zero,$f4
|
|
/* f040cc8: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f040ccc: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f040cd0: 4600203c */ c.lt.s $f4,$f0
|
|
/* f040cd4: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f040cd8: 27a70098 */ addiu $a3,$sp,0x98
|
|
/* f040cdc: 27ab008c */ addiu $t3,$sp,0x8c
|
|
/* f040ce0: 45000006 */ bc1f .NB0f040cfc
|
|
/* f040ce4: 27ae0094 */ addiu $t6,$sp,0x94
|
|
/* f040ce8: 27ad0090 */ addiu $t5,$sp,0x90
|
|
/* f040cec: afad0018 */ sw $t5,0x18($sp)
|
|
/* f040cf0: afab0010 */ sw $t3,0x10($sp)
|
|
/* f040cf4: 0fc0fdc8 */ jal chrCalculateShieldHit
|
|
/* f040cf8: afae0014 */ sw $t6,0x14($sp)
|
|
.NB0f040cfc:
|
|
/* f040cfc: 8faa0278 */ lw $t2,0x278($sp)
|
|
.NB0f040d00:
|
|
/* f040d00: 8fb9025c */ lw $t9,0x25c($sp)
|
|
/* f040d04: 8fac0098 */ lw $t4,0x98($sp)
|
|
/* f040d08: 8d4f001c */ lw $t7,0x1c($t2)
|
|
/* f040d0c: 8fab0094 */ lw $t3,0x94($sp)
|
|
/* f040d10: 8fae0090 */ lw $t6,0x90($sp)
|
|
/* f040d14: 241800c8 */ addiu $t8,$zero,0xc8
|
|
/* f040d18: 8fa40088 */ lw $a0,0x88($sp)
|
|
/* f040d1c: afb80014 */ sw $t8,0x14($sp)
|
|
/* f040d20: afa00028 */ sw $zero,0x28($sp)
|
|
/* f040d24: 8fa5009c */ lw $a1,0x9c($sp)
|
|
/* f040d28: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f040d2c: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f040d30: afb90018 */ sw $t9,0x18($sp)
|
|
/* f040d34: afac001c */ sw $t4,0x1c($sp)
|
|
/* f040d38: afaf0010 */ sw $t7,0x10($sp)
|
|
/* f040d3c: afab0020 */ sw $t3,0x20($sp)
|
|
/* f040d40: 0fc0ceb9 */ jal func0f0341dc
|
|
/* f040d44: afae0024 */ sw $t6,0x24($sp)
|
|
/* f040d48: 10000010 */ beqz $zero,.NB0f040d8c
|
|
/* f040d4c: 8faa01f0 */ lw $t2,0x1f0($sp)
|
|
.NB0f040d50:
|
|
/* f040d50: 11a00006 */ beqz $t5,.NB0f040d6c
|
|
/* f040d54: c7b201d0 */ lwc1 $f18,0x1d0($sp)
|
|
/* f040d58: 91a20000 */ lbu $v0,0x0($t5)
|
|
/* f040d5c: 24010003 */ addiu $at,$zero,0x3
|
|
/* f040d60: 10410009 */ beq $v0,$at,.NB0f040d88
|
|
/* f040d64: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040d68: 10410007 */ beq $v0,$at,.NB0f040d88
|
|
.NB0f040d6c:
|
|
/* f040d6c: 3c017f1a */ lui $at,0x7f1a
|
|
/* f040d70: c4303410 */ lwc1 $f16,0x3410($at)
|
|
/* f040d74: 4610903c */ c.lt.s $f18,$f16
|
|
/* f040d78: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040d7c: 45020003 */ bc1fl .NB0f040d8c
|
|
/* f040d80: 8faa01f0 */ lw $t2,0x1f0($sp)
|
|
/* f040d84: afa001f0 */ sw $zero,0x1f0($sp)
|
|
.NB0f040d88:
|
|
/* f040d88: 8faa01f0 */ lw $t2,0x1f0($sp)
|
|
.NB0f040d8c:
|
|
/* f040d8c: 8faf01cc */ lw $t7,0x1cc($sp)
|
|
/* f040d90: 514000e5 */ beqzl $t2,.NB0f041128
|
|
/* f040d94: 8fac01c0 */ lw $t4,0x1c0($sp)
|
|
/* f040d98: 11e000a2 */ beqz $t7,.NB0f041024
|
|
/* f040d9c: 8fac0224 */ lw $t4,0x224($sp)
|
|
/* f040da0: 91e20000 */ lbu $v0,0x0($t7)
|
|
/* f040da4: 24010006 */ addiu $at,$zero,0x6
|
|
/* f040da8: 93b8026f */ lbu $t8,0x26f($sp)
|
|
/* f040dac: 10410003 */ beq $v0,$at,.NB0f040dbc
|
|
/* f040db0: 24010003 */ addiu $at,$zero,0x3
|
|
/* f040db4: 54410053 */ bnel $v0,$at,.NB0f040f04
|
|
/* f040db8: 24010001 */ addiu $at,$zero,0x1
|
|
.NB0f040dbc:
|
|
/* f040dbc: 1700000c */ bnez $t8,.NB0f040df0
|
|
/* f040dc0: 8fb901bc */ lw $t9,0x1bc($sp)
|
|
/* f040dc4: 1720000a */ bnez $t9,.NB0f040df0
|
|
/* f040dc8: 8fac0278 */ lw $t4,0x278($sp)
|
|
/* f040dcc: 8d8b0018 */ lw $t3,0x18($t4)
|
|
/* f040dd0: 8fad01cc */ lw $t5,0x1cc($sp)
|
|
/* f040dd4: 01802825 */ or $a1,$t4,$zero
|
|
/* f040dd8: 316e0040 */ andi $t6,$t3,0x40
|
|
/* f040ddc: 11c00045 */ beqz $t6,.NB0f040ef4
|
|
/* f040de0: 24060002 */ addiu $a2,$zero,0x2
|
|
/* f040de4: 0fc1279f */ jal chrCompareTeams
|
|
/* f040de8: 8da40004 */ lw $a0,0x4($t5)
|
|
/* f040dec: 10400041 */ beqz $v0,.NB0f040ef4
|
|
.NB0f040df0:
|
|
/* f040df0: 240affff */ addiu $t2,$zero,-1
|
|
/* f040df4: 240f00c8 */ addiu $t7,$zero,0xc8
|
|
/* f040df8: afa00084 */ sw $zero,0x84($sp)
|
|
/* f040dfc: afa00080 */ sw $zero,0x80($sp)
|
|
/* f040e00: afaa007c */ sw $t2,0x7c($sp)
|
|
/* f040e04: afaf0078 */ sw $t7,0x78($sp)
|
|
/* f040e08: 0fc2bea2 */ jal gsetGetDamage
|
|
/* f040e0c: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f040e10: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f040e14: e7a00074 */ swc1 $f0,0x74($sp)
|
|
/* f040e18: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f040e1c: 8cb90004 */ lw $t9,0x4($a1)
|
|
/* f040e20: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f040e24: 0fc296b1 */ jal bgunPlayPropHitSound
|
|
/* f040e28: afb90070 */ sw $t9,0x70($sp)
|
|
/* f040e2c: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f040e30: 8c8b0020 */ lw $t3,0x20($a0)
|
|
/* f040e34: 51600012 */ beqzl $t3,.NB0f040e80
|
|
/* f040e38: 8faf0278 */ lw $t7,0x278($sp)
|
|
/* f040e3c: 0fc0ce2a */ jal chrGetShield
|
|
/* f040e40: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040e44: 44805000 */ mtc1 $zero,$f10
|
|
/* f040e48: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f040e4c: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f040e50: 4600503c */ c.lt.s $f10,$f0
|
|
/* f040e54: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f040e58: 27a70084 */ addiu $a3,$sp,0x84
|
|
/* f040e5c: 27ae0078 */ addiu $t6,$sp,0x78
|
|
/* f040e60: 45000006 */ bc1f .NB0f040e7c
|
|
/* f040e64: 27ad0080 */ addiu $t5,$sp,0x80
|
|
/* f040e68: 27ac007c */ addiu $t4,$sp,0x7c
|
|
/* f040e6c: afac0018 */ sw $t4,0x18($sp)
|
|
/* f040e70: afae0010 */ sw $t6,0x10($sp)
|
|
/* f040e74: 0fc0fdc8 */ jal chrCalculateShieldHit
|
|
/* f040e78: afad0014 */ sw $t5,0x14($sp)
|
|
.NB0f040e7c:
|
|
/* f040e7c: 8faf0278 */ lw $t7,0x278($sp)
|
|
.NB0f040e80:
|
|
/* f040e80: 27aa01e0 */ addiu $t2,$sp,0x1e0
|
|
/* f040e84: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f040e88: afaa0010 */ sw $t2,0x10($sp)
|
|
/* f040e8c: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f040e90: 8fa60078 */ lw $a2,0x78($sp)
|
|
/* f040e94: 27a70228 */ addiu $a3,$sp,0x228
|
|
/* f040e98: 0fc09630 */ jal chrEmitSparks
|
|
/* f040e9c: afaf0014 */ sw $t7,0x14($sp)
|
|
/* f040ea0: 8fb90278 */ lw $t9,0x278($sp)
|
|
/* f040ea4: 8fae01cc */ lw $t6,0x1cc($sp)
|
|
/* f040ea8: 8fad0084 */ lw $t5,0x84($sp)
|
|
/* f040eac: 8f38001c */ lw $t8,0x1c($t9)
|
|
/* f040eb0: 8fac0080 */ lw $t4,0x80($sp)
|
|
/* f040eb4: 8faa007c */ lw $t2,0x7c($sp)
|
|
/* f040eb8: 240b00c8 */ addiu $t3,$zero,0xc8
|
|
/* f040ebc: afab0014 */ sw $t3,0x14($sp)
|
|
/* f040ec0: afa00028 */ sw $zero,0x28($sp)
|
|
/* f040ec4: 8fa40070 */ lw $a0,0x70($sp)
|
|
/* f040ec8: 8fa50074 */ lw $a1,0x74($sp)
|
|
/* f040ecc: 27a601e0 */ addiu $a2,$sp,0x1e0
|
|
/* f040ed0: 27a70260 */ addiu $a3,$sp,0x260
|
|
/* f040ed4: afae0018 */ sw $t6,0x18($sp)
|
|
/* f040ed8: afad001c */ sw $t5,0x1c($sp)
|
|
/* f040edc: afb80010 */ sw $t8,0x10($sp)
|
|
/* f040ee0: afac0020 */ sw $t4,0x20($sp)
|
|
/* f040ee4: 0fc0ceb9 */ jal func0f0341dc
|
|
/* f040ee8: afaa0024 */ sw $t2,0x24($sp)
|
|
/* f040eec: 1000006f */ beqz $zero,.NB0f0410ac
|
|
/* f040ef0: 93b90260 */ lbu $t9,0x260($sp)
|
|
.NB0f040ef4:
|
|
/* f040ef4: afa00250 */ sw $zero,0x250($sp)
|
|
/* f040ef8: 1000006b */ beqz $zero,.NB0f0410a8
|
|
/* f040efc: afa00268 */ sw $zero,0x268($sp)
|
|
/* f040f00: 24010001 */ addiu $at,$zero,0x1
|
|
.NB0f040f04:
|
|
/* f040f04: 10410005 */ beq $v0,$at,.NB0f040f1c
|
|
/* f040f08: 8faf01cc */ lw $t7,0x1cc($sp)
|
|
/* f040f0c: 24010004 */ addiu $at,$zero,0x4
|
|
/* f040f10: 10410002 */ beq $v0,$at,.NB0f040f1c
|
|
/* f040f14: 24010002 */ addiu $at,$zero,0x2
|
|
/* f040f18: 14410063 */ bne $v0,$at,.NB0f0410a8
|
|
.NB0f040f1c:
|
|
/* f040f1c: 3c0b800a */ lui $t3,0x800a
|
|
/* f040f20: 8d6be9d4 */ lw $t3,-0x162c($t3)
|
|
/* f040f24: 8df90004 */ lw $t9,0x4($t7)
|
|
/* f040f28: 2418ffff */ addiu $t8,$zero,-1
|
|
/* f040f2c: afb80068 */ sw $t8,0x68($sp)
|
|
/* f040f30: 11600004 */ beqz $t3,.NB0f040f44
|
|
/* f040f34: afb9006c */ sw $t9,0x6c($sp)
|
|
/* f040f38: 0fc61c7f */ jal mpPlayerGetIndex
|
|
/* f040f3c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040f40: afa20068 */ sw $v0,0x68($sp)
|
|
.NB0f040f44:
|
|
/* f040f44: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f040f48: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f040f4c: 0fc296b1 */ jal bgunPlayPropHitSound
|
|
/* f040f50: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f040f54: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f040f58: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f040f5c: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f040f60: 0fc19437 */ jal func0f065e74
|
|
/* f040f64: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f040f68: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f040f6c: afae0210 */ sw $t6,0x210($sp)
|
|
/* f040f70: 0fc4e3ea */ jal chrIsUsingPaintball
|
|
/* f040f74: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f040f78: 1040000b */ beqz $v0,.NB0f040fa8
|
|
/* f040f7c: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f040f80: 240d0019 */ addiu $t5,$zero,0x19
|
|
/* f040f84: afad0014 */ sw $t5,0x14($sp)
|
|
/* f040f88: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f040f8c: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f040f90: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f040f94: 00003825 */ or $a3,$zero,$zero
|
|
/* f040f98: 0fc4a960 */ jal sparksCreate
|
|
/* f040f9c: afa00010 */ sw $zero,0x10($sp)
|
|
/* f040fa0: 10000007 */ beqz $zero,.NB0f040fc0
|
|
/* f040fa4: 00000000 */ sll $zero,$zero,0x0
|
|
.NB0f040fa8:
|
|
/* f040fa8: 8fa501cc */ lw $a1,0x1cc($sp)
|
|
/* f040fac: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f040fb0: 00003825 */ or $a3,$zero,$zero
|
|
/* f040fb4: afa00010 */ sw $zero,0x10($sp)
|
|
/* f040fb8: 0fc4a960 */ jal sparksCreate
|
|
/* f040fbc: afa00014 */ sw $zero,0x14($sp)
|
|
.NB0f040fc0:
|
|
/* f040fc0: 3c0c800a */ lui $t4,0x800a
|
|
/* f040fc4: 818a27ab */ lb $t2,0x27ab($t4)
|
|
/* f040fc8: 8faf0278 */ lw $t7,0x278($sp)
|
|
/* f040fcc: 0541000a */ bgez $t2,.NB0f040ff8
|
|
/* f040fd0: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040fd4: 91f90125 */ lbu $t9,0x125($t7)
|
|
/* f040fd8: 24010010 */ addiu $at,$zero,0x10
|
|
/* f040fdc: 8fb8006c */ lw $t8,0x6c($sp)
|
|
/* f040fe0: 17210005 */ bne $t9,$at,.NB0f040ff8
|
|
/* f040fe4: 00000000 */ sll $zero,$zero,0x0
|
|
/* f040fe8: 8f0b000c */ lw $t3,0xc($t8)
|
|
/* f040fec: 316e0001 */ andi $t6,$t3,0x1
|
|
/* f040ff0: 55c0002e */ bnezl $t6,.NB0f0410ac
|
|
/* f040ff4: 93b90260 */ lbu $t9,0x260($sp)
|
|
.NB0f040ff8:
|
|
/* f040ff8: 0fc2bea2 */ jal gsetGetDamage
|
|
/* f040ffc: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041000: 8fad0068 */ lw $t5,0x68($sp)
|
|
/* f041004: 44050000 */ mfc1 $a1,$f0
|
|
/* f041008: 8fa4006c */ lw $a0,0x6c($sp)
|
|
/* f04100c: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041010: 93a70260 */ lbu $a3,0x260($sp)
|
|
/* f041014: 0fc20ebd */ jal objTakeGunfire
|
|
/* f041018: afad0010 */ sw $t5,0x10($sp)
|
|
/* f04101c: 10000023 */ beqz $zero,.NB0f0410ac
|
|
/* f041020: 93b90260 */ lbu $t9,0x260($sp)
|
|
.NB0f041024:
|
|
/* f041024: 11800020 */ beqz $t4,.NB0f0410a8
|
|
/* f041028: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f04102c: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f041030: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041034: 0fc19437 */ jal func0f065e74
|
|
/* f041038: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f04103c: 240a0001 */ addiu $t2,$zero,0x1
|
|
/* f041040: afaa0210 */ sw $t2,0x210($sp)
|
|
/* f041044: 27a40260 */ addiu $a0,$sp,0x260
|
|
/* f041048: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f04104c: 2406ffff */ addiu $a2,$zero,-1
|
|
/* f041050: 0fc298a8 */ jal bgunPlayBgHitSound
|
|
/* f041054: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041058: 0fc4e3ea */ jal chrIsUsingPaintball
|
|
/* f04105c: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041060: 1040000b */ beqz $v0,.NB0f041090
|
|
/* f041064: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f041068: 240f0019 */ addiu $t7,$zero,0x19
|
|
/* f04106c: afaf0014 */ sw $t7,0x14($sp)
|
|
/* f041070: 87a40214 */ lh $a0,0x214($sp)
|
|
/* f041074: 00002825 */ or $a1,$zero,$zero
|
|
/* f041078: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f04107c: 00003825 */ or $a3,$zero,$zero
|
|
/* f041080: 0fc4a960 */ jal sparksCreate
|
|
/* f041084: afa00010 */ sw $zero,0x10($sp)
|
|
/* f041088: 10000008 */ beqz $zero,.NB0f0410ac
|
|
/* f04108c: 93b90260 */ lbu $t9,0x260($sp)
|
|
.NB0f041090:
|
|
/* f041090: 00002825 */ or $a1,$zero,$zero
|
|
/* f041094: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f041098: 00003825 */ or $a3,$zero,$zero
|
|
/* f04109c: afa00010 */ sw $zero,0x10($sp)
|
|
/* f0410a0: 0fc4a960 */ jal sparksCreate
|
|
/* f0410a4: afa00014 */ sw $zero,0x14($sp)
|
|
.NB0f0410a8:
|
|
/* f0410a8: 93b90260 */ lbu $t9,0x260($sp)
|
|
.NB0f0410ac:
|
|
/* f0410ac: 24010007 */ addiu $at,$zero,0x7
|
|
/* f0410b0: 93b80263 */ lbu $t8,0x263($sp)
|
|
/* f0410b4: 1721001b */ bne $t9,$at,.NB0f041124
|
|
/* f0410b8: 24010001 */ addiu $at,$zero,0x1
|
|
/* f0410bc: 17010019 */ bne $t8,$at,.NB0f041124
|
|
/* f0410c0: 8fab0278 */ lw $t3,0x278($sp)
|
|
/* f0410c4: 8d6e02d4 */ lw $t6,0x2d4($t3)
|
|
/* f0410c8: 3c03800a */ lui $v1,0x800a
|
|
/* f0410cc: 11c00005 */ beqz $t6,.NB0f0410e4
|
|
/* f0410d0: 00000000 */ sll $zero,$zero,0x0
|
|
/* f0410d4: 0fc61c7f */ jal mpPlayerGetIndex
|
|
/* f0410d8: 01602025 */ or $a0,$t3,$zero
|
|
/* f0410dc: 10000002 */ beqz $zero,.NB0f0410e8
|
|
/* f0410e0: 00401825 */ or $v1,$v0,$zero
|
|
.NB0f0410e4:
|
|
/* f0410e4: 8c63e94c */ lw $v1,-0x16b4($v1)
|
|
.NB0f0410e8:
|
|
/* f0410e8: 8fad0210 */ lw $t5,0x210($sp)
|
|
/* f0410ec: 27a40244 */ addiu $a0,$sp,0x244
|
|
/* f0410f0: 27a50234 */ addiu $a1,$sp,0x234
|
|
/* f0410f4: 15a00005 */ bnez $t5,.NB0f04110c
|
|
/* f0410f8: 27a60228 */ addiu $a2,$sp,0x228
|
|
/* f0410fc: 27a70214 */ addiu $a3,$sp,0x214
|
|
/* f041100: 0fc19437 */ jal func0f065e74
|
|
/* f041104: afa30064 */ sw $v1,0x64($sp)
|
|
/* f041108: 8fa30064 */ lw $v1,0x64($sp)
|
|
.NB0f04110c:
|
|
/* f04110c: 00002025 */ or $a0,$zero,$zero
|
|
/* f041110: 27a50228 */ addiu $a1,$sp,0x228
|
|
/* f041114: 27a60214 */ addiu $a2,$sp,0x214
|
|
/* f041118: 24070016 */ addiu $a3,$zero,0x16
|
|
/* f04111c: 0fc49158 */ jal explosionCreateSimple
|
|
/* f041120: afa30010 */ sw $v1,0x10($sp)
|
|
.NB0f041124:
|
|
/* f041124: 8fac01c0 */ lw $t4,0x1c0($sp)
|
|
.NB0f041128:
|
|
/* f041128: 8fa4025c */ lw $a0,0x25c($sp)
|
|
/* f04112c: 51800004 */ beqzl $t4,.NB0f041140
|
|
/* f041130: 8fa80268 */ lw $t0,0x268($sp)
|
|
/* f041134: 0fc18cfb */ jal propSetPerimEnabled
|
|
/* f041138: 00002825 */ or $a1,$zero,$zero
|
|
/* f04113c: 8fa80268 */ lw $t0,0x268($sp)
|
|
.NB0f041140:
|
|
/* f041140: 8faf0250 */ lw $t7,0x250($sp)
|
|
/* f041144: 93b90260 */ lbu $t9,0x260($sp)
|
|
/* f041148: 0008502b */ sltu $t2,$zero,$t0
|
|
/* f04114c: 11e0000e */ beqz $t7,.NB0f041188
|
|
/* f041150: 01404025 */ or $t0,$t2,$zero
|
|
/* f041154: 2738fffe */ addiu $t8,$t9,-2
|
|
/* f041158: 2f01002a */ sltiu $at,$t8,0x2a
|
|
/* f04115c: 10200009 */ beqz $at,.NB0f041184
|
|
/* f041160: 0018c080 */ sll $t8,$t8,0x2
|
|
/* f041164: 3c017f1a */ lui $at,0x7f1a
|
|
/* f041168: 00380821 */ addu $at,$at,$t8
|
|
/* f04116c: 8c383414 */ lw $t8,0x3414($at)
|
|
/* f041170: 03000008 */ jr $t8
|
|
/* f041174: 00000000 */ sll $zero,$zero,0x0
|
|
/* f041178: 240e0001 */ addiu $t6,$zero,0x1
|
|
/* f04117c: 10000002 */ beqz $zero,.NB0f041188
|
|
/* f041180: afae0250 */ sw $t6,0x250($sp)
|
|
.NB0f041184:
|
|
/* f041184: afa00250 */ sw $zero,0x250($sp)
|
|
.NB0f041188:
|
|
/* f041188: 11000004 */ beqz $t0,.NB0f04119c
|
|
/* f04118c: 01003825 */ or $a3,$t0,$zero
|
|
/* f041190: 8fa70250 */ lw $a3,0x250($sp)
|
|
/* f041194: 0007582b */ sltu $t3,$zero,$a3
|
|
/* f041198: 01603825 */ or $a3,$t3,$zero
|
|
.NB0f04119c:
|
|
/* f04119c: 27ad0244 */ addiu $t5,$sp,0x244
|
|
/* f0411a0: 27ac0228 */ addiu $t4,$sp,0x228
|
|
/* f0411a4: afac0014 */ sw $t4,0x14($sp)
|
|
/* f0411a8: afad0010 */ sw $t5,0x10($sp)
|
|
/* f0411ac: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0411b0: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f0411b4: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f0411b8: 0fc0f6a6 */ jal chrCreateFireslot
|
|
/* f0411bc: afa80054 */ sw $t0,0x54($sp)
|
|
/* f0411c0: 93aa026f */ lbu $t2,0x26f($sp)
|
|
/* f0411c4: 8fa80054 */ lw $t0,0x54($sp)
|
|
/* f0411c8: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f0411cc: 11400015 */ beqz $t2,.NB0f041224
|
|
/* f0411d0: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f0411d4: 1100000a */ beqz $t0,.NB0f041200
|
|
/* f0411d8: 01003025 */ or $a2,$t0,$zero
|
|
/* f0411dc: 8faf0278 */ lw $t7,0x278($sp)
|
|
/* f0411e0: 8fb8027c */ lw $t8,0x27c($sp)
|
|
/* f0411e4: 8df902d4 */ lw $t9,0x2d4($t7)
|
|
/* f0411e8: 00187080 */ sll $t6,$t8,0x2
|
|
/* f0411ec: 032e1021 */ addu $v0,$t9,$t6
|
|
/* f0411f0: 8c430024 */ lw $v1,0x24($v0)
|
|
/* f0411f4: 18600002 */ blez $v1,.NB0f041200
|
|
/* f0411f8: 246bffff */ addiu $t3,$v1,-1
|
|
/* f0411fc: ac4b0024 */ sw $t3,0x24($v0)
|
|
.NB0f041200:
|
|
/* f041200: 11000004 */ beqz $t0,.NB0f041214
|
|
/* f041204: 8fa40278 */ lw $a0,0x278($sp)
|
|
/* f041208: 93a6026e */ lbu $a2,0x26e($sp)
|
|
/* f04120c: 0006682b */ sltu $t5,$zero,$a2
|
|
/* f041210: 01a03025 */ or $a2,$t5,$zero
|
|
.NB0f041214:
|
|
/* f041214: 0fc0fc0f */ jal chrSetFiring
|
|
/* f041218: 8fa5027c */ lw $a1,0x27c($sp)
|
|
/* f04121c: 10000004 */ beqz $zero,.NB0f041230
|
|
/* f041220: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.NB0f041224:
|
|
/* f041224: 0fc0fc0f */ jal chrSetFiring
|
|
/* f041228: 8fa60268 */ lw $a2,0x268($sp)
|
|
/* f04122c: 8fbf0044 */ lw $ra,0x44($sp)
|
|
.NB0f041230:
|
|
/* f041230: 27bd0278 */ addiu $sp,$sp,0x278
|
|
/* f041234: 03e00008 */ jr $ra
|
|
/* f041238: 00000000 */ sll $zero,$zero,0x0
|
|
);
|
|
#endif
|
|
#else
|
|
/**
|
|
* Fire the chr's gun, check what was hit and do all the appropriate things such
|
|
* as dealing damage, creating beams and sparks and playing sounds.
|
|
*
|
|
* This should be called on every tick while the chr is shooting. The function
|
|
* takes care of the gun's fire rate.
|
|
*/
|
|
// Mismatches:
|
|
// - near botactShootFarsight, chr needs to be loaded into t3 which
|
|
// should solve instruction ordering.
|
|
// - Float calculations near 65536 have diffent codegen
|
|
// - Calculation of sp168 and spcc have reordered instructions
|
|
// - Calculate of xdiff/ydiff/zdiff prior to chrCalculateHit is different
|
|
void chrShoot(struct chrdata *chr, s32 handnum)
|
|
{
|
|
struct prop *chrprop = chr->prop; // 274
|
|
struct prop *gunprop;
|
|
u8 isaibot = false; // 26f
|
|
u8 normalshoot = true; // 26e
|
|
|
|
if (chr->aibot) {
|
|
isaibot = true;
|
|
}
|
|
|
|
gunprop = chrGetHeldProp(chr, handnum);
|
|
|
|
if (gunprop) {
|
|
bool firingthistick = false;
|
|
struct weaponobj *weapon = gunprop->weapon; // 264
|
|
struct gset gset; // 260
|
|
struct prop *targetprop = chrGetTargetProp(chr); // 25c
|
|
u32 attackflags;
|
|
bool shotdue; // 254
|
|
bool makebeam; // 250
|
|
struct coord gunpos; // 244
|
|
s16 gunrooms[8]; // 234
|
|
struct coord hitpos; // 228
|
|
bool hitsomething; // 224
|
|
s16 hitrooms[8]; // 214
|
|
bool sp210;
|
|
s32 tickspershot;
|
|
f32 sp208; // unused?
|
|
|
|
gset = weapon->gset;
|
|
attackflags = ATTACKFLAG_AIMATTARGET;
|
|
|
|
if (chr->actiontype == ACT_ATTACK
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTAND
|
|
|| chr->actiontype == ACT_BOT_ATTACKKNEEL
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTRAFE) {
|
|
attackflags = chr->act_attack.flags;
|
|
}
|
|
|
|
shotdue = false;
|
|
makebeam = false;
|
|
hitsomething = false;
|
|
sp210 = false;
|
|
|
|
// Most guns can fire at most once every few ticks - even automatics.
|
|
// The chr's firecount property tracks how many ticks have elapsed since
|
|
// the last bullet, which is used to determine if another bullet should
|
|
// be discharged on this tick.
|
|
tickspershot = weaponGetNumTicksPerShot(gset.weaponnum, gset.weaponfunc);
|
|
|
|
if (tickspershot <= 0) {
|
|
shotdue = true;
|
|
makebeam = true;
|
|
} else {
|
|
if (chr->aibot
|
|
&& chr->aibot->weaponnum == WEAPON_REAPER
|
|
&& chr->aibot->gunfunc == FUNC_PRIMARY) {
|
|
sp208 = (TICKS(90) - chr->aibot->reaperspeed[handnum]);
|
|
sp208 *= 1.0f / 1.8f;
|
|
tickspershot *= sp208 + 1;
|
|
}
|
|
|
|
chr->firecount[handnum] += g_Vars.lvupdate240_60;
|
|
|
|
if (chr->firecount[handnum] >= tickspershot) {
|
|
chr->firecount[handnum] = 0;
|
|
chr->unk32c_12 ^= 1 << handnum;
|
|
|
|
shotdue = true;
|
|
|
|
if ((chr->unk32c_12 & (1 << handnum)) || gset.weaponnum == WEAPON_LASER) {
|
|
makebeam = true;
|
|
}
|
|
|
|
if (chr->actiontype == ACT_ATTACK) {
|
|
if (modelGetAnimNum(chr->model) == ANIM_SNIPING_ONGROUND) {
|
|
chr->act_attack.numshots++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (shotdue) {
|
|
f32 aimangle = chrGetAimAngle(chr);
|
|
f32 sp200 = func0f03e754(chr);
|
|
bool sp1fc = isaibot ? CDTYPE_PLAYERS : 0;
|
|
|
|
firingthistick = true;
|
|
|
|
if (!chrGetGunPos(chr, handnum, &gunpos)) {
|
|
// Gun is off screen - use a quick but inexact calculation
|
|
gunpos.f[0] = chrprop->pos.f[0];
|
|
gunpos.f[1] = chrprop->pos.f[1] + 30;
|
|
gunpos.f[2] = chrprop->pos.f[2];
|
|
|
|
if (handnum == HAND_LEFT) {
|
|
gunpos.f[0] += cosf(aimangle) * 10;
|
|
gunpos.f[2] += -sinf(aimangle) * 10;
|
|
} else {
|
|
gunpos.f[0] += -cosf(aimangle) * 10;
|
|
gunpos.f[2] += sinf(aimangle) * 10;
|
|
}
|
|
}
|
|
|
|
// Check that the chr isn't clipping their gun through anything such
|
|
// as another chr or a closed door. If they are, the shot won't be
|
|
// taken because that wouldn't be fair.
|
|
// How nice of the developers to check for this!
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
if (cd0002de34(&chrprop->pos, chrprop->rooms, &gunpos, gunrooms,
|
|
CDTYPE_DOORS | CDTYPE_CHRS | CDTYPE_BG | CDTYPE_DOORSWITHOUTFLAG | sp1fc,
|
|
0x10) == CDRESULT_COLLISION) {
|
|
firingthistick = false;
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
|
|
if (firingthistick) {
|
|
bool angleok = false; // 1f8
|
|
bool hitplayer = false; // 1f4
|
|
bool effective = true; // 1f0
|
|
u32 sp1ec;
|
|
struct coord vector; // 1e0
|
|
f32 xdiff;
|
|
f32 ydiff;
|
|
f32 zdiff;
|
|
f32 sqshotdist; // 1d0
|
|
struct prop *hitprop = NULL; // 1cc
|
|
u32 sp1c8 = isaibot
|
|
? CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_CHRS | CDTYPE_PATHBLOCKER | CDTYPE_BG | CDTYPE_DOORSWITHOUTFLAG | CDTYPE_PLAYERS
|
|
: CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_CHRS | CDTYPE_PATHBLOCKER | CDTYPE_BG | CDTYPE_DOORSWITHOUTFLAG;
|
|
u32 sp1c4;
|
|
bool isshootingeyespy = CHRRACE(targetprop->chr) == RACE_EYESPY && chrGetDistanceToTarget(chr) > 150; // 1c0
|
|
bool fudgeforeyespy = false; // 1bc
|
|
|
|
if (isshootingeyespy) {
|
|
vector.f[0] = xdiff = targetprop->pos.f[0] - gunpos.f[0];
|
|
vector.f[1] = ydiff = targetprop->pos.f[1] - gunpos.f[1];
|
|
vector.f[2] = zdiff = targetprop->pos.f[2] - gunpos.f[2];
|
|
|
|
guNormalize(&vector.f[0], &vector.f[1], &vector.f[2]);
|
|
propSetPerimEnabled(targetprop, true);
|
|
} else {
|
|
vector.f[0] = cosf(sp200) * sinf(aimangle);
|
|
vector.f[1] = sinf(sp200);
|
|
vector.f[2] = cosf(sp200) * cosf(aimangle);
|
|
|
|
if (isaibot) {
|
|
bgunCalculateBotShotSpread(&vector, chr->aibot->weaponnum, chr->aibot->gunfunc, chr->aibot->burstsdone[handnum], botGuessCrouchPos(chr), chr->weapons_held[0] && chr->weapons_held[1]);
|
|
}
|
|
}
|
|
|
|
// Handle Farsight shots by aibots specially
|
|
// because they can shoot through walls.
|
|
if (chr->aibot && gset.weaponnum == WEAPON_FARSIGHT && !chr->aibot->targetinsight) {
|
|
makebeam = true;
|
|
|
|
// This function can never return 2 though...
|
|
if (botactShootFarsight(chr, 0, &vector, &gunpos) == 2) {
|
|
normalshoot = random() % 255 > 200;
|
|
}
|
|
}
|
|
|
|
// Check if the shot would hit anything
|
|
hitpos.f[0] = gunpos.f[0] + vector.f[0] * 65536;
|
|
hitpos.f[1] = gunpos.f[1] + vector.f[1] * 65536;
|
|
hitpos.f[2] = gunpos.f[2] + vector.f[2] * 65536;
|
|
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
if (isaibot) {
|
|
g_Vars.useperimshoot = true;
|
|
}
|
|
|
|
if (cdTestAToB4(&gunpos, gunrooms, &hitpos, sp1c8, 0x10) == CDRESULT_COLLISION) {
|
|
hitsomething = true;
|
|
cdGetPos(&hitpos, 12072, "chraction.c");
|
|
hitprop = cdGetObstacle();
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
|
|
if (isaibot) {
|
|
g_Vars.useperimshoot = false;
|
|
}
|
|
|
|
// Eyespy is small and hard to hit, so make it a 50/50 chance
|
|
if (hitprop == NULL && isshootingeyespy) {
|
|
fudgeforeyespy = random() % 100 > 50;
|
|
|
|
if (fudgeforeyespy) {
|
|
hitprop = targetprop;
|
|
|
|
hitpos.x = targetprop->pos.x;
|
|
hitpos.y = targetprop->pos.y;
|
|
hitpos.z = targetprop->pos.z;
|
|
}
|
|
}
|
|
|
|
xdiff = hitpos.x - gunpos.x;
|
|
ydiff = hitpos.y - gunpos.y;
|
|
zdiff = hitpos.z - gunpos.z;
|
|
|
|
sqshotdist = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
|
|
|
|
// Handle projectile launchers specially
|
|
if (gset.weaponnum == WEAPON_ROCKETLAUNCHER
|
|
|| gset.weaponnum == WEAPON_SLAYER
|
|
|| (gset.weaponnum == WEAPON_SUPERDRAGON && gset.weaponfunc == FUNC_SECONDARY)
|
|
|| gset.weaponnum == WEAPON_DEVASTATOR
|
|
|| gset.weaponnum == WEAPON_CROSSBOW
|
|
|| gset.weaponnum == WEAPON_ROCKETLAUNCHER_34) {
|
|
makebeam = false;
|
|
|
|
// AI bots won't fire their projectile weapon in less than
|
|
// 4 metres of space
|
|
if (isaibot || sqshotdist > 400 * 400) {
|
|
struct weaponobj *projectileobj; // 1b8
|
|
Mtxf sp178;
|
|
struct coord sp16c;
|
|
f32 sp168;
|
|
struct coord sp15c;
|
|
Mtxf sp11c;
|
|
Mtxf spdc;
|
|
struct weapon *weapondef = weaponFindById(gset.weaponnum);
|
|
struct weaponfunc_shootprojectile *func = weapondef->functions[gset.weaponfunc]; // d4
|
|
|
|
// Handle creating the projectile
|
|
if (gset.weaponnum == WEAPON_ROCKETLAUNCHER
|
|
|| gset.weaponnum == WEAPON_ROCKETLAUNCHER_34
|
|
|| gset.weaponnum == WEAPON_SLAYER) {
|
|
s32 rockettype = WEAPON_ROCKET;
|
|
|
|
if (func->base.base.flags & FUNCFLAG_HOMINGROCKET) {
|
|
rockettype = WEAPON_HOMINGROCKET;
|
|
}
|
|
|
|
projectileobj = weaponCreateProjectileFromWeaponNum(func->projectilemodelnum, rockettype, chr);
|
|
} else if (gset.weaponnum == WEAPON_CROSSBOW) {
|
|
projectileobj = weaponCreateProjectileFromWeaponNum(func->projectilemodelnum, WEAPON_BOLT, chr);
|
|
|
|
if (projectileobj) {
|
|
projectileobj->gunfunc = gset.weaponfunc;
|
|
}
|
|
} else if (gset.weaponnum == WEAPON_DEVASTATOR) {
|
|
projectileobj = weaponCreateProjectileFromWeaponNum(func->projectilemodelnum, WEAPON_GRENADEROUND, chr);
|
|
|
|
if (projectileobj) {
|
|
projectileobj->gunfunc = gset.weaponfunc;
|
|
}
|
|
} else if (gset.weaponnum == WEAPON_SUPERDRAGON) {
|
|
projectileobj = weaponCreateProjectileFromWeaponNum(func->projectilemodelnum, WEAPON_GRENADEROUND, chr);
|
|
|
|
if (projectileobj) {
|
|
projectileobj->gunfunc = FUNC_2;
|
|
}
|
|
} else {
|
|
// Unreachable
|
|
projectileobj = weaponCreateProjectileFromGset(func->projectilemodelnum, &gset, g_Vars.currentplayer->prop->chr);
|
|
}
|
|
|
|
if (projectileobj) {
|
|
f32 spcc;
|
|
|
|
sp168 = func->unk4c * (1.0f / 0.6f) / 60.0f;
|
|
spcc = func->unk54 * (1.0f / 0.6f);
|
|
|
|
// AI bots are a bit smarter than solo chrs
|
|
// with regard to how they aim their projectiles
|
|
if (isaibot && chrIsTargetInFov(chr, 30, 0)) {
|
|
bool hasaimpos = false;
|
|
f32 tmp1;
|
|
struct coord aimpos; // b8
|
|
|
|
if (gset.weaponfunc == FUNC_PRIMARY &&
|
|
(gset.weaponnum == WEAPON_ROCKETLAUNCHER
|
|
|| gset.weaponnum == WEAPON_ROCKETLAUNCHER_34
|
|
|| gset.weaponnum == WEAPON_SLAYER)) {
|
|
if (targetprop->type == PROPTYPE_CHR || targetprop->type == PROPTYPE_PLAYER) {
|
|
// Rockets - aim at target's feet
|
|
aimpos.f[0] = targetprop->pos.f[0];
|
|
aimpos.f[1] = targetprop->chr->manground;
|
|
aimpos.f[2] = targetprop->pos.f[2];
|
|
|
|
vector.f[0] = aimpos.f[0] - gunpos.f[0];
|
|
vector.f[1] = aimpos.f[1] - gunpos.f[1];
|
|
vector.f[2] = aimpos.f[2] - gunpos.f[2];
|
|
|
|
guNormalize(&vector.f[0], &vector.f[1], &vector.f[2]);
|
|
hasaimpos = true;
|
|
}
|
|
} else if ((gset.weaponnum == WEAPON_DEVASTATOR && gset.weaponfunc == FUNC_PRIMARY)
|
|
|| gset.weaponnum == WEAPON_SUPERDRAGON) {
|
|
if (targetprop->type == PROPTYPE_CHR || targetprop->type == PROPTYPE_PLAYER) {
|
|
// Grenades - aim at target's feet
|
|
aimpos.x = targetprop->pos.x;
|
|
aimpos.y = targetprop->chr->manground;
|
|
aimpos.z = targetprop->pos.z;
|
|
|
|
chrCalculateTrajectory(&gunpos, spcc, &aimpos, &vector);
|
|
hasaimpos = true;
|
|
}
|
|
} else if ((gset.weaponnum == WEAPON_DEVASTATOR && gset.weaponfunc == FUNC_SECONDARY)
|
|
|| gset.weaponnum == WEAPON_CROSSBOW) {
|
|
// Wall hugger grenade or crossbow - aim at target directly
|
|
aimpos.x = targetprop->pos.x;
|
|
aimpos.y = targetprop->pos.y;
|
|
aimpos.z = targetprop->pos.z;
|
|
|
|
if (targetprop->type == PROPTYPE_PLAYER) {
|
|
aimpos.y -= 25;
|
|
}
|
|
|
|
chrCalculateTrajectory(&gunpos, spcc, &aimpos, &vector);
|
|
hasaimpos = true;
|
|
}
|
|
|
|
if (hasaimpos) {
|
|
f32 angle = chrGetAngleToPos(chr, &aimpos); // b4
|
|
f32 cos = cosf(angle); // b0
|
|
f32 sin = sinf(angle);
|
|
|
|
tmp1 = vector.f[0];
|
|
vector.x = vector.f[2] * sin + vector.f[0] * cos;
|
|
vector.z = vector.f[2] * cos - tmp1 * sin;
|
|
}
|
|
}
|
|
|
|
// Calculate and projectile's matrix,
|
|
// spawn position and speed
|
|
mtx4LoadIdentity(&sp178);
|
|
mtx4LoadXRotation(sp200, &sp11c);
|
|
mtx4LoadYRotation(aimangle, &spdc);
|
|
mtx00015be0(&spdc, &sp11c);
|
|
|
|
sp15c.f[0] = xdiff = vector.f[0] * sp168;
|
|
sp15c.f[1] = ydiff = vector.f[1] * sp168;
|
|
sp15c.f[2] = zdiff = vector.f[2] * sp168;
|
|
|
|
sp16c.x = vector.f[0] * spcc + xdiff * g_Vars.lvupdate240freal;
|
|
sp16c.y = vector.f[1] * spcc + ydiff * g_Vars.lvupdate240freal;
|
|
sp16c.z = vector.f[2] * spcc + zdiff * g_Vars.lvupdate240freal;
|
|
|
|
projectileobj->timer240 = func->timer60;
|
|
|
|
if (projectileobj->timer240 != -1) {
|
|
#if PAL
|
|
projectileobj->timer240 = projectileobj->timer240 * 200 / 60;
|
|
#else
|
|
projectileobj->timer240 *= 4;
|
|
#endif
|
|
}
|
|
|
|
bgun0f09ebcc(&projectileobj->base, &gunpos, gunrooms, &sp11c, &sp16c, &sp178, chrprop, &gunpos);
|
|
|
|
if (projectileobj->base.hidden & OBJHFLAG_PROJECTILE) {
|
|
if (func->base.base.flags & FUNCFLAG_PROJECTILE_LIGHTWEIGHT) {
|
|
projectileobj->base.projectile->flags |= PROJECTILEFLAG_LIGHTWEIGHT;
|
|
} else if (func->base.base.flags & FUNCFLAG_PROJECTILE_POWERED) {
|
|
projectileobj->base.projectile->flags |= PROJECTILEFLAG_POWERED;
|
|
}
|
|
|
|
projectileobj->base.projectile->unk010 = sp15c.x;
|
|
projectileobj->base.projectile->unk014 = sp15c.y;
|
|
projectileobj->base.projectile->unk018 = sp15c.z;
|
|
|
|
projectileobj->base.projectile->pickuptimer240 = 240;
|
|
projectileobj->base.projectile->unk08c = func->unk5c;
|
|
projectileobj->base.projectile->unk098 = func->unk50 * (1.0f / 0.6f);
|
|
|
|
projectileobj->base.projectile->targetprop = chrGetTargetProp(chr);
|
|
|
|
// Play sound
|
|
if (func->soundnum > 0) {
|
|
propsnd0f0939f8(NULL, projectileobj->base.prop, func->soundnum, -1,
|
|
-1, 0, 0, 0, NULL, -1, NULL, -1, -1, -1, -1);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
firingthistick = false;
|
|
}
|
|
|
|
normalshoot = false;
|
|
} else if (gset.weaponnum == WEAPON_MAULER && isaibot && gset.weaponfunc == FUNC_SECONDARY) {
|
|
gset.unk063a = (s32)(chr->aibot->maulercharge[handnum] * 10);
|
|
chr->aibot->maulercharge[handnum] = 0;
|
|
}
|
|
|
|
if (normalshoot) {
|
|
if (!isaibot) {
|
|
if ((attackflags & ATTACKFLAG_AIMATTARGET)
|
|
&& targetprop->type == PROPTYPE_PLAYER
|
|
&& chrCanSeeAttackTarget(chr, &gunpos, gunrooms, false)
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
&& chrCompareTeams(targetprop->chr, chr, COMPARE_ENEMIES)
|
|
#endif
|
|
) {
|
|
// Solo chr shooting at a player
|
|
f32 xdiff = targetprop->pos.f[0] - gunpos.f[0] - vector.f[0] * 15;
|
|
f32 ydiff = targetprop->pos.f[1] - gunpos.f[1] - vector.f[1] * 15;
|
|
f32 zdiff = targetprop->pos.f[2] - gunpos.f[2] - vector.f[2] * 15;
|
|
|
|
if (xdiff * xdiff + ydiff * ydiff + zdiff * zdiff <= sqshotdist) {
|
|
// Player has a chance of being hit
|
|
chrCalculateHit(chr, &angleok, &hitplayer, &gset);
|
|
|
|
// If the player was hit then turn off effective
|
|
// (There's no need to check other props for
|
|
// hits later on in this function)
|
|
effective = !hitplayer;
|
|
|
|
if (angleok
|
|
&& (chr->actiontype == ACT_ATTACK
|
|
|| chr->actiontype == ACT_ATTACKROLL
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTAND
|
|
|| chr->actiontype == ACT_BOT_ATTACKKNEEL
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTRAFE)) {
|
|
chr->act_attack.lastontarget60 = g_Vars.lvframe60;
|
|
}
|
|
}
|
|
} else {
|
|
// Solo chr shooting at something else
|
|
if (chr->actiontype == ACT_ATTACK
|
|
|| chr->actiontype == ACT_ATTACKROLL
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTAND
|
|
|| chr->actiontype == ACT_BOT_ATTACKKNEEL
|
|
|| chr->actiontype == ACT_BOT_ATTACKSTRAFE) {
|
|
chr->act_attack.lastontarget60 = g_Vars.lvframe60;
|
|
}
|
|
}
|
|
|
|
if (hitplayer) {
|
|
f32 damage = gsetGetDamage(&gset); // 9c
|
|
struct modelnode *node = NULL; // 98
|
|
struct model *model = NULL; // 94
|
|
s32 side = -1; // 90
|
|
s32 hitpart = HITPART_GENERAL; // 8c
|
|
struct chrdata *targetchr = targetprop->chr; // 88
|
|
|
|
hitpos.x = targetprop->pos.x;
|
|
hitpos.y = targetprop->pos.y;
|
|
hitpos.z = targetprop->pos.z;
|
|
|
|
if (random() % 2) {
|
|
hitpos.y += 2 + random() % 10;
|
|
} else {
|
|
hitpos.y -= 2 + random() % 10;
|
|
}
|
|
|
|
bgunPlayPropHitSound(&gset, targetprop, -1);
|
|
|
|
if (targetchr->model && chrGetShield(targetchr) > 0) {
|
|
chrCalculateShieldHit(targetchr, &hitpos, &vector, &node, &hitpart, &model, &side);
|
|
}
|
|
|
|
func0f0341dc(targetchr, damage, &vector, &gset, chr->prop, HITPART_GENERAL, targetprop, node, model, side, NULL);
|
|
} else if ((hitprop == NULL || (hitprop->type != PROPTYPE_CHR && hitprop->type != PROPTYPE_PLAYER))
|
|
&& sqshotdist < 100 * 100) {
|
|
// Hit the background or something other than a
|
|
// player or chr, and the shot distance was less
|
|
// than 1 metre. Don't bother applying damage etc.
|
|
effective = false;
|
|
}
|
|
}
|
|
|
|
if (effective) {
|
|
if (hitprop) {
|
|
if (hitprop->type == PROPTYPE_PLAYER || hitprop->type == PROPTYPE_CHR) {
|
|
// Hit a player or chr other than the one they
|
|
// were aiming for
|
|
if (isaibot
|
|
|| fudgeforeyespy
|
|
|| ((chr->chrflags & CHRCFLAG_00000040) && chrCompareTeams(hitprop->chr, chr, COMPARE_ENEMIES))) {
|
|
struct modelnode *node = NULL; // 84
|
|
struct model *model = NULL; // 80
|
|
s32 side = -1; // 7c
|
|
s32 hitpart = HITPART_GENERAL; // 78
|
|
f32 damage = gsetGetDamage(&gset);
|
|
struct chrdata *hitchr = hitprop->chr; // 70
|
|
|
|
bgunPlayPropHitSound(&gset, hitprop, -1);
|
|
|
|
if (hitchr->model && chrGetShield(hitchr) > 0) {
|
|
chrCalculateShieldHit(hitchr, &hitpos, &vector, &node, &hitpart, &model, &side);
|
|
}
|
|
|
|
chrEmitSparks(hitchr, hitprop, hitpart, &hitpos, &vector, chr);
|
|
func0f0341dc(hitchr, damage, &vector, &gset, chr->prop, HITPART_GENERAL, hitprop, node, model, side, NULL);
|
|
} else {
|
|
makebeam = false;
|
|
firingthistick = false;
|
|
}
|
|
} else if (hitprop->type == PROPTYPE_OBJ
|
|
|| hitprop->type == PROPTYPE_WEAPON
|
|
|| hitprop->type == PROPTYPE_DOOR) {
|
|
// Hit an object
|
|
struct defaultobj *hitobj = hitprop->obj; // 6c
|
|
s32 playernum = -1; // 68
|
|
|
|
if (g_Vars.mplayerisrunning) {
|
|
playernum = mpPlayerGetIndex(chr);
|
|
}
|
|
|
|
bgunPlayPropHitSound(&gset, hitprop, -1);
|
|
func0f065e74(&gunpos, gunrooms, &hitpos, hitrooms);
|
|
sp210 = true;
|
|
|
|
if (chrIsUsingPaintball(chr)) {
|
|
sparksCreate(hitrooms[0], hitprop, &hitpos, NULL, NULL, SPARKTYPE_PAINT);
|
|
} else {
|
|
sparksCreate(hitrooms[0], hitprop, &hitpos, NULL, NULL, SPARKTYPE_DEFAULT);
|
|
}
|
|
|
|
if (g_MissionConfig.iscoop && chr->team == TEAM_ALLY
|
|
&& (hitobj->flags2 & OBJFLAG2_IMMUNETOANTI)) {
|
|
// empty
|
|
} else {
|
|
objTakeGunfire(hitobj, gsetGetDamage(&gset), &hitpos, gset.weaponnum, playernum);
|
|
}
|
|
}
|
|
} else if (hitsomething) {
|
|
// Hit the background
|
|
func0f065e74(&gunpos, gunrooms, &hitpos, hitrooms);
|
|
sp210 = true;
|
|
bgunPlayBgHitSound(&gset, &hitpos, -1, hitrooms);
|
|
|
|
if (chrIsUsingPaintball(chr)) {
|
|
sparksCreate(hitrooms[0], 0, &hitpos, NULL, NULL, SPARKTYPE_PAINT);
|
|
} else {
|
|
sparksCreate(hitrooms[0], 0, &hitpos, NULL, NULL, SPARKTYPE_DEFAULT);
|
|
}
|
|
}
|
|
|
|
// Create explosion if using Phoenix
|
|
if (gset.weaponnum == WEAPON_PHOENIX && gset.weaponfunc == FUNC_SECONDARY) {
|
|
s32 playernum = chr->aibot ? mpPlayerGetIndex(chr) : g_Vars.currentplayernum;
|
|
|
|
if (!sp210) {
|
|
func0f065e74(&gunpos, gunrooms, &hitpos, hitrooms);
|
|
}
|
|
|
|
explosionCreateSimple(0, &hitpos, hitrooms, EXPLOSIONTYPE_PHOENIX, playernum);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isshootingeyespy) {
|
|
propSetPerimEnabled(targetprop, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (makebeam) {
|
|
switch (gset.weaponnum) {
|
|
case WEAPON_FALCON2:
|
|
case WEAPON_FALCON2_SILENCER:
|
|
case WEAPON_FALCON2_SCOPE:
|
|
case WEAPON_MAGSEC4:
|
|
case WEAPON_MAULER:
|
|
case WEAPON_PHOENIX:
|
|
case WEAPON_DY357MAGNUM:
|
|
case WEAPON_DY357LX:
|
|
case WEAPON_CMP150:
|
|
case WEAPON_CYCLONE:
|
|
case WEAPON_CALLISTO:
|
|
case WEAPON_RCP120:
|
|
case WEAPON_LAPTOPGUN:
|
|
case WEAPON_DRAGON:
|
|
case WEAPON_K7AVENGER:
|
|
case WEAPON_AR34:
|
|
case WEAPON_SUPERDRAGON:
|
|
case WEAPON_REAPER:
|
|
case WEAPON_SNIPERRIFLE:
|
|
case WEAPON_FARSIGHT:
|
|
case WEAPON_TRANQUILIZER:
|
|
case WEAPON_LASER:
|
|
case WEAPON_PP9I:
|
|
case WEAPON_CC13:
|
|
case WEAPON_KL01313:
|
|
case WEAPON_KF7SPECIAL:
|
|
case WEAPON_ZZT:
|
|
case WEAPON_DMC:
|
|
case WEAPON_AR53:
|
|
case WEAPON_RCP45:
|
|
makebeam = true;
|
|
break;
|
|
default:
|
|
makebeam = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
chrCreateFireslot(chr, handnum, firingthistick, firingthistick && makebeam, &gunpos, &hitpos);
|
|
|
|
if (isaibot) {
|
|
if (firingthistick) {
|
|
if (chr->aibot->loadedammo[handnum] > 0) {
|
|
chr->aibot->loadedammo[handnum]--;
|
|
}
|
|
}
|
|
|
|
chrSetFiring(chr, handnum, firingthistick && normalshoot);
|
|
} else {
|
|
chrSetFiring(chr, handnum, firingthistick);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void func0f041a74(struct chrdata *chr)
|
|
{
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
chr->hidden2 &= ~CHRH2FLAG_0020;
|
|
#else
|
|
chr->hidden &= ~CHRHFLAG_00000080;
|
|
#endif
|
|
|
|
if (chr->actiontype == ACT_ROBOTATTACK) {
|
|
if (chr->act_robotattack.firing[0]) {
|
|
chr->prop->forcetick = true;
|
|
projectileCreate(chr->prop, chr->unk348[0], &chr->act_robotattack.pos[0],
|
|
&chr->act_robotattack.dir[0], chr->act_robotattack.guntype[0], chrGetTargetProp(chr));
|
|
chr->unk348[1]->unk08 = g_Vars.lvframe60 + 2;
|
|
chr->unk348[1]->unk14 = chr->unk348[0]->unk14;
|
|
} else {
|
|
chr->prop->forcetick = false;
|
|
}
|
|
|
|
if (chr->act_robotattack.firing[1]) {
|
|
chr->prop->forcetick = true;
|
|
projectileCreate(chr->prop, chr->unk348[1], &chr->act_robotattack.pos[1],
|
|
&chr->act_robotattack.dir[1], chr->act_robotattack.guntype[1], chrGetTargetProp(chr));
|
|
chr->unk348[0]->unk14 = chr->unk348[1]->unk14;
|
|
} else {
|
|
chr->prop->forcetick = false;
|
|
}
|
|
|
|
beamTick(chr->unk348[0]->beam);
|
|
beamTick(chr->unk348[1]->beam);
|
|
} else if (chr->actiontype == ACT_ATTACKAMOUNT) {
|
|
if (chr->act_attack.numshots < chr->act_attack.maxshots
|
|
&& (chr->hidden & CHRHFLAG_FIRINGRIGHT)) {
|
|
chrShoot(chr, 0);
|
|
}
|
|
} else {
|
|
if (chr->hidden & CHRHFLAG_FIRINGRIGHT) {
|
|
chrShoot(chr, 0);
|
|
chr->hidden &= ~CHRHFLAG_FIRINGRIGHT;
|
|
}
|
|
|
|
if (chr->hidden & CHRHFLAG_FIRINGLEFT) {
|
|
chrShoot(chr, 1);
|
|
chr->hidden &= ~CHRHFLAG_FIRINGLEFT;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool func0f041c44(struct chrdata *chr)
|
|
{
|
|
if (CHRRACE(chr) == RACE_HUMAN) {
|
|
if (chr->act_attack.animcfg == &g_RollAttackAnims[2] || chr->act_attack.animcfg == &g_RollAttackAnims[3]) {
|
|
struct model *model = chr->model;
|
|
struct attackanimconfig *animcfg = &g_RollAttackAnims[1];
|
|
bool flip = model->anim->flip;
|
|
|
|
chr->act_attack.turning = TURNSTATE_OFF;
|
|
chr->act_attack.animcfg = animcfg;
|
|
chr->sleep = 0;
|
|
|
|
modelSetAnimation(model, animcfg->animnum, flip, animcfg->unk1c, chrGetRangedSpeed(chr, 0.7f, 1.12f), 22);
|
|
|
|
if (animcfg->unk14 >= 0) {
|
|
modelSetAnimEndFrame(model, animcfg->unk14);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void chrAttackAmountUpdateAnimation(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
|
|
if (chr->act_attack.animcfg->unk24 > 0) {
|
|
modelSetAnimation(model,
|
|
modelGetAnimNum(model),
|
|
model->anim->flip,
|
|
chr->act_attack.animcfg->unk24,
|
|
chrGetRangedSpeed(chr, 0.5f, 0.8f),
|
|
8);
|
|
} else {
|
|
modelSetAnimation(model,
|
|
modelGetAnimNum(model),
|
|
model->anim->flip,
|
|
chr->act_attack.animcfg->unk1c,
|
|
chrGetRangedSpeed(chr, 0.5f, 0.8f),
|
|
8);
|
|
}
|
|
|
|
if (chr->act_attack.animcfg->unk14 >= 0) {
|
|
modelSetAnimEndFrame(model, chr->act_attack.animcfg->unk14);
|
|
}
|
|
}
|
|
|
|
void chrTickFire(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
f32 curframe = modelGetCurAnimFrame(model);
|
|
s32 i;
|
|
|
|
if (modelGetAnimNum(model) == ANIM_SNIPING_GETDOWN) {
|
|
return;
|
|
}
|
|
|
|
if (chr->act_attack.lastontarget60 < chr->act_attack.lastfire60 - TICKS(30)
|
|
&& model->anim->animnum2 == 0
|
|
&& curframe > chr->act_attack.animcfg->unk18 + 10
|
|
&& curframe < chr->act_attack.animcfg->unk1c
|
|
&& (chr->act_attack.animcfg->unk24 < 0 || curframe < chr->act_attack.animcfg->unk24)) {
|
|
if (!chr->act_attack.dorecoil) {
|
|
if (!func0f041c44(chr)) {
|
|
modelSetAnimation(model, modelGetAnimNum(model), model->anim->flip,
|
|
chr->act_attack.animcfg->unk1c, chrGetRangedSpeed(chr, 0.5f, 0.8f), 8);
|
|
|
|
if (chr->act_attack.animcfg->unk14 >= 0) {
|
|
modelSetAnimEndFrame(model, chr->act_attack.animcfg->unk14);
|
|
}
|
|
}
|
|
} else {
|
|
chrAttackAmountUpdateAnimation(chr);
|
|
}
|
|
|
|
chr->act_attack.numshots = chr->act_attack.maxshots + 1;
|
|
|
|
curframe = modelGetCurAnimFrame(model);
|
|
}
|
|
|
|
if (curframe >= modelGetAnimEndFrame(model)) {
|
|
if (modelGetAnimNum(model) != ANIM_SNIPING_ONGROUND
|
|
&& (chr->act_attack.dooneburst || chr->act_attack.numshots > chr->act_attack.maxshots)) {
|
|
if (!func0f041c44(chr)) {
|
|
if (chr->act_attack.flags & ATTACKFLAG_AIMATTARGET) {
|
|
chrRecordLastSeeTargetTime(chr);
|
|
}
|
|
|
|
chrStop(chr);
|
|
return;
|
|
}
|
|
} else if (chr->act_attack.numshots == chr->act_attack.maxshots) {
|
|
chr->act_attack.numshots++;
|
|
chrAttackAmountUpdateAnimation(chr);
|
|
} else if (chr->act_attack.fired) {
|
|
f32 f2 = 0.5f;
|
|
f32 startframe;
|
|
f32 endframe;
|
|
f32 diff;
|
|
|
|
if (chr->act_attack.dorecoil) {
|
|
if (chr->act_attack.animcfg->unk20 > 0) {
|
|
startframe = chr->act_attack.animcfg->unk20;
|
|
} else {
|
|
startframe = chr->act_attack.animcfg->unk18;
|
|
}
|
|
|
|
if (chr->act_attack.animcfg->unk24 > 0) {
|
|
endframe = chr->act_attack.animcfg->unk24;
|
|
} else {
|
|
endframe = chr->act_attack.animcfg->unk1c;
|
|
}
|
|
} else {
|
|
startframe = chr->act_attack.animcfg->unk18;
|
|
|
|
if (chr->act_attack.animcfg->unk20 > 0) {
|
|
endframe = chr->act_attack.animcfg->unk20;
|
|
} else {
|
|
endframe = chr->act_attack.animcfg->unk1c;
|
|
}
|
|
}
|
|
|
|
diff = endframe - startframe;
|
|
|
|
if (diff < 12) {
|
|
f2 = diff * (1.0f / 24.0f);
|
|
} else if (diff > 16) {
|
|
f2 = diff * (1.0f / 32.0f);
|
|
}
|
|
|
|
if (chr->act_attack.everytick[HAND_RIGHT] && chr->act_attack.everytick[HAND_LEFT]) {
|
|
f2 = f2 + f2;
|
|
}
|
|
|
|
chr->act_attack.fired = false;
|
|
|
|
modelSetAnimation(model, modelGetAnimNum(model), model->anim->flip, startframe, f2, 8);
|
|
modelSetAnimEndFrame(model, endframe);
|
|
}
|
|
|
|
curframe = modelGetCurAnimFrame(model);
|
|
}
|
|
|
|
if (modelGetAnimNum(model) != ANIM_SNIPING_ONGROUND && (chr->act_attack.flags & ATTACKFLAG_DONTTURN) == 0) {
|
|
f32 f2 = chr->act_attack.animcfg->unk0c;
|
|
f32 f12 = chr->act_attack.animcfg->unk04;
|
|
|
|
if ((chr->act_attack.flags & ATTACKFLAG_AIMONLY) && f12 > modelGetAnimEndFrame(model)) {
|
|
f12 = modelGetAnimEndFrame(model);
|
|
}
|
|
|
|
if (model->anim->flip) {
|
|
f2 = M_BADTAU - f2;
|
|
}
|
|
|
|
chr->act_attack.turning = chrTurn(chr, chr->act_attack.turning, f12, chrGetRangedSpeed(chr, 1, 1.6f), f2);
|
|
}
|
|
|
|
if ((curframe > chr->act_attack.animcfg->unk28 && curframe < chr->act_attack.animcfg->unk2c)
|
|
|| modelGetAnimNum(model) == ANIM_SNIPING_ONGROUND) {
|
|
func0f03e9f4(chr, chr->act_attack.animcfg, chr->act_attack.firegun[HAND_LEFT], chr->act_attack.firegun[HAND_RIGHT], 1);
|
|
} else {
|
|
chrResetAimEndProperties(chr);
|
|
}
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
if (chr->act_attack.firegun[i]) {
|
|
if (chr->act_attack.everytick[i] == 0) {
|
|
if (modelGetAnimNum(model) == ANIM_SNIPING_ONGROUND
|
|
|| (curframe >= chr->act_attack.animcfg->unk18 && curframe < chr->act_attack.animcfg->unk1c)) {
|
|
chrSetHandFiring(chr, i, true);
|
|
|
|
chr->act_attack.lastfire60 = g_Vars.lvframe60;
|
|
|
|
if (chr->actiontype == ACT_ATTACKROLL) {
|
|
f32 f12 = chr->act_attack.animcfg->unk1c - chr->act_attack.animcfg->unk18;
|
|
|
|
if (f12 < 30) {
|
|
if (chr->act_attack.pausecount >= TICKS(60) - (s32)(PAL ? f12 * (50.0f / 60.0f) : f12) * 2) {
|
|
modelSetAnimSpeed(model, 0.5f, 0);
|
|
} else {
|
|
modelSetAnimSpeed(model, 0.1f, 0);
|
|
chr->act_attack.pausecount += g_Vars.lvupdate240_60;
|
|
}
|
|
} else {
|
|
modelSetAnimSpeed(model, 0.5f, 0);
|
|
}
|
|
} else {
|
|
modelSetAnimSpeed(model, 0.5f, 0);
|
|
}
|
|
} else {
|
|
chrSetHandFiring(chr, i, false);
|
|
|
|
if (chr->actiontype == ACT_ATTACKROLL) {
|
|
modelSetAnimSpeed(model, chrGetRangedSpeed(chr, 0.5f, 0.8f), 0);
|
|
} else {
|
|
modelSetAnimSpeed(model, chrGetRangedSpeed(chr, 0.5f, 0.8f), 0);
|
|
}
|
|
}
|
|
} else if (modelGetAnimNum(model) == ANIM_SNIPING_ONGROUND
|
|
|| ((!chr->act_attack.fired && (i == chr->act_attack.nextgun || !chr->act_attack.everytick[chr->act_attack.nextgun]))
|
|
&& ((chr->act_attack.animcfg->unk20 >= 0 && curframe >= chr->act_attack.animcfg->unk20 && curframe <= chr->act_attack.animcfg->unk24)
|
|
|| (chr->act_attack.animcfg->unk20 < 0 && curframe >= chr->act_attack.animcfg->unk18)))) {
|
|
chr->act_attack.fired = true;
|
|
chr->act_attack.nextgun = 1 - chr->act_attack.nextgun;
|
|
chr->act_attack.numshots++;
|
|
chr->act_attack.lastfire60 = g_Vars.lvframe60;
|
|
|
|
chrSetHandFiring(chr, i, true);
|
|
} else {
|
|
chrSetHandFiring(chr, i, false);
|
|
}
|
|
} else {
|
|
chrSetHandFiring(chr, i, false);
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrTickAttackAmount(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
f32 frame = modelGetCurAnimFrame(model);
|
|
f32 unk0c = chr->act_attack.animcfg->unk0c;
|
|
f32 unk04 = chr->act_attack.animcfg->unk04;
|
|
|
|
chrTurn(chr, 1, unk04, chrGetRangedSpeed(chr, 1, 1.6f), unk0c);
|
|
|
|
if (frame > chr->act_attack.animcfg->unk28
|
|
&& frame < chr->act_attack.animcfg->unk2c) {
|
|
func0f03e9f4(chr, chr->act_attack.animcfg, false, true, 0.2f);
|
|
} else {
|
|
chrResetAimEndProperties(chr);
|
|
}
|
|
|
|
if (frame >= chr->act_attack.animcfg->unk18 && chr->act_attack.dooneburst == false) {
|
|
chr->act_attack.dooneburst = true;
|
|
}
|
|
|
|
if (chr->act_attack.dooneburst) {
|
|
if (chr->act_attack.numshots++ < chr->act_attack.maxshots) {
|
|
chrSetHandFiring(chr, HAND_RIGHT, true);
|
|
} else {
|
|
chrAttackAmountUpdateAnimation(chr);
|
|
chrSetHandFiring(chr, HAND_RIGHT, false);
|
|
}
|
|
} else {
|
|
chrSetHandFiring(chr, HAND_RIGHT, false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the robot's muzzle flash to on or off.
|
|
*
|
|
* There are two muzzles, left and right, which is specified using the `right`
|
|
* argument.
|
|
*/
|
|
void robotSetMuzzleFlash(struct chrdata *chr, bool right, bool visible)
|
|
{
|
|
struct modelnode *node;
|
|
union modelrwdata *rwdata;
|
|
s32 partnum;
|
|
|
|
if (right) {
|
|
partnum = MODELPART_ROBOT_RGUNFIRE;
|
|
} else {
|
|
partnum = MODELPART_ROBOT_LGUNFIRE;
|
|
}
|
|
|
|
node = modelGetPart(chr->model->filedata, partnum);
|
|
|
|
if (node) {
|
|
rwdata = modelGetNodeRwData(chr->model, node);
|
|
}
|
|
|
|
if (rwdata) {
|
|
rwdata->chrgunfire.visible = visible;
|
|
}
|
|
}
|
|
|
|
void robotAttack(struct chrdata *chr)
|
|
{
|
|
u32 numshots = random() % 20;
|
|
|
|
if (chr->unk348[0] && chr->unk348[1]) {
|
|
chr->actiontype = ACT_ROBOTATTACK;
|
|
|
|
chr->unk348[0]->beam->age = -1;
|
|
chr->unk348[0]->unk00 = random() % 3;
|
|
chr->unk348[0]->unk01 = 0;
|
|
chr->unk348[0]->unk08 = -1;
|
|
chr->unk348[0]->unk0c = 0.85f;
|
|
|
|
if ((lvGetDifficulty() == DIFF_PA) * 0.2f) {
|
|
chr->unk348[0]->unk10 = 2.0f;
|
|
} else {
|
|
chr->unk348[0]->unk10 = 1.0f;
|
|
}
|
|
|
|
chr->unk348[0]->unk14 = 0.0f;
|
|
|
|
chr->act_robotattack.pos[0].x = 0.0f;
|
|
chr->act_robotattack.pos[0].y = 0.0f;
|
|
chr->act_robotattack.pos[0].z = 0.0f;
|
|
chr->act_robotattack.dir[0].x = 0.0f;
|
|
chr->act_robotattack.dir[0].y = 0.0f;
|
|
chr->act_robotattack.dir[0].z = 0.0f;
|
|
chr->act_robotattack.guntype[0] = WEAPON_WATCHLASER;
|
|
chr->act_robotattack.firing[0] = false;
|
|
|
|
chr->unk348[1]->beam->age = -1;
|
|
chr->unk348[1]->unk00 = random() % 3;
|
|
chr->unk348[1]->unk01 = 0;
|
|
chr->unk348[1]->unk08 = -1;
|
|
chr->unk348[1]->unk0c = 0.85f;
|
|
chr->unk348[1]->unk10 = 0.2f;
|
|
chr->unk348[1]->unk14 = 0.0f;
|
|
|
|
chr->act_robotattack.guntype[1] = WEAPON_WATCHLASER;
|
|
chr->act_robotattack.firing[1] = false;
|
|
chr->act_robotattack.finished = false;
|
|
chr->act_robotattack.numshots[0] = numshots;
|
|
chr->act_robotattack.numshots[1] = numshots;
|
|
chr->act_robotattack.pos[1].x = 0.0f;
|
|
chr->act_robotattack.pos[1].y = 0.0f;
|
|
chr->act_robotattack.pos[1].z = 0.0f;
|
|
chr->act_robotattack.dir[1].x = 0.0f;
|
|
chr->act_robotattack.dir[1].y = 0.0f;
|
|
chr->act_robotattack.dir[1].z = 0.0f;
|
|
|
|
chrChooseStandAnimation(chr, 16);
|
|
}
|
|
}
|
|
|
|
void func0f0429d8(struct chrdata *chr, f32 arg1, f32 arg2)
|
|
{
|
|
struct prop *prop = chrGetTargetProp(chr);
|
|
f32 distance = atan2f(prop->pos.x - chr->prop->pos.x, prop->pos.z - chr->prop->pos.z);
|
|
f32 value = model0001afe8(arg2, distance, arg1);
|
|
chrSetLookAngle(chr, value);
|
|
}
|
|
|
|
void chrTickRobotAttack(struct chrdata *chr)
|
|
{
|
|
s32 i;
|
|
f32 roty = 0.0f;
|
|
f32 rotx = 0.0f;
|
|
struct prop *targetprop = chrGetTargetProp(chr);
|
|
bool firing;
|
|
bool empty;
|
|
f32 invtheta = chrGetInverseTheta(chr);
|
|
struct act_robotattack *act = &chr->act_robotattack;
|
|
|
|
func0f0429d8(chr, 0.085f, invtheta);
|
|
|
|
if (chr->model->filedata->skel != &g_SkelRobot) {
|
|
act->finished = true;
|
|
return;
|
|
}
|
|
|
|
for (i = 0; i < 2; i++) {
|
|
empty = false;
|
|
|
|
if (act->numshots[i] > 0) {
|
|
chr->unk348[i]->unk01 = !(chr->unk348[i]->unk00 % 3);
|
|
firing = !(chr->unk348[i]->unk00 % 2);
|
|
} else {
|
|
chr->unk348[i]->unk01 = 0;
|
|
firing = false;
|
|
}
|
|
|
|
act->firing[i] = firing;
|
|
|
|
if (act->numshots[0] <= 0 && act->numshots[1] <= 0) {
|
|
empty = true;
|
|
|
|
if (ABS(chr->gunroty[0]) < 0.03f
|
|
&& ABS(chr->gunrotx[0]) < 0.03f
|
|
&& ABS(chr->gunroty[1]) < 0.03f
|
|
&& ABS(chr->gunrotx[1]) < 0.03f) {
|
|
act->finished = true;
|
|
}
|
|
}
|
|
|
|
if (empty);
|
|
if ((f32)empty);
|
|
|
|
if (!empty) {
|
|
f32 aimy;
|
|
union modelrodata *rodata;
|
|
struct coord spe4;
|
|
Mtxf spa4;
|
|
|
|
aimy = targetprop->pos.y - 20.0f;
|
|
rodata = modelGetPartRodata(chr->model->filedata, (i ? MODELPART_ROBOT_0000 : MODELPART_ROBOT_0001));
|
|
|
|
act->pos[i].x = rodata->position.pos.x;
|
|
act->pos[i].y = rodata->position.pos.y - 300.0f;
|
|
act->pos[i].z = rodata->position.pos.z;
|
|
|
|
mtx4LoadYRotation(invtheta, &spa4);
|
|
mtx4RotateVec(&spa4, &act->pos[i], &spe4);
|
|
|
|
spe4.x *= chr->model->scale;
|
|
spe4.y *= chr->model->scale;
|
|
spe4.z *= chr->model->scale;
|
|
|
|
act->pos[i].x = spe4.x + chr->prop->pos.x;
|
|
act->pos[i].y = spe4.y + chr->prop->pos.y;
|
|
act->pos[i].z = spe4.z + chr->prop->pos.z;
|
|
|
|
roty = atan2f(targetprop->pos.x - act->pos[i].x, targetprop->pos.z - act->pos[i].z) - invtheta;
|
|
|
|
if (roty < 0.0f) {
|
|
roty += M_BADTAU;
|
|
}
|
|
|
|
if (roty > M_BADPI) {
|
|
roty -= M_BADTAU;
|
|
}
|
|
|
|
if (roty < -0.524f) {
|
|
roty = -0.524f;
|
|
}
|
|
|
|
if (roty > 0.524f) {
|
|
roty = 0.524f;
|
|
}
|
|
|
|
#define X() (targetprop->pos.x - act->pos[i].x)
|
|
#define Z() (targetprop->pos.z - act->pos[i].z)
|
|
|
|
rotx = M_BADTAU - atan2f(aimy - act->pos[i].y, sqrtf(Z() * Z() + X() * X()));
|
|
|
|
if (rotx > M_BADPI) {
|
|
rotx -= M_BADTAU;
|
|
}
|
|
|
|
if (rotx < -0.524f) {
|
|
rotx = -0.524f;
|
|
}
|
|
|
|
if (rotx > 0.524f) {
|
|
rotx = 0.524f;
|
|
}
|
|
}
|
|
|
|
chr->gunroty[i] += (roty - chr->gunroty[i]) * 0.15f;
|
|
chr->gunrotx[i] += (rotx - chr->gunrotx[i]) * 0.15f;
|
|
|
|
if (!empty) {
|
|
if (firing) {
|
|
f32 gunrotx = chr->gunrotx[i];
|
|
f32 gunroty = chr->gunroty[i];
|
|
|
|
if (gunrotx < 0.0f) {
|
|
gunrotx += M_BADTAU;
|
|
}
|
|
|
|
if (gunroty < 0.0f) {
|
|
gunroty += M_BADTAU;
|
|
}
|
|
|
|
gunroty += invtheta;
|
|
|
|
if (gunroty >= M_BADTAU) {
|
|
gunroty -= M_BADTAU;
|
|
}
|
|
|
|
act->dir[i].x = sinf(gunroty) * cosf(gunrotx);
|
|
act->dir[i].y = -sinf(gunrotx);
|
|
act->dir[i].z = cosf(gunroty) * cosf(gunrotx);
|
|
|
|
robotSetMuzzleFlash(chr, i, true);
|
|
|
|
act->numshots[i]--;
|
|
}
|
|
|
|
chr->unk348[i]->unk00++;
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrTickAttack(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
f32 curframe = modelGetCurAnimFrame(model);
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
modelSetAnimation(model, chr->act_attack.animcfg->animnum, chr->act_attack.flip,
|
|
chr->act_attack.animcfg->unk10, chrGetRangedSpeed(chr, 0.5f, 0.8f), 16);
|
|
func0f031254(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
if (chr->act_attack.animcfg->animnum == ANIM_SNIPING_GETDOWN) {
|
|
if (curframe >= modelGetAnimEndFrame(model)) {
|
|
chr->act_attack.animcfg = var80067d70;
|
|
|
|
modelSetAnimation(model, chr->act_attack.animcfg->animnum, chr->act_attack.flip,
|
|
chr->act_attack.animcfg->unk10, chrGetRangedSpeed(chr, 0.5f, 0.8f), 16);
|
|
}
|
|
}
|
|
|
|
if (!chr->aibot && chr->act_attack.reaim != 0) {
|
|
if (chr->act_attack.reaim == 1) {
|
|
f32 startframe;
|
|
|
|
if (chr->act_attack.animcfg->unk24 >= 0) {
|
|
startframe = chr->act_attack.animcfg->unk24;
|
|
} else {
|
|
startframe = chr->act_attack.animcfg->unk1c;
|
|
}
|
|
|
|
modelSetAnimation(model, modelGetAnimNum(model), model->anim->flip, startframe, chrGetRangedSpeed(chr, 0.5f, 0.8f), 16);
|
|
|
|
if (chr->act_attack.animcfg->unk14 >= 0) {
|
|
modelSetAnimEndFrame(model, chr->act_attack.animcfg->unk14);
|
|
}
|
|
|
|
chr->act_attack.reaim = 2;
|
|
chrResetAimEndProperties(chr);
|
|
return;
|
|
}
|
|
|
|
if (chr->act_attack.reaim == 2) {
|
|
if (curframe >= modelGetAnimEndFrame(model)) {
|
|
chr->act_attack.flags &= ~ATTACKFLAG_DONTTURN;
|
|
|
|
if (chr->act_attack.standing) {
|
|
chrAttackStand(chr, chr->act_attack.flags, chr->act_attack.entityid);
|
|
} else {
|
|
chrAttackKneel(chr, chr->act_attack.flags, chr->act_attack.entityid);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!chr->aibot && (chr->act_attack.flags & ATTACKFLAG_AIMONLY)) {
|
|
if (chr->act_attack.flags & ATTACKFLAG_DONTTURN) {
|
|
if (!func0f03e9f4(chr, chr->act_attack.animcfg, chr->act_attack.firegun[HAND_LEFT], chr->act_attack.firegun[HAND_RIGHT], 0.2f)) {
|
|
chr->act_attack.reaim = 1;
|
|
}
|
|
return;
|
|
}
|
|
|
|
if (curframe >= modelGetAnimEndFrame(model)) {
|
|
chr->act_attack.flags |= ATTACKFLAG_DONTTURN;
|
|
chr->act_attack.turning = TURNSTATE_OFF;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!chr->aibot
|
|
&& chr->act_attack.dorecoil == 0
|
|
&& chr->act_attack.animcfg->unk24 > 0
|
|
&& curframe <= chr->act_attack.animcfg->unk24
|
|
&& curframe >= modelGetAnimEndFrame(model)) {
|
|
modelSetAnimation(model, modelGetAnimNum(model), model->anim->flip,
|
|
chr->act_attack.animcfg->unk24, chrGetRangedSpeed(chr, 0.5f, 0.8f), 16);
|
|
|
|
if (chr->act_attack.dooneburst) {
|
|
if (chr->act_attack.animcfg->unk14 >= 0) {
|
|
modelSetAnimEndFrame(model, chr->act_attack.animcfg->unk14);
|
|
}
|
|
} else {
|
|
modelSetAnimEndFrame(model, chr->act_attack.animcfg->unk1c);
|
|
}
|
|
}
|
|
|
|
chrTickFire(chr);
|
|
}
|
|
|
|
void chrTickAttackRoll(struct chrdata *chr)
|
|
{
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrAttackRollChooseAnimation(chr);
|
|
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
if (chr->act_attack.onehanded) {
|
|
struct model *model = chr->model;
|
|
f32 curframe = modelGetCurAnimFrame(model);
|
|
|
|
if (chr->act_attack.animcfg == &g_RollAttackAnims[4]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[5]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[6]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[7]) {
|
|
if (curframe >= chr->act_attack.animcfg->unk14) {
|
|
struct attackanimconfig *newanimcfg = chr->act_attack.animcfg + 4;
|
|
bool flip = model->anim->flip;
|
|
f32 sp34 = 16;
|
|
|
|
if (chr->act_attack.firegun[HAND_LEFT] && chr->act_attack.firegun[HAND_RIGHT]) {
|
|
if (random() % 2 == 0) {
|
|
newanimcfg += 4;
|
|
} else {
|
|
newanimcfg += 8;
|
|
}
|
|
}
|
|
|
|
if (newanimcfg == &g_RollAttackAnims[8]) {
|
|
sp34 = 24;
|
|
} else if (newanimcfg == &g_RollAttackAnims[9]) {
|
|
sp34 = 24;
|
|
} else if (newanimcfg == &g_RollAttackAnims[10]) {
|
|
sp34 = 32;
|
|
} else if (newanimcfg == &g_RollAttackAnims[11]) {
|
|
sp34 = 44;
|
|
} else if (newanimcfg == &g_RollAttackAnims[12]) {
|
|
sp34 = 24;
|
|
} else if (newanimcfg == &g_RollAttackAnims[13]) {
|
|
sp34 = 34;
|
|
} else if (newanimcfg == &g_RollAttackAnims[14]) {
|
|
sp34 = 32;
|
|
} else if (newanimcfg == &g_RollAttackAnims[15]) {
|
|
sp34 = 44;
|
|
} else if (newanimcfg == &g_RollAttackAnims[16]) {
|
|
sp34 = 24;
|
|
} else if (newanimcfg == &g_RollAttackAnims[17]) {
|
|
sp34 = 34;
|
|
} else if (newanimcfg == &g_RollAttackAnims[18]) {
|
|
sp34 = 32;
|
|
} else if (newanimcfg == &g_RollAttackAnims[19]) {
|
|
sp34 = 44;
|
|
}
|
|
|
|
chr->act_attack.turning = TURNSTATE_OFF;
|
|
chr->act_attack.animcfg = newanimcfg;
|
|
chr->sleep = 0;
|
|
|
|
modelSetAnimation(model, newanimcfg->animnum, flip, newanimcfg->unk10,
|
|
chrGetRangedSpeed(chr, 0.5f, 0.8f), sp34);
|
|
|
|
if (chr->act_attack.dorecoil) {
|
|
if (newanimcfg->unk24 >= 0.0f) {
|
|
modelSetAnimEndFrame(model, newanimcfg->unk24);
|
|
} else {
|
|
modelSetAnimEndFrame(model, newanimcfg->unk1c);
|
|
}
|
|
} else {
|
|
if (newanimcfg->unk20 >= 0.0f) {
|
|
modelSetAnimEndFrame(model, newanimcfg->unk20);
|
|
} else {
|
|
if (newanimcfg->unk14 >= 0.0f) {
|
|
modelSetAnimEndFrame(model, newanimcfg->unk14);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (chr->act_attack.animcfg->unk0c != 0.0f) {
|
|
union modelrwdata *rwdata = modelGetNodeRwData(model, model->filedata->rootnode);
|
|
rwdata->chrinfo.unk5c = sp34;
|
|
rwdata->chrinfo.unk58 = -chr->act_attack.animcfg->unk0c / sp34;
|
|
|
|
if (flip) {
|
|
rwdata->chrinfo.unk58 = -rwdata->chrinfo.unk58;
|
|
}
|
|
}
|
|
}
|
|
} else if (chr->act_attack.animcfg == &g_RollAttackAnims[8]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[9]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[10]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[11]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[12]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[13]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[14]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[15]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[16]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[17]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[18]
|
|
|| chr->act_attack.animcfg == &g_RollAttackAnims[19]) {
|
|
if (!chr->act_attack.dorecoil
|
|
&& chr->act_attack.animcfg->unk24 > 0
|
|
&& curframe <= chr->act_attack.animcfg->unk24
|
|
&& curframe >= modelGetAnimEndFrame(model)) {
|
|
modelSetAnimation(model, modelGetAnimNum(model), model->anim->flip,
|
|
chr->act_attack.animcfg->unk24, chrGetRangedSpeed(chr, 0.5f, 0.8f), 16);
|
|
|
|
if (chr->act_attack.dooneburst) {
|
|
if (chr->act_attack.animcfg->unk14 >= 0) {
|
|
modelSetAnimEndFrame(model, chr->act_attack.animcfg->unk14);
|
|
}
|
|
} else {
|
|
u32 stack;
|
|
modelSetAnimEndFrame(model, chr->act_attack.animcfg->unk1c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
chrTickFire(chr);
|
|
}
|
|
|
|
void propPrintDangerous(void)
|
|
{
|
|
u8 i;
|
|
|
|
osSyncPrintf("Current dangerous items:");
|
|
|
|
for (i = 0; i < MAX_DANGEROUSPROPS; i++) {
|
|
struct prop *prop = g_DangerousProps[i];
|
|
|
|
if (prop) {
|
|
if (prop->weapon
|
|
&& prop->weapon->weaponnum == WEAPON_GRENADE
|
|
&& prop->type == PROPTYPE_WEAPON) {
|
|
osSyncPrintf(" Grenade %x", prop);
|
|
} else if (prop->type == PROPTYPE_EXPLOSION) {
|
|
osSyncPrintf(" Explosion %x", prop);
|
|
} else {
|
|
osSyncPrintf("misc dangerous prop");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void propUnsetDangerous(struct prop *prop)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i != MAX_DANGEROUSPROPS; i++) {
|
|
if (g_DangerousProps[i] == prop) {
|
|
g_DangerousProps[i] = NULL;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void propSetDangerous(struct prop *prop)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i != MAX_DANGEROUSPROPS; i++) {
|
|
if (g_DangerousProps[i] == NULL) {
|
|
g_DangerousProps[i] = prop;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void chrTickThrowGrenade(struct chrdata *chr)
|
|
{
|
|
struct model *model;
|
|
f32 frame;
|
|
u32 hand;
|
|
struct prop *weaponprop;
|
|
struct defaultobj *obj;
|
|
struct weaponobj *weapon;
|
|
f32 frame2;
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrThrowGrenadeChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
model = chr->model;
|
|
frame = modelGetCurAnimFrame(model);
|
|
hand = model->anim->flip ? 1 : 0;
|
|
weaponprop = chrGetHeldProp(chr, hand);
|
|
|
|
if ((frame >= 20 && weaponprop && modelGetAnimNum(model) == ANIM_THROWGRENADE_STANDING) ||
|
|
(frame >= 1 && weaponprop && modelGetAnimNum(model) == ANIM_THROWGRENADE_NOPIN) ||
|
|
(frame >= 1 && weaponprop && modelGetAnimNum(model) == ANIM_THROWGRENADE_CROUCHING)) {
|
|
obj = weaponprop->obj;
|
|
obj->hidden &= ~OBJHFLAG_00000800;
|
|
}
|
|
|
|
if ((frame >= 119 && weaponprop && modelGetAnimNum(model) == ANIM_THROWGRENADE_STANDING) ||
|
|
(frame >= 57 && weaponprop && modelGetAnimNum(model) == ANIM_THROWGRENADE_NOPIN) ||
|
|
(frame >= 58 && weaponprop && modelGetAnimNum(model) == ANIM_THROWGRENADE_CROUCHING)) {
|
|
weapon = weaponprop->weapon;
|
|
objSetDropped(weaponprop, DROPTYPE_THROWGRENADE);
|
|
chr->hidden |= CHRHFLAG_00000001;
|
|
weapon->timer240 = TICKS(240);
|
|
}
|
|
|
|
frame2 = modelGetCurAnimFrame(model);
|
|
|
|
if (frame2 >= modelGetAnimEndFrame(model)) {
|
|
chrStop(chr);
|
|
} else {
|
|
if ((frame >= 87 && frame <= 110 && modelGetAnimNum(model) == ANIM_THROWGRENADE_STANDING) ||
|
|
(frame >= 5 && frame <= 45 && modelGetAnimNum(model) == ANIM_THROWGRENADE_NOPIN) ||
|
|
((frame >= 20 && frame <= 45 && modelGetAnimNum(model) == ANIM_THROWGRENADE_CROUCHING))) {
|
|
f32 value = chrGetRangedSpeed(chr, 1, 3.2);
|
|
chrTurn(chr, 1, 110, value, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool chrDetectDangerousObject(struct chrdata *chr, u8 flags)
|
|
{
|
|
s32 i;
|
|
|
|
for (i = 0; i != MAX_DANGEROUSPROPS; i++) {
|
|
struct prop *prop = g_DangerousProps[i];
|
|
bool pass = false;
|
|
|
|
if (prop) {
|
|
if ((flags & 1) && prop->weapon &&
|
|
prop->weapon->weaponnum == WEAPON_GRENADE &&
|
|
prop->weapon->timer240 < TICKS(480)) {
|
|
pass = true;
|
|
}
|
|
|
|
if ((flags & 2) && prop->type == PROPTYPE_EXPLOSION) {
|
|
pass = true;
|
|
}
|
|
|
|
if (pass && chrGetSquaredDistanceToCoord(chr, &prop->pos) < 1600) {
|
|
chr->runfrompos.x = g_DangerousProps[i]->pos.x;
|
|
chr->runfrompos.y = g_DangerousProps[i]->pos.y;
|
|
chr->runfrompos.z = g_DangerousProps[i]->pos.z;
|
|
|
|
if (chr->aibot) {
|
|
chr->aibot->unk064 |= 0x0004;
|
|
chr->aibot->dangerouspropnum = i;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (chr->aibot) {
|
|
chr->aibot->unk064 &= ~0x0004;
|
|
chr->aibot->dangerouspropnum = -1;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void chrTickBondDie(struct chrdata *chr)
|
|
{
|
|
// empty
|
|
}
|
|
|
|
bool func0f043f2c(struct chrdata *chr, struct coord *runpos, u32 arg2, f32 *turnspeed)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct model *model = chr->model;
|
|
f32 accel;
|
|
f32 maxspeed;
|
|
f32 angle1;
|
|
f32 finalangle;
|
|
f32 angle2;
|
|
f32 angle3;
|
|
f32 xdiff = runpos->f[0] - prop->pos.f[0];
|
|
f32 zdiff = runpos->f[2] - prop->pos.f[2];
|
|
bool result;
|
|
|
|
result = false;
|
|
angle1 = atan2f(xdiff, zdiff);
|
|
finalangle = func0f03e578(chr);
|
|
angle2 = angle1 - finalangle;
|
|
|
|
if (finalangle > angle1) {
|
|
angle2 += M_BADTAU;
|
|
}
|
|
|
|
if (chr->aibot) {
|
|
if (chr->blurdrugamount > 0) {
|
|
angle1 += chr->blurdrugamount * PALUPF(0.00031410926021636f) * sinf((g_Vars.lvframe60 % TICKS(1200)) * PALUPF(0.0052351541817188f));
|
|
|
|
if (angle1 >= M_BADTAU) {
|
|
angle1 -= M_BADTAU;
|
|
}
|
|
|
|
angle1 += M_BADTAU;
|
|
}
|
|
|
|
finalangle = angle1;
|
|
*turnspeed = 0;
|
|
result = true;
|
|
} else {
|
|
angle3 = angle2;
|
|
|
|
if (angle2 > M_BADPI) {
|
|
angle3 = M_BADTAU - angle3;
|
|
}
|
|
|
|
if ((arg2 % 4) == 2) {
|
|
maxspeed = 0.29915165901184f;
|
|
accel = 0.014957583509386f;
|
|
} else if ((arg2 % 4) == 1) {
|
|
if (angle3 < 0.3926365673542f) {
|
|
maxspeed = 0.019631829112768f;
|
|
} else if (angle3 < 1.2564370632172f) {
|
|
maxspeed = 0.098159141838551f;
|
|
} else {
|
|
maxspeed = 0.1963182836771f;
|
|
}
|
|
|
|
accel = 0.014957583509386f;
|
|
} else {
|
|
if (angle3 < 0.3926365673542f) {
|
|
maxspeed = 0.0098159145563841f;
|
|
} else if (angle3 < 1.2564370632172f) {
|
|
maxspeed = 0.049079570919275f;
|
|
} else {
|
|
maxspeed = 0.12564370036125f;
|
|
}
|
|
|
|
accel = 0.0098159145563841f;
|
|
}
|
|
|
|
maxspeed *= model->anim->playspeed;
|
|
accel *= model->anim->playspeed;
|
|
|
|
applyRotation(&finalangle, angle1, turnspeed, accel, accel + accel, maxspeed);
|
|
|
|
if (ABS(finalangle - angle1) < 0.01f) {
|
|
*turnspeed = 0;
|
|
result = true;
|
|
}
|
|
}
|
|
|
|
func0f03e5b0(chr, finalangle);
|
|
|
|
return result;
|
|
}
|
|
|
|
void chrTickAttackWalk(struct chrdata *chr)
|
|
{
|
|
struct model *model = chr->model;
|
|
struct prop *prop = chr->prop;
|
|
struct prop *targetprop = chrGetTargetProp(chr);
|
|
s32 i;
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrAttackWalkChooseAnimation(chr);
|
|
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
chr->act_attackwalk.frame60count += g_Vars.lvupdate240_60;
|
|
chr->lastwalk60 = g_Vars.lvframe60;
|
|
|
|
// If stuck or time exceeded, stop
|
|
if (chr->invalidmove == 1
|
|
|| chr->lastmoveok60 < g_Vars.lvframe60 - TICKS(60)
|
|
|| chr->act_attackwalk.frame60count > chr->act_attackwalk.frame60max) {
|
|
if (modelGetCurAnimFrame(model) > modelGetNumAnimFrames(model) * 0.5f) {
|
|
modelSetAnimSpeedAuto(model, 0, 16);
|
|
} else {
|
|
modelSetAnimSpeedAuto(model, modelGetNumAnimFrames(model) * 0.5f, 16);
|
|
}
|
|
|
|
chrRecordLastSeeTargetTime(chr);
|
|
chrStop(chr);
|
|
return;
|
|
}
|
|
|
|
// If within 3 metres of the player, stop
|
|
xdiff = targetprop->pos.x - prop->pos.x;
|
|
zdiff = targetprop->pos.z - prop->pos.z;
|
|
|
|
if (xdiff < 300 && xdiff > -300 && zdiff < 300 && zdiff > -300) {
|
|
chrRecordLastSeeTargetTime(chr);
|
|
chrStop(chr);
|
|
return;
|
|
}
|
|
|
|
if (func0f043f2c(chr, &targetprop->pos, 0, &chr->act_attackwalk.turnspeed)) {
|
|
chr->act_attackwalk.facedtarget = true;
|
|
}
|
|
|
|
if (chr->act_attackwalk.frame60count > TICKS(20)) {
|
|
func0f03e9f4(chr, chr->act_attackwalk.animcfg,
|
|
chr->act_attackwalk.firegun[HAND_LEFT],
|
|
chr->act_attackwalk.firegun[HAND_RIGHT], 1);
|
|
} else {
|
|
chrResetAimEndProperties(chr);
|
|
}
|
|
|
|
if (chr->act_attackwalk.facedtarget && chr->act_attackwalk.frame60count > TICKS(30)) {
|
|
for (i = 0; i < 2; i++) {
|
|
if (chr->act_attackwalk.firegun[i]) {
|
|
if (!chr->act_attackwalk.everytick[i]) {
|
|
chrSetHandFiring(chr, i, true);
|
|
} else if (chr->act_attackwalk.frame60count > chr->act_attackwalk.nextshot60
|
|
&& (i == chr->act_attackwalk.nextgun || chr->act_attackwalk.everytick[chr->act_attackwalk.nextgun] == 0)) {
|
|
chr->act_attackwalk.nextshot60 = chr->act_attackwalk.frame60count;
|
|
|
|
if (chr->act_attackwalk.everytick[1 - i]) {
|
|
if (chr->act_attackwalk.singleshot[i]) {
|
|
chr->act_attackwalk.nextshot60 += TICKS(90);
|
|
} else {
|
|
chr->act_attackwalk.nextshot60 += TICKS(20);
|
|
}
|
|
} else {
|
|
if (chr->act_attackwalk.singleshot[i]) {
|
|
chr->act_attackwalk.nextshot60 += TICKS(180);
|
|
} else {
|
|
chr->act_attackwalk.nextshot60 += TICKS(40);
|
|
}
|
|
}
|
|
|
|
chr->act_attackwalk.nextgun = 1 - chr->act_attackwalk.nextgun;
|
|
|
|
chrSetHandFiring(chr, i, true);
|
|
} else {
|
|
chrSetHandFiring(chr, i, false);
|
|
}
|
|
} else {
|
|
chrSetHandFiring(chr, i, false);
|
|
}
|
|
}
|
|
} else {
|
|
chrSetHandFiring(chr, HAND_LEFT, false);
|
|
chrSetHandFiring(chr, HAND_RIGHT, false);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This function might be misnamed. It was named by isolating it and testing it
|
|
* with different inputs to see what it returns, but I couldn't determine how
|
|
* the range affects the latter part of the function.
|
|
*/
|
|
bool posIsMovingTowardsPosOrStoppedInRange(struct coord *prevpos, struct coord *moveddelta, struct coord *targetpos, f32 range)
|
|
{
|
|
struct coord prevdist;
|
|
f32 tmp;
|
|
|
|
prevdist.x = targetpos->x - prevpos->x;
|
|
prevdist.z = targetpos->z - prevpos->z;
|
|
|
|
if (moveddelta->f[0] == 0 && moveddelta->f[2] == 0) {
|
|
return prevdist.f[0] * prevdist.f[0] + prevdist.f[2] * prevdist.f[2] <= range * range;
|
|
}
|
|
|
|
tmp = moveddelta->f[0] * prevdist.f[0] + moveddelta->f[2] * prevdist.f[2];
|
|
|
|
if (tmp > 0) {
|
|
f32 sqmoveddist = moveddelta->f[0] * moveddelta->f[0] + moveddelta->f[2] * moveddelta->f[2];
|
|
f32 sqprevdist = prevdist.f[0] * prevdist.f[0] + prevdist.f[2] * prevdist.f[2];
|
|
|
|
if ((sqprevdist - range * range) * sqmoveddist <= tmp * tmp) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Return true if:
|
|
* - either prevpos or curpos is within the given range of targetpos, and
|
|
* - the prev -> cur delta is moving towards the targetpos or is stopped inside
|
|
* the range.
|
|
*
|
|
* This is a lateral check, meaning the Y value is not considered.
|
|
*/
|
|
bool posIsArrivingLaterallyAtPos(struct coord *prevpos, struct coord *curpos, struct coord *targetpos, f32 range)
|
|
{
|
|
struct coord moveddelta;
|
|
|
|
if (prevpos->x <= targetpos->x - range && curpos->x <= targetpos->x - range) {
|
|
return false;
|
|
}
|
|
|
|
if (prevpos->x >= targetpos->x + range && curpos->x >= targetpos->x + range) {
|
|
return false;
|
|
}
|
|
|
|
if (prevpos->z <= targetpos->z - range && curpos->z <= targetpos->z - range) {
|
|
return false;
|
|
}
|
|
|
|
if (prevpos->z >= targetpos->z + range && curpos->z >= targetpos->z + range) {
|
|
return false;
|
|
}
|
|
|
|
moveddelta.x = curpos->x - prevpos->x;
|
|
moveddelta.y = 0;
|
|
moveddelta.z = curpos->z - prevpos->z;
|
|
|
|
return posIsMovingTowardsPosOrStoppedInRange(prevpos, &moveddelta, targetpos, range);
|
|
}
|
|
|
|
/**
|
|
* Return true if:
|
|
* - either prevpos or curpos is within the given range of targetpos,
|
|
* - the prev -> cur delta is moving towards the targetpos or is stopped inside
|
|
* the range, and
|
|
* - either prevpos or curpos is within 150cm vertically of targetpos.
|
|
*/
|
|
bool posIsArrivingAtPos(struct coord *prevpos, struct coord *curpos, struct coord *targetpos, f32 range)
|
|
{
|
|
if (prevpos->y <= targetpos->y - 150 && curpos->y <= targetpos->y - 150) {
|
|
return false;
|
|
}
|
|
|
|
if (prevpos->y >= targetpos->y + 150 && curpos->y >= targetpos->y + 150) {
|
|
return false;
|
|
}
|
|
|
|
return posIsArrivingLaterallyAtPos(prevpos, curpos, targetpos, range);
|
|
}
|
|
|
|
void chrTickRunPos(struct chrdata *chr)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct model *model = chr->model;
|
|
u32 race = CHRRACE(chr);
|
|
f32 fVar6;
|
|
f32 zero;
|
|
f32 fVar7;
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrRunPosChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
chr->lastwalk60 = g_Vars.lvframe60;
|
|
|
|
if (chr->invalidmove == 1
|
|
|| g_Vars.lvframe60 - TICKS(60) > chr->lastmoveok60
|
|
|| posIsArrivingLaterallyAtPos(&chr->prevpos, &prop->pos, &chr->act_runpos.pos, chr->act_runpos.neardist)) {
|
|
if (race == RACE_HUMAN) {
|
|
modelGetAnimNum(model);
|
|
}
|
|
|
|
zero = 0;
|
|
fVar7 = modelGetCurAnimFrame(model);
|
|
fVar6 = fVar7 - zero;
|
|
|
|
if (fVar7 < 0) {
|
|
fVar6 += modelGetNumAnimFrames(model);
|
|
}
|
|
|
|
if (modelGetNumAnimFrames(model) * 0.5f < fVar6) {
|
|
zero = 0;
|
|
modelSetAnimSpeedAuto(model, modelGetNumAnimFrames(model) - zero, 16);
|
|
} else {
|
|
zero = 0;
|
|
fVar7 = modelGetNumAnimFrames(model) * 0.5f;
|
|
fVar6 = fVar7 - zero;
|
|
|
|
if (fVar7 < 0) {
|
|
fVar6 += modelGetNumAnimFrames(model);
|
|
}
|
|
|
|
modelSetAnimSpeedAuto(model, fVar6, 16);
|
|
}
|
|
|
|
chrStop(chr);
|
|
return;
|
|
}
|
|
|
|
func0f043f2c(chr, &chr->act_runpos.pos, 1, &chr->act_runpos.turnspeed);
|
|
|
|
if (chr->act_runpos.eta60 > 0) {
|
|
chr->act_runpos.eta60 -= g_Vars.lvupdate240_60;
|
|
} else {
|
|
fVar7 = 1;
|
|
|
|
if (race == RACE_HUMAN) {
|
|
if (modelGetAnimNum(model) == ANIM_RUNNING_ONEHANDGUN) {
|
|
fVar7 = func0f02dff0(ANIM_RUNNING_ONEHANDGUN);
|
|
} else {
|
|
fVar7 = func0f02dff0(ANIM_RUNNING_TWOHANDGUN);
|
|
}
|
|
} else if (race == RACE_SKEDAR) {
|
|
fVar7 = func0f02dff0(ANIM_SKEDAR_RUNNING);
|
|
}
|
|
|
|
chr->act_runpos.neardist += fVar7 * g_Vars.lvupdate240freal * modelGetAbsAnimSpeed(model);
|
|
}
|
|
}
|
|
|
|
void func0f044b68(struct coord *arg0, struct coord *arg1, struct coord *arg2)
|
|
{
|
|
struct coord sp0c;
|
|
struct coord sp00;
|
|
|
|
sp0c.x = arg1->x - arg0->x;
|
|
sp0c.y = arg1->y - arg0->y;
|
|
sp0c.z = arg1->z - arg0->z;
|
|
|
|
sp00.x = -arg2->z;
|
|
sp00.y = 0;
|
|
sp00.z = arg2->x;
|
|
|
|
if (sp00.f[0] * sp0c.f[0] + sp00.f[2] * sp0c.f[2] > 0) {
|
|
// empty
|
|
} else {
|
|
sp0c.x = arg0->x;
|
|
sp0c.y = arg0->y;
|
|
sp0c.z = arg0->z;
|
|
|
|
arg0->x = arg1->x;
|
|
arg0->y = arg1->y;
|
|
arg0->z = arg1->z;
|
|
|
|
arg1->x = sp0c.x;
|
|
arg1->y = sp0c.y;
|
|
arg1->z = sp0c.z;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check to see if the chr can see the next pos in their route.
|
|
*
|
|
* If an obstacle is found, set the leftpos and rightpos coordinates to the
|
|
* left and right corners of the object from the chr's perspective and return
|
|
* false.
|
|
*
|
|
* Return true if path ahead is clear.
|
|
*
|
|
* This is similar to chrNavCheckForObstacle. The difference between the two are
|
|
* not yet understood.
|
|
*/
|
|
bool chrNavCanSeeNextPos(struct chrdata *chr, struct coord *chrpos, s16 *chrrooms, struct coord *aimpos, struct coord *leftpos, struct coord *rightpos, f32 negchrradius, f32 chrradius, s32 cdtypes, s32 arg9)
|
|
{
|
|
struct coord spd4;
|
|
f32 spd0;
|
|
f32 spcc;
|
|
f32 spc8;
|
|
f32 spc4;
|
|
f32 norm;
|
|
bool spbc = false;
|
|
bool spb8 = false;
|
|
struct coord spac;
|
|
struct coord spa0;
|
|
struct coord sp94;
|
|
struct coord sp88;
|
|
bool result = false;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius2;
|
|
struct coord sp6c;
|
|
struct coord sp60;
|
|
s16 sp50[8];
|
|
s16 sp40[8];
|
|
struct prop *prop = chr->prop;
|
|
|
|
chrGetBbox(prop, &radius2, &ymax, &ymin);
|
|
|
|
spd4.x = aimpos->x - chrpos->x;
|
|
spd4.y = 0.0f;
|
|
spd4.z = aimpos->z - chrpos->z;
|
|
|
|
if (spd4.f[0] == 0.0f && spd4.f[2] == 0.0f) {
|
|
return true;
|
|
}
|
|
|
|
norm = 1.0f / sqrtf(spd4.f[0] * spd4.f[0] + spd4.f[2] * spd4.f[2]);
|
|
spd4.x *= norm;
|
|
spd4.z *= norm;
|
|
|
|
spd0 = spd4.x * chrradius * 0.95f;
|
|
spcc = spd4.z * chrradius * 0.95f;
|
|
spc8 = spd4.x * chrradius * 1.2f;
|
|
spc4 = spd4.z * chrradius * 1.2f;
|
|
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
sp6c.x = chrpos->x + spcc;
|
|
sp6c.y = chrpos->y;
|
|
sp6c.z = chrpos->z - spd0;
|
|
sp60.x = (spd4.x * negchrradius) + (aimpos->x + spc4);
|
|
sp60.y = aimpos->y;
|
|
sp60.z = (spd4.z * negchrradius) + (aimpos->z - spc8);
|
|
|
|
if (cd0002da50(chrpos, chrrooms, &sp6c, sp50, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION
|
|
|| cd0002d7c0(&sp6c, sp50, &sp60, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) {
|
|
spbc = true;
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cd00024e4c(&spac, &spa0, 14154, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_FINAL
|
|
cd00024e4c(&spac, &spa0, 14151, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_BETA
|
|
cd00024e4c(&spac, &spa0, 14146, "chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(&spac, &spa0, 14145, "chraction.c");
|
|
#else
|
|
cd00024e4c(&spac, &spa0, 14158, "chraction.c");
|
|
#endif
|
|
func0f044b68(&spac, &spa0, &spd4);
|
|
}
|
|
|
|
sp6c.x = chrpos->x - spcc;
|
|
sp6c.y = chrpos->y;
|
|
sp6c.z = chrpos->z + spd0;
|
|
|
|
sp60.x = (spd4.x * negchrradius) + (aimpos->x - spc4);
|
|
sp60.y = aimpos->y;
|
|
sp60.z = (spd4.z * negchrradius) + (aimpos->z + spc8);
|
|
|
|
if (cd0002da50(chrpos, chrrooms, &sp6c, sp50, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION
|
|
|| cd0002d7c0(&sp6c, chrrooms, &sp60, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) {
|
|
spb8 = true;
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cd00024e4c(&sp94, &sp88, 14169, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_FINAL
|
|
cd00024e4c(&sp94, &sp88, 14166, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_BETA
|
|
cd00024e4c(&sp94, &sp88, 14161, "chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(&sp94, &sp88, 14160, "chraction.c");
|
|
#else
|
|
cd00024e4c(&sp94, &sp88, 14173, "chraction.c");
|
|
#endif
|
|
func0f044b68(&sp94, &sp88, &spd4);
|
|
}
|
|
|
|
if (spbc && spb8) {
|
|
func0f044b68(&spac, &sp94, &spd4);
|
|
func0f044b68(&spa0, &sp88, &spd4);
|
|
|
|
leftpos->x = spac.x;
|
|
leftpos->y = spac.y;
|
|
leftpos->z = spac.z;
|
|
|
|
rightpos->x = sp88.x;
|
|
rightpos->y = sp88.y;
|
|
rightpos->z = sp88.z;
|
|
} else if (spbc) {
|
|
leftpos->x = spac.x;
|
|
leftpos->y = spac.y;
|
|
leftpos->z = spac.z;
|
|
|
|
rightpos->x = spa0.x;
|
|
rightpos->y = spa0.y;
|
|
rightpos->z = spa0.z;
|
|
} else if (spb8) {
|
|
leftpos->x = sp94.x;
|
|
leftpos->y = sp94.y;
|
|
leftpos->z = sp94.z;
|
|
|
|
rightpos->x = sp88.x;
|
|
rightpos->y = sp88.y;
|
|
rightpos->z = sp88.z;
|
|
} else if (cd0002da50(chrpos, chrrooms, aimpos, sp40, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION
|
|
&& (!arg9 || cd0002a6fc(chrpos, aimpos, chrradius, sp40, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION)) {
|
|
result = true;
|
|
} else {
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cd00024e4c(leftpos, rightpos, 14239, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_FINAL
|
|
cd00024e4c(leftpos, rightpos, 14236, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_BETA
|
|
cd00024e4c(leftpos, rightpos, 14231, "chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(leftpos, rightpos, 14230, "chraction.c");
|
|
#else
|
|
cd00024e4c(leftpos, rightpos, 14243, "chraction.c");
|
|
#endif
|
|
func0f044b68(leftpos, rightpos, &spd4);
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Check if the path ahead contains an obstacle that the chr should route
|
|
* around.
|
|
*
|
|
* If an obstacle is found, set the leftpos and rightpos coordinates to the
|
|
* left and right corners of the object from the chr's perspective and return
|
|
* false.
|
|
*
|
|
* Return true if path ahead is clear.
|
|
*
|
|
* This is similar to chrNavCanSeeNextPos. The only difference is this one uses
|
|
* the value1 and value2 variables.
|
|
*/
|
|
bool chrNavCheckForObstacle(struct chrdata *chr, struct coord *chrpos, s16 *chrrooms, struct coord *aimpos, struct coord *leftpos, struct coord *rightpos, f32 negchrradius, f32 chrradius, s32 cdtypes, bool hasobstacle)
|
|
{
|
|
struct coord spd4;
|
|
f32 spd0;
|
|
f32 spcc;
|
|
f32 spc8;
|
|
f32 spc4;
|
|
f32 norm;
|
|
bool spbc = false;
|
|
bool spb8 = false;
|
|
struct coord spac;
|
|
struct coord spa0;
|
|
struct coord sp94;
|
|
struct coord sp88;
|
|
bool result = false;
|
|
f32 value1;
|
|
f32 value2;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius2;
|
|
struct coord sp6c;
|
|
struct coord sp60;
|
|
s16 sp50[8];
|
|
s16 sp40[8];
|
|
struct prop *prop = chr->prop;
|
|
|
|
chrGetBbox(prop, &radius2, &ymax, &ymin);
|
|
|
|
spd4.x = aimpos->x - chrpos->x;
|
|
spd4.y = 0.0f;
|
|
spd4.z = aimpos->z - chrpos->z;
|
|
|
|
if (spd4.f[0] == 0.0f && spd4.f[2] == 0.0f) {
|
|
return true;
|
|
}
|
|
|
|
norm = 1.0f / sqrtf(spd4.f[0] * spd4.f[0] + spd4.f[2] * spd4.f[2]);
|
|
spd4.x *= norm;
|
|
spd4.z *= norm;
|
|
|
|
spd0 = spd4.x * chrradius * 0.95f;
|
|
spcc = spd4.z * chrradius * 0.95f;
|
|
spc8 = spd4.x * chrradius * 1.2f;
|
|
spc4 = spd4.z * chrradius * 1.2f;
|
|
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
sp6c.x = chrpos->x + spcc;
|
|
sp6c.y = chrpos->y;
|
|
sp6c.z = chrpos->z - spd0;
|
|
sp60.x = (spd4.x * negchrradius) + (aimpos->x + spc4);
|
|
sp60.y = aimpos->y;
|
|
sp60.z = (spd4.z * negchrradius) + (aimpos->z - spc8);
|
|
|
|
if (cd0002da50(chrpos, chrrooms, &sp6c, sp50, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION
|
|
|| cd0002d7c0(&sp6c, sp50, &sp60, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) {
|
|
spbc = true;
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cd00024e4c(&spac, &spa0, 14319, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_FINAL
|
|
cd00024e4c(&spac, &spa0, 14316, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_BETA
|
|
cd00024e4c(&spac, &spa0, 14311, "chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(&spac, &spa0, 14310, "chraction.c");
|
|
#else
|
|
cd00024e4c(&spac, &spa0, 14323, "chraction.c");
|
|
#endif
|
|
func0f044b68(&spac, &spa0, &spd4);
|
|
value1 = cd00024e40();
|
|
}
|
|
|
|
sp6c.x = chrpos->x - spcc;
|
|
sp6c.y = chrpos->y;
|
|
sp6c.z = chrpos->z + spd0;
|
|
|
|
sp60.x = (spd4.x * negchrradius) + (aimpos->x - spc4);
|
|
sp60.y = aimpos->y;
|
|
sp60.z = (spd4.z * negchrradius) + (aimpos->z + spc8);
|
|
|
|
if (cd0002da50(chrpos, chrrooms, &sp6c, sp50, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION
|
|
|| cd0002d7c0(&sp6c, chrrooms, &sp60, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) == CDRESULT_COLLISION) {
|
|
spb8 = true;
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cd00024e4c(&sp94, &sp88, 14334, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_FINAL
|
|
cd00024e4c(&sp94, &sp88, 14331, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_BETA
|
|
cd00024e4c(&sp94, &sp88, 14326, "chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(&sp94, &sp88, 14325, "chraction.c");
|
|
#else
|
|
cd00024e4c(&sp94, &sp88, 14338, "chraction.c");
|
|
#endif
|
|
func0f044b68(&sp94, &sp88, &spd4);
|
|
value2 = cd00024e40();
|
|
}
|
|
|
|
if (spbc && spb8) {
|
|
if (value1 < value2) {
|
|
leftpos->x = spac.x;
|
|
leftpos->y = spac.y;
|
|
leftpos->z = spac.z;
|
|
|
|
rightpos->x = spa0.x;
|
|
rightpos->y = spa0.y;
|
|
rightpos->z = spa0.z;
|
|
} else {
|
|
leftpos->x = sp94.x;
|
|
leftpos->y = sp94.y;
|
|
leftpos->z = sp94.z;
|
|
|
|
rightpos->x = sp88.x;
|
|
rightpos->y = sp88.y;
|
|
rightpos->z = sp88.z;
|
|
}
|
|
} else if (spbc) {
|
|
leftpos->x = spac.x;
|
|
leftpos->y = spac.y;
|
|
leftpos->z = spac.z;
|
|
|
|
rightpos->x = spa0.x;
|
|
rightpos->y = spa0.y;
|
|
rightpos->z = spa0.z;
|
|
} else if (spb8) {
|
|
leftpos->x = sp94.x;
|
|
leftpos->y = sp94.y;
|
|
leftpos->z = sp94.z;
|
|
|
|
rightpos->x = sp88.x;
|
|
rightpos->y = sp88.y;
|
|
rightpos->z = sp88.z;
|
|
} else if (cd0002da50(chrpos, chrrooms, aimpos, sp40, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION
|
|
&& (!hasobstacle || cd0002a6fc(chrpos, aimpos, chrradius, sp40, cdtypes, 1, ymax - prop->pos.y, ymin - prop->pos.y) != CDRESULT_COLLISION)) {
|
|
result = true;
|
|
} else {
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cd00024e4c(leftpos, rightpos, 14404, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_FINAL
|
|
cd00024e4c(leftpos, rightpos, 14401, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_BETA
|
|
cd00024e4c(leftpos, rightpos, 14396, "chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cd00024e4c(leftpos, rightpos, 14395, "chraction.c");
|
|
#else
|
|
cd00024e4c(leftpos, rightpos, 14408, "chraction.c");
|
|
#endif
|
|
func0f044b68(leftpos, rightpos, &spd4);
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool chrNavTryObstacle(struct chrdata *chr, struct coord *arg1, bool arg2, struct coord *arg3, f32 radius, bool arg5, struct coord *nextpos, struct waydata *waydata, f32 arg8, s32 cdtypes, s32 arg10)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct coord sp68;
|
|
struct coord sp5c;
|
|
f32 norm;
|
|
f32 angle;
|
|
struct coord sp48;
|
|
struct coord *sp44;
|
|
struct coord *sp40;
|
|
|
|
if (arg2) {
|
|
sp44 = arg1;
|
|
sp40 = arg3;
|
|
} else {
|
|
sp44 = arg3;
|
|
sp40 = arg1;
|
|
}
|
|
|
|
sp68.x = arg1->x - prop->pos.x;
|
|
sp68.y = 0.0f;
|
|
sp68.z = arg1->z - prop->pos.z;
|
|
|
|
if (sp68.f[0] != 0.0f || sp68.f[2] != 0.0f) {
|
|
norm = sqrtf(sp68.f[0] * sp68.f[0] + sp68.f[2] * sp68.f[2]);
|
|
|
|
if (norm > 0.0f) {
|
|
norm = 1.0f / norm;
|
|
sp68.x *= radius * norm;
|
|
sp68.z *= radius * norm;
|
|
} else {
|
|
norm = 1.0f;
|
|
sp68.z = radius * norm;
|
|
}
|
|
} else {
|
|
norm = 1.0f;
|
|
sp68.z = radius * norm;
|
|
}
|
|
|
|
if (radius * norm > 1.0f) {
|
|
angle = 0.7852731347084f;
|
|
} else {
|
|
angle = acosf(radius * norm);
|
|
}
|
|
|
|
if (!arg2 && angle != 0.0f) {
|
|
angle = M_BADTAU - angle;
|
|
}
|
|
|
|
sp48.x = -cosf(angle) * sp68.f[0] + sinf(angle) * sp68.f[2];
|
|
sp48.y = 0.0f;
|
|
sp48.z = -sinf(angle) * sp68.f[0] - cosf(angle) * sp68.f[2];
|
|
|
|
sp5c.x = arg1->x + sp48.f[0];
|
|
sp5c.y = arg1->y;
|
|
sp5c.z = arg1->z + sp48.f[2];
|
|
|
|
if (chrNavCanSeeNextPos(chr, &prop->pos, prop->rooms, &sp5c, sp44, sp40, arg8, chr->radius, cdtypes, 1)) {
|
|
if (!arg5 || func0f03645c(chr, &prop->pos, prop->rooms, &sp5c, nextpos, cdtypes)) {
|
|
if (arg10) {
|
|
waydata->gotaimposobj = true;
|
|
waydata->aimposobj.x = sp5c.x;
|
|
waydata->aimposobj.y = sp5c.y;
|
|
waydata->aimposobj.z = sp5c.z;
|
|
} else {
|
|
waydata->gotaimpos = true;
|
|
waydata->aimpos.x = sp5c.x;
|
|
waydata->aimpos.y = sp5c.y;
|
|
waydata->aimpos.z = sp5c.z;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
const char var7f1a8be8[] = "CHARS -> FRAMETIMESCALEI(240) = %d";
|
|
const char var7f1a8c0c[] = "CHARS -> numseenbond1 \t= %d/%d";
|
|
const char var7f1a8c30[] = "CHARS -> numseenbond2 \t= %d/%d";
|
|
const char var7f1a8c54[] = "CHARS -> numseenbond3 \t= %d/%d";
|
|
const char var7f1a8c78[] = "CHARS -> numseenbond \t= %d/%d";
|
|
#endif
|
|
|
|
const char var7f1a8c9c[] = "CHARS -> DEAD = %d/%d";
|
|
const char var7f1a8cb4[] = "chrdisttopad : %x -> %d : Dist=%f";
|
|
|
|
/**
|
|
* Check for doors in front of the chr and open them if possible.
|
|
*
|
|
* I'm guessing the coord argument is a position in front of the chr, and the
|
|
* collision check is looking for doors between the chr and that point.
|
|
*
|
|
* - Multiplayer simulants can open any doors
|
|
* - Solo chrs cannot open doors with OBJFLAG2_AICANNOTUSE
|
|
* - In ntsc-beta, solo chrs can bring down lasers even if they have that flag
|
|
*
|
|
* The chr must be within 200cm of the door unless it's a laser.
|
|
*/
|
|
struct prop *chrOpenDoor(struct chrdata *chr, struct coord *coord)
|
|
{
|
|
struct prop *doorprop = NULL;
|
|
|
|
if (cd0002d7c0(&chr->prop->pos, chr->prop->rooms, coord, 0x5020, 1, 0, 0) == CDRESULT_COLLISION) {
|
|
doorprop = cdGetObstacle();
|
|
}
|
|
|
|
if (doorprop) {
|
|
struct doorobj *door = doorprop->door;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (chr->aibot || (door->base.flags2 & OBJFLAG2_AICANNOTUSE) == 0)
|
|
#else
|
|
if (chr->aibot
|
|
|| (door->base.flags2 & OBJFLAG2_AICANNOTUSE) == 0
|
|
|| (door->doorflags & DOORFLAG_DAMAGEONCONTACT))
|
|
#endif
|
|
{
|
|
f32 xdiff = doorprop->pos.x - chr->prop->pos.x;
|
|
f32 zdiff = doorprop->pos.z - chr->prop->pos.z;
|
|
|
|
if (xdiff * xdiff + zdiff * zdiff < 200 * 200 || (door->doorflags & DOORFLAG_DAMAGEONCONTACT)) {
|
|
chrGoPosClearRestartTtl(chr);
|
|
doorsChooseSwingDirection(chr->prop, doorprop->door);
|
|
|
|
if (!doorCallLift(doorprop, false)) {
|
|
doorsRequestMode(doorprop->door, DOORMODE_OPENING);
|
|
}
|
|
} else {
|
|
doorprop = NULL;
|
|
}
|
|
} else {
|
|
doorprop = NULL;
|
|
}
|
|
}
|
|
|
|
return doorprop;
|
|
}
|
|
|
|
/**
|
|
* Tick a chr's navigation process when they are using the "main" method of
|
|
* navigating.
|
|
*
|
|
* Main refers to the chr being on screen or close to on screen, where all
|
|
* collision checks are enabled. This is opposed to the magic method, where
|
|
* they are off screen and the collision checks are skipped.
|
|
*
|
|
* The chr will generally move towards the nextpos, which is the position of the
|
|
* next pad/corner in the route, and open doors along the way. However they must
|
|
* also check for obstacles ahead of them such as other chrs or doors which have
|
|
* opened into their path. If one is found, the chr routes around the obstacle
|
|
* and then to the next pos again.
|
|
*/
|
|
void chrNavTickMain(struct chrdata *chr, struct coord *nextpos, struct waydata *waydata, bool arg3)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct coord sp100;
|
|
struct coord spf4;
|
|
s32 i;
|
|
s32 cdtypes;
|
|
|
|
// By default, do collision checks for everything except doors that AI can
|
|
// open, but if they're blocking a door then include all doors
|
|
cdtypes = (CDTYPE_ALL & ~CDTYPE_DOORS) | CDTYPE_DOORSLOCKEDTOAI;
|
|
|
|
if (chr->hidden & CHRHFLAG_BLOCKINGDOOR) {
|
|
cdtypes = CDTYPE_ALL;
|
|
}
|
|
|
|
for (i = 0; i < 1; i++) {
|
|
if (0.0f);
|
|
|
|
if (waydata->mode == WAYMODE_INIT || waydata->mode == WAYMODE_RETRY) {
|
|
sp100.x = nextpos->x;
|
|
sp100.y = nextpos->y;
|
|
sp100.z = nextpos->z;
|
|
|
|
// Check to see if the chr can see the next pad. This is almost
|
|
// always true, but if the chr has tried to avoid an object they
|
|
// may have gone behind a wall and can't see the pad any more.
|
|
if (chrNavCanSeeNextPos(chr, &prop->pos, prop->rooms, &sp100, &waydata->obstacleleft, &waydata->obstacleright, -chr->radius, chr->radius, CDTYPE_PATHBLOCKER | CDTYPE_BG, arg3)) {
|
|
// Can see the next pad
|
|
waydata->gotaimpos = true;
|
|
waydata->aimpos.x = sp100.x;
|
|
waydata->aimpos.y = sp100.y;
|
|
waydata->aimpos.z = sp100.z;
|
|
waydata->mode = WAYMODE_HAVEAIMPOS;
|
|
} else if (waydata->mode == WAYMODE_INIT) {
|
|
waydata->mode = WAYMODE_LOST1;
|
|
waydata->iter = 0;
|
|
} else if (waydata->mode == WAYMODE_RETRY) {
|
|
waydata->mode = WAYMODE_LOST2;
|
|
waydata->iter = 0;
|
|
}
|
|
} else if (waydata->mode == WAYMODE_LOST1) {
|
|
// Chr has tried to avoid an obstacle, and in the process can no
|
|
// longer see the next pad. The chr will try to get back on the
|
|
// route by navigating to either side of the obstacle they were
|
|
// trying to avoid.
|
|
f32 wantclearance = chr->radius * 1.26f;
|
|
|
|
if (chrNavTryObstacle(chr, &waydata->obstacleleft, true, &spf4, wantclearance, true, nextpos, waydata, 0, CDTYPE_PATHBLOCKER | CDTYPE_BG, 0)) {
|
|
// Will go to left side
|
|
waydata->mode = WAYMODE_HAVEAIMPOS;
|
|
} else if (chrNavTryObstacle(chr, &waydata->obstacleright, false, &spf4, wantclearance, true, nextpos, waydata, 0, CDTYPE_PATHBLOCKER | CDTYPE_BG, 0)) {
|
|
// Will go to right side
|
|
waydata->mode = WAYMODE_HAVEAIMPOS;
|
|
} else {
|
|
// Can't see the obstacle either!
|
|
// Remain in LOST1 for 5 iterations to see if line of sight
|
|
// comes back. If not, retry the next pad again.
|
|
waydata->iter++;
|
|
|
|
if (waydata->iter > 5) {
|
|
waydata->mode = WAYMODE_RETRY;
|
|
}
|
|
}
|
|
} else if (waydata->mode == WAYMODE_LOST2) {
|
|
// Chr has gone through LOST1 without seeing the obstacle, then
|
|
// tried to find the next pad but can't see that either. Try
|
|
// navigating to the obstacle again, but with different arguments.
|
|
// This is a more desparate attempt at returning to the path.
|
|
f32 wantclearance = chr->radius * 1.26f;
|
|
u32 stack;
|
|
|
|
if (chrNavTryObstacle(chr, &waydata->obstacleleft, true, &spf4, wantclearance, false, NULL, waydata, 0, CDTYPE_PATHBLOCKER | CDTYPE_BG, 0)) {
|
|
// Will go to left side
|
|
waydata->mode = WAYMODE_HAVEAIMPOS;
|
|
} else if (chrNavTryObstacle(chr, &waydata->obstacleright, false, &spf4, wantclearance, false, NULL, waydata, 0, CDTYPE_PATHBLOCKER | CDTYPE_BG, 0)) {
|
|
// Will go to right side
|
|
waydata->mode = WAYMODE_HAVEAIMPOS;
|
|
} else {
|
|
// Still can't see the obstacle using the desparate check.
|
|
// Remain in LOST2 for 5 iterations to see if line of sight
|
|
// comes back.
|
|
waydata->iter++;
|
|
|
|
if (waydata->iter > 5) {
|
|
// Clear any references to the obstacle we were trying to
|
|
// avoid and attempt to restart the process. I don't think
|
|
// this is likely to work, but there's nothing else that can
|
|
// be done.
|
|
waydata->gotaimposobj = waydata->gotaimpos = false;
|
|
waydata->aimposobj.x = waydata->aimpos.x = nextpos->x;
|
|
waydata->aimposobj.y = waydata->aimpos.y = nextpos->y;
|
|
waydata->aimposobj.z = waydata->aimpos.z = nextpos->z;
|
|
waydata->mode = WAYMODE_INIT;
|
|
}
|
|
}
|
|
} else if (waydata->mode == WAYMODE_HAVEAIMPOS) {
|
|
// Chr is happily walking towards a position (aim pos).
|
|
// The position could be the next pad, or it could be an arbitrary
|
|
// position next to an obstacle that has to be routed around.
|
|
// Either way, check that there's no new obstacles between the chr
|
|
// and their aim pos.
|
|
bool hasobstacle = true;
|
|
|
|
if (!arg3
|
|
&& nextpos->x == waydata->aimpos.x
|
|
&& nextpos->y == waydata->aimpos.y
|
|
&& nextpos->z == waydata->aimpos.z) {
|
|
hasobstacle = false;
|
|
}
|
|
|
|
if (chrNavCheckForObstacle(chr, &prop->pos, prop->rooms, &waydata->aimpos, &waydata->obstacleleft, &waydata->obstacleright, -chr->radius, chr->radius, cdtypes, hasobstacle)) {
|
|
// No obstacle ahead
|
|
waydata->gotaimposobj = true;
|
|
waydata->mode = WAYMODE_INIT;
|
|
waydata->aimposobj.x = waydata->aimpos.x;
|
|
waydata->aimposobj.y = waydata->aimpos.y;
|
|
waydata->aimposobj.z = waydata->aimpos.z;
|
|
} else {
|
|
// Obstacle ahead
|
|
waydata->mode = WAYMODE_NEWOBSTACLE;
|
|
waydata->iter = 0;
|
|
}
|
|
} else if (waydata->mode == WAYMODE_NEWOBSTACLE) {
|
|
// Chr has just noticed an obstacle ahead of them which they need to
|
|
// route around. The obstacleleft and obstacleright coordinates are
|
|
// already populated and they indicate the left and right corners of
|
|
// the object. This part of the code decides which side to use and
|
|
// calculates some turning angles.
|
|
f32 f20;
|
|
u32 stack;
|
|
f32 spd0;
|
|
f32 spcc;
|
|
u32 stack2;
|
|
f32 f24 = chr->radius * 1.26f;
|
|
|
|
f20 = atan2f(waydata->aimpos.x - prop->pos.x, waydata->aimpos.z - prop->pos.z);
|
|
spd0 = f20 - atan2f(waydata->obstacleleft.x - prop->pos.x, waydata->obstacleleft.z - prop->pos.z);
|
|
spcc = f20 - atan2f(waydata->obstacleright.x - prop->pos.x, waydata->obstacleright.z - prop->pos.z);
|
|
|
|
if (spd0 < 0) {
|
|
spd0 += M_BADTAU;
|
|
}
|
|
|
|
if (spd0 >= M_BADPI) {
|
|
spd0 -= M_BADTAU;
|
|
}
|
|
|
|
if (spd0 < 0) {
|
|
spd0 = -spd0;
|
|
}
|
|
|
|
if (spcc < 0) {
|
|
spcc += M_BADTAU;
|
|
}
|
|
|
|
if (spcc >= M_BADPI) {
|
|
spcc -= M_BADTAU;
|
|
}
|
|
|
|
if (spcc < 0) {
|
|
spcc = -spcc;
|
|
}
|
|
|
|
if (spd0 < spcc) {
|
|
f32 spc0;
|
|
f32 spbc;
|
|
u32 stack;
|
|
f32 f22 = f24 * 1.1f;
|
|
|
|
if (chrNavTryObstacle(chr, &waydata->obstacleleft, true, &spf4, f24, false, NULL, waydata, f22, cdtypes, 1)) {
|
|
waydata->mode = WAYMODE_INIT;
|
|
break;
|
|
}
|
|
|
|
spc0 = f20 - atan2f(waydata->obstacleleft.x - prop->pos.x, waydata->obstacleleft.z - prop->pos.z);
|
|
spbc = f20 - atan2f(spf4.x - prop->pos.x, spf4.z - prop->pos.z);
|
|
|
|
if (spc0 < 0) {
|
|
spc0 += M_BADTAU;
|
|
}
|
|
|
|
if (spc0 >= M_BADPI) {
|
|
spc0 -= M_BADTAU;
|
|
}
|
|
|
|
if (spc0 < 0) {
|
|
spc0 = -spc0;
|
|
}
|
|
|
|
if (spbc < 0) {
|
|
spbc += M_BADTAU;
|
|
}
|
|
|
|
if (spbc >= M_BADPI) {
|
|
spbc -= M_BADTAU;
|
|
}
|
|
|
|
if (spbc < 0) {
|
|
spbc = -spbc;
|
|
}
|
|
|
|
if (spbc < spc0) {
|
|
if (chrNavTryObstacle(chr, &spf4, false, &spf4, f24, false, NULL, waydata, f22, cdtypes, 1)) {
|
|
waydata->mode = WAYMODE_INIT;
|
|
break;
|
|
}
|
|
}
|
|
} else {
|
|
f32 spb0;
|
|
f32 spac;
|
|
f32 f22 = f24 * 1.1f;
|
|
|
|
if (chrNavTryObstacle(chr, &waydata->obstacleright, false, &spf4, f24, false, NULL, waydata, f22, cdtypes, 1)) {
|
|
waydata->mode = WAYMODE_INIT;
|
|
break;
|
|
}
|
|
|
|
spb0 = f20 - atan2f(waydata->obstacleright.x - prop->pos.x, waydata->obstacleright.z - prop->pos.z);
|
|
spac = f20 - atan2f(spf4.x - prop->pos.x, spf4.z - prop->pos.z);
|
|
|
|
if (spb0 < 0) {
|
|
spb0 += M_BADTAU;
|
|
}
|
|
|
|
if (spb0 >= M_BADPI) {
|
|
spb0 -= M_BADTAU;
|
|
}
|
|
|
|
if (spb0 < 0) {
|
|
spb0 = -spb0;
|
|
}
|
|
|
|
if (spac < 0) {
|
|
spac += M_BADTAU;
|
|
}
|
|
|
|
if (spac >= M_BADPI) {
|
|
spac -= M_BADTAU;
|
|
}
|
|
|
|
if (spac < 0) {
|
|
spac = -spac;
|
|
}
|
|
|
|
if (spac < spb0) {
|
|
if (chrNavTryObstacle(chr, &spf4, true, &spf4, f24, false, NULL, waydata, f22, cdtypes, 1)) {
|
|
waydata->mode = WAYMODE_INIT;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
waydata->iter++;
|
|
|
|
if (waydata->iter > 5) {
|
|
waydata->gotaimposobj = false;
|
|
waydata->mode = WAYMODE_INIT;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!waydata->gotaimposobj) {
|
|
waydata->aimposobj.x = waydata->aimpos.x;
|
|
waydata->aimposobj.y = waydata->aimpos.y;
|
|
waydata->aimposobj.z = waydata->aimpos.z;
|
|
}
|
|
|
|
// Every 10 ticks, attempt to open any door in front of the chr
|
|
if (waydata->age % 10 == 0) {
|
|
struct prop *doorprop = chrOpenDoor(chr, &waydata->aimposobj);
|
|
|
|
// Consider returning to stand animation while door is opening
|
|
if (doorprop
|
|
&& chr->aibot == NULL
|
|
&& (chr->hidden & CHRHFLAG_BLOCKINGDOOR) == 0
|
|
&& !chrGoPosIsWaiting(chr)) {
|
|
chrChooseStandAnimation(chr, 16);
|
|
chr->lastmoveok60 = g_Vars.lvframe60;
|
|
}
|
|
|
|
// Resume moving if there's no longer a door in the way
|
|
// or if the chr is blocking the door
|
|
if (!doorprop || (chr->hidden & CHRHFLAG_BLOCKINGDOOR)) {
|
|
if (chr->aibot == NULL
|
|
&& chrGoPosIsWaiting(chr)
|
|
&& chr->liftaction != LIFTACTION_WAITINGFORLIFT
|
|
&& chr->liftaction != LIFTACTION_WAITINGONLIFT) {
|
|
if (chr->actiontype == ACT_PATROL) {
|
|
chrPatrolChooseAnimation(chr);
|
|
} else {
|
|
chrGoPosChooseAnimation(chr);
|
|
}
|
|
}
|
|
|
|
if (!doorprop) {
|
|
chr->hidden &= ~CHRHFLAG_BLOCKINGDOOR;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Handle turning and anim speed
|
|
if (chr->actiontype == ACT_PATROL) {
|
|
func0f043f2c(chr, &waydata->aimposobj, 0, &chr->act_patrol.turnspeed);
|
|
} else {
|
|
chr->unk32c_21 = chr->act_gopos.turnspeed != 0;
|
|
|
|
func0f043f2c(chr, &waydata->aimposobj, chr->act_gopos.flags, &chr->act_gopos.turnspeed);
|
|
|
|
if (chr->aibot == NULL && !chrGoPosIsWaiting(chr)) {
|
|
if ((chr->act_gopos.flags & GOPOSMASK_SPEED) == GOPOSFLAG_RUN) {
|
|
if (chr->act_gopos.turnspeed) {
|
|
if (!chr->unk32c_21) {
|
|
modelSetAnimSpeed(chr->model, 0.25f, 8);
|
|
}
|
|
} else {
|
|
if (chr->unk32c_21) {
|
|
if (chr->chrflags & CHRCFLAG_RUNFASTER) {
|
|
modelSetAnimSpeed(chr->model, 0.65f, 32);
|
|
} else {
|
|
modelSetAnimSpeed(chr->model, 0.5f, 32);
|
|
}
|
|
}
|
|
}
|
|
} else if ((chr->act_gopos.flags & GOPOSMASK_SPEED) == GOPOSFLAG_JOG) {
|
|
if (chr->act_gopos.turnspeed) {
|
|
modelSetAnimSpeed(chr->model, 0.4f, 0);
|
|
} else {
|
|
modelSetAnimSpeed(chr->model, 0.5f, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool chrGoPosUpdateLiftAction(struct chrdata *chr, u32 curpadflags, bool arg2, bool arrivingatlift, s16 curpadnum, s32 nextpadnum)
|
|
{
|
|
bool advance = false;
|
|
struct pad nextpad;
|
|
u32 nextpadflags = 0;
|
|
f32 nextground;
|
|
f32 lifty;
|
|
struct liftobj *lift;
|
|
struct prop *liftprop = liftFindByPad(curpadnum);
|
|
u32 stack;
|
|
|
|
if (!liftprop) {
|
|
return false;
|
|
}
|
|
|
|
lift = (struct liftobj *) liftprop->obj;
|
|
|
|
lifty = liftGetY(lift);
|
|
|
|
if (nextpadnum >= 0) {
|
|
padUnpack(nextpadnum, PADFIELD_POS | PADFIELD_ROOM | PADFIELD_FLAGS, &nextpad);
|
|
nextpadflags = nextpad.flags;
|
|
}
|
|
|
|
if (curpadflags & PADFLAG_AIWAITLIFT) {
|
|
if (nextpadflags & PADFLAG_AIONLIFT) {
|
|
if (arrivingatlift || chr->liftaction == LIFTACTION_WAITINGFORLIFT) {
|
|
if (nextpadflags);
|
|
|
|
// Begin entering lift if lift is under 40cm above this level
|
|
advance = (lifty <= chr->manground + 40);
|
|
|
|
// ...and (if solo mode) lift is over 1m under this level
|
|
// (this logic allows MP simulants to drop down onto lifts)
|
|
if (!g_Vars.normmplayerisrunning && advance) {
|
|
advance = (lifty > chr->manground - 100);
|
|
}
|
|
|
|
// ...and if the lift has a door, is at least halfway open
|
|
if (advance && lift->doors[lift->levelcur] && lift->doors[lift->levelcur]->frac < 0.5f) {
|
|
advance = false;
|
|
}
|
|
}
|
|
|
|
if (!advance) {
|
|
if (arrivingatlift && chr->liftaction != LIFTACTION_WAITINGFORLIFT) {
|
|
// Just arrived at lift
|
|
chr->liftaction = LIFTACTION_WAITINGFORLIFT;
|
|
|
|
chrChooseStandAnimation(chr, 16);
|
|
|
|
if (nextpadnum >= 0) {
|
|
// Call the lift
|
|
chrOpenDoor(chr, &nextpad.pos);
|
|
}
|
|
}
|
|
} else {
|
|
// Enter lift
|
|
chr->liftaction = LIFTACTION_NOTUSINGLIFT;
|
|
|
|
if (chrGoPosIsWaiting(chr)) {
|
|
if (chr->actiontype == ACT_PATROL) {
|
|
chrPatrolChooseAnimation(chr);
|
|
} else {
|
|
chrGoPosChooseAnimation(chr);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// On a wait lift pad, but the next pad in the route is not on the
|
|
// lift, so the chr is running past the lift without using it.
|
|
if (arrivingatlift) {
|
|
advance = true;
|
|
chr->liftaction = LIFTACTION_NOTUSINGLIFT;
|
|
}
|
|
}
|
|
} else if (curpadflags & PADFLAG_AIONLIFT) {
|
|
if (nextpadflags & PADFLAG_AIWAITLIFT) {
|
|
// Waiting for door to close or lift to arrive at destination
|
|
if (arg2 || chr->liftaction == LIFTACTION_WAITINGONLIFT) {
|
|
// Continue waiting
|
|
s16 rooms[] = {0, -1};
|
|
u32 stack2;
|
|
|
|
rooms[0] = nextpad.room;
|
|
|
|
nextground = cd0002a36c(&nextpad.pos, rooms, NULL, NULL);
|
|
|
|
// Begin exiting lift if lift is 30cm under destination or higher
|
|
advance = (lifty >= nextground - 30);
|
|
|
|
// ...and (if solo) lift is under 1m above destination
|
|
if (!g_Vars.normmplayerisrunning && advance) {
|
|
advance = (lifty < nextground + 100);
|
|
}
|
|
|
|
// ...and if the lift has a door, is at least halfway open
|
|
if (advance && lift->doors[lift->levelcur] && lift->doors[lift->levelcur]->frac < 0.5f) {
|
|
advance = false;
|
|
}
|
|
}
|
|
|
|
if (!advance) {
|
|
if (arg2 && chr->liftaction != LIFTACTION_WAITINGONLIFT) {
|
|
// Just arrived inside lift
|
|
chr->liftaction = LIFTACTION_WAITINGONLIFT;
|
|
chrChooseStandAnimation(chr, 16);
|
|
}
|
|
} else {
|
|
// Start disembarking
|
|
chr->liftaction = LIFTACTION_ONLIFT;
|
|
|
|
if (chrGoPosIsWaiting(chr)) {
|
|
if (chr->actiontype == ACT_PATROL) {
|
|
chrPatrolChooseAnimation(chr);
|
|
} else {
|
|
chrGoPosChooseAnimation(chr);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// Not our stop? Not sure why advance is true here. I guess the chr
|
|
// can't go anywhere anyway because the next pad is above or below
|
|
// them.
|
|
if (arg2) {
|
|
advance = true;
|
|
chr->liftaction = LIFTACTION_ONLIFT;
|
|
}
|
|
}
|
|
}
|
|
|
|
return advance;
|
|
}
|
|
|
|
s32 chrIsUsingLift(struct chrdata *chr)
|
|
{
|
|
return (chr->actiontype == ACT_GOPOS || chr->actiontype == ACT_PATROL) && chr->liftaction > 0;
|
|
}
|
|
|
|
s16 chrGoPosGetNextPadNum(struct chrdata *chr)
|
|
{
|
|
if (chr->act_gopos.waypoints[chr->act_gopos.curindex + 1]) {
|
|
return chr->act_gopos.waypoints[chr->act_gopos.curindex + 1]->padnum;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
void chrTickGoPos(struct chrdata *chr)
|
|
{
|
|
struct waypoint *waypoint;
|
|
struct coord nextpos;
|
|
s16 nextrooms[8];
|
|
struct prop *prop = chr->prop;
|
|
bool enteringmagic = false;
|
|
struct pad pad;
|
|
bool sp240 = true;
|
|
struct coord curwppos;
|
|
s16 curwprooms[8];
|
|
u32 curwpflags;
|
|
|
|
chr->act_gopos.flags &= ~(GOPOSFLAG_DUCK | GOPOSFLAG_WALKDIRECT);
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrGoPosChooseAnimation(chr);
|
|
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
chr->act_gopos.waydata.age++;
|
|
|
|
// If stuck for 1 second
|
|
if (chr->lastmoveok60 < g_Vars.lvframe60 - TICKS(60)) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (chr->goposforce >= 0) {
|
|
// Try and warp the chr past whatever obstacle is blocking them?
|
|
struct coord sp196 = {0, 0, 0};
|
|
|
|
chrDamageByMisc(chr, 1, &sp196, NULL, NULL);
|
|
|
|
chr->lastmoveok60 = g_Vars.lvframe60;
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
// Goposforce was not set - restart the action to try and find a new route
|
|
chrGoToRoomPos(chr, &chr->act_gopos.endpos, chr->act_gopos.endrooms, chr->act_gopos.flags);
|
|
}
|
|
|
|
chrGoPosConsiderRestart(chr);
|
|
chrGoPosGetCurWaypointInfoWithFlags(chr, &curwppos, curwprooms, &curwpflags);
|
|
|
|
// If magic mode ended over 3 seconds ago, not multiplayer, not in view of
|
|
// eyespy, pad is nothing special and not in lift, then enter the magic move
|
|
// mode.
|
|
if (chr->act_gopos.waydata.mode != WAYMODE_MAGIC
|
|
&& chr->act_gopos.waydata.lastvisible60 + TICKS(180) < g_Vars.lvframe60
|
|
&& g_Vars.normmplayerisrunning == false
|
|
&& chrIsRoomOffScreen(chr, &curwppos, curwprooms) // related to eyespy
|
|
&& (curwpflags & (PADFLAG_AIWAITLIFT | PADFLAG_AIONLIFT)) == 0
|
|
&& chr->inlift == false) {
|
|
enteringmagic = true;
|
|
chrGoPosInitMagic(chr, &chr->act_gopos.waydata, &curwppos, &prop->pos);
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (g_NumChrsSeenPlayerRecently2 >= 9
|
|
&& (chr->hidden & CHRHFLAG_00400000)
|
|
&& (chr->flags & CHRFLAG0_ACTIVATEALARM) == 0) {
|
|
chrStop(chr);
|
|
return;
|
|
}
|
|
#else
|
|
if (g_NumChrsSeenPlayerRecently2 >= 10) {
|
|
chrStop(chr);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
// If goposforce is set then decrease it on each tick. If it's reached -1
|
|
// then stop the chr. I guess goposforce is not only used to warp past
|
|
// obstacles, but is also used as a run countdown timer.
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (chr->goposforce >= 0) {
|
|
chr->goposforce -= g_Vars.lvupdate240_60;
|
|
|
|
if (chr->goposforce < 0) {
|
|
chrStop(chr);
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// Check if chr needs to exit magic mode
|
|
if (chr->act_gopos.waydata.mode == WAYMODE_MAGIC) {
|
|
if ((!enteringmagic && ((prop->flags & (PROPFLAG_ONANYSCREENPREVTICK | PROPFLAG_ONANYSCREENTHISTICK | PROPFLAG_ONTHISSCREENTHISTICK)) || !chrIsRoomOffScreen(chr, &curwppos, curwprooms)))
|
|
|| (curwpflags & (PADFLAG_AIWAITLIFT | PADFLAG_AIONLIFT))
|
|
|| chr->inlift) {
|
|
// Exiting magic mode
|
|
chrGoPosInitExpensive(chr);
|
|
chr->act_gopos.waydata.lastvisible60 = g_Vars.lvframe60;
|
|
return;
|
|
}
|
|
|
|
chrNavTickMagic(chr, &chr->act_gopos.waydata, func0f0370a8(chr), &curwppos, curwprooms);
|
|
} else {
|
|
bool advance = false;
|
|
bool sp188;
|
|
bool sp184;
|
|
f32 sp180;
|
|
f32 sp176;
|
|
f32 sp172;
|
|
f32 sp168;
|
|
bool candosomething;
|
|
f32 sp160;
|
|
f32 sp156;
|
|
struct waypoint *next;
|
|
struct pad pad2;
|
|
|
|
waypoint = chr->act_gopos.waypoints[chr->act_gopos.curindex];
|
|
|
|
if (waypoint) {
|
|
padUnpack(waypoint->padnum, PADFIELD_FLAGS | PADFIELD_POS, &pad);
|
|
|
|
// Both of these functions are calculating something with the coords
|
|
// and are returning a boolean. There are no write operations.
|
|
sp188 = posIsArrivingAtPos(&chr->prevpos, &prop->pos, &pad.pos, 30);
|
|
sp184 = posIsArrivingLaterallyAtPos(&chr->prevpos, &prop->pos, &pad.pos, 30);
|
|
|
|
if (pad.flags & PADFLAG_AIDUCK) {
|
|
chr->act_gopos.flags |= GOPOSFLAG_DUCK;
|
|
} else if (pad.flags & PADFLAG_10000) {
|
|
chr->act_gopos.flags |= GOPOSFLAG_WALKDIRECT;
|
|
}
|
|
|
|
if ((pad.flags & PADFLAG_AIWAITLIFT) || (pad.flags & PADFLAG_AIONLIFT)) {
|
|
advance = chrGoPosUpdateLiftAction(chr, pad.flags, sp184, sp188, waypoint->padnum, chrGoPosGetNextPadNum(chr));
|
|
} else {
|
|
if (sp188 || (sp184 && (chr->inlift || (pad.flags & PADFLAG_8000)))) {
|
|
advance = true;
|
|
}
|
|
}
|
|
} else {
|
|
// No more waypoints - chr is finished
|
|
if (posIsArrivingAtPos(&chr->prevpos, &prop->pos, &chr->act_gopos.endpos, 30) ||
|
|
(chr->inlift && posIsArrivingLaterallyAtPos(&chr->prevpos, &prop->pos, &chr->act_gopos.endpos, 30))) {
|
|
if (chr->act_gopos.flags & GOPOSFLAG_FORPATHSTART) {
|
|
chrTryStartPatrol(chr);
|
|
return;
|
|
}
|
|
|
|
chrStop(chr);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (advance) {
|
|
chrGoPosAdvanceWaypoint(chr);
|
|
}
|
|
|
|
// Every 10 ticks: Check something a couple of waypoints ahead
|
|
// This might be checking if the chr has line of sight to that pad and can
|
|
// walk straight to it.
|
|
if (chr->act_gopos.waydata.age % 10 == 5 || (chr->act_gopos.flags & GOPOSFLAG_INIT)) {
|
|
// Load waypoint that the chr is running to
|
|
waypoint = chr->act_gopos.waypoints[chr->act_gopos.curindex];
|
|
|
|
if (waypoint) {
|
|
padUnpack(waypoint->padnum, PADFIELD_FLAGS, &pad);
|
|
|
|
if ((pad.flags & PADFLAG_AIWALKDIRECT) == 0) {
|
|
// The waypoint the chr is running to doesn't have
|
|
// PADFLAG_AIWALKDIRECT, so the chr is able to ignore it and run
|
|
// towards the next one if it's in sight.
|
|
|
|
// Load the next waypoint after the one the chr is running to
|
|
waypoint = chr->act_gopos.waypoints[chr->act_gopos.curindex + 1];
|
|
|
|
if (waypoint) {
|
|
padUnpack(waypoint->padnum, PADFIELD_FLAGS, &pad);
|
|
|
|
if ((pad.flags & PADFLAG_AIWALKDIRECT) == 0) {
|
|
// And this one doesn't have PADFLAG_AIWALKDIRECT either,
|
|
// so the chr can consider skipping this one too.
|
|
waypoint = chr->act_gopos.waypoints[chr->act_gopos.curindex + 2];
|
|
|
|
if (waypoint) {
|
|
padUnpack(waypoint->padnum, PADFIELD_ROOM | PADFIELD_POS, &pad);
|
|
|
|
nextpos.x = pad.pos.x;
|
|
nextpos.y = pad.pos.y;
|
|
nextpos.z = pad.pos.z;
|
|
|
|
nextrooms[0] = pad.room;
|
|
nextrooms[1] = -1;
|
|
} else {
|
|
nextpos.x = chr->act_gopos.endpos.x;
|
|
nextpos.y = chr->act_gopos.endpos.y;
|
|
nextpos.z = chr->act_gopos.endpos.z;
|
|
|
|
roomsCopy(chr->act_gopos.endrooms, nextrooms);
|
|
}
|
|
|
|
// Some bbox related check
|
|
if (func0f03654c(chr, &prop->pos, prop->rooms, &nextpos, nextrooms, NULL, chr->radius * 1.2f, CDTYPE_PATHBLOCKER | CDTYPE_BG)) {
|
|
chrGoPosAdvanceWaypoint(chr);
|
|
chrGoPosAdvanceWaypoint(chr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (chr->act_gopos.waydata.age % 10 == 0 || (chr->act_gopos.flags & GOPOSFLAG_INIT)) {
|
|
waypoint = chr->act_gopos.waypoints[chr->act_gopos.curindex];
|
|
|
|
if (waypoint) {
|
|
candosomething = (chr->act_gopos.flags & GOPOSFLAG_INIT) != 0;
|
|
padUnpack(waypoint->padnum, PADFIELD_FLAGS | PADFIELD_POS, &pad);
|
|
|
|
next = chr->act_gopos.waypoints[chr->act_gopos.curindex + 1];
|
|
|
|
if (next) {
|
|
padUnpack(next->padnum, PADFIELD_ROOM | PADFIELD_POS, &pad2);
|
|
|
|
if ((pad.flags & (PADFLAG_AIWAITLIFT | PADFLAG_AIONLIFT))
|
|
&& (pad2.flags & (PADFLAG_AIWAITLIFT | PADFLAG_AIONLIFT))) {
|
|
candosomething = false;
|
|
}
|
|
}
|
|
|
|
if ((pad.flags & PADFLAG_AIWALKDIRECT) == 0 || candosomething) {
|
|
if (next) {
|
|
nextpos.x = pad2.pos.x;
|
|
nextpos.y = pad2.pos.y;
|
|
nextpos.z = pad2.pos.z;
|
|
|
|
nextrooms[0] = pad2.room;
|
|
nextrooms[1] = -1;
|
|
} else {
|
|
nextpos.x = chr->act_gopos.endpos.x;
|
|
nextpos.y = chr->act_gopos.endpos.y;
|
|
nextpos.z = chr->act_gopos.endpos.z;
|
|
|
|
roomsCopy(chr->act_gopos.endrooms, nextrooms);
|
|
}
|
|
|
|
// I suspect this is making the chr turn to face the next pad
|
|
if ((pad.flags & PADFLAG_AIWALKDIRECT) && candosomething) {
|
|
if (true) {
|
|
sp180 = prop->pos.x - pad.pos.x;
|
|
sp176 = prop->pos.z - pad.pos.z;
|
|
sp172 = nextpos.x - pad.pos.x;
|
|
sp168 = nextpos.z - pad.pos.z;
|
|
}
|
|
|
|
sp156 = sqrtf((sp180 * sp180 + sp176 * sp176) * (sp172 * sp172 + sp168 * sp168));
|
|
|
|
if (sp156 > 0) {
|
|
sp160 = acosf((sp180 * sp172 + sp176 * sp168) / sp156);
|
|
|
|
// sp160 < DEG2RAD(45) || sp160 > DEG2RAD(315)
|
|
if (sp160 < 0.7852731347084f || sp160 > 5.4969120025635f) {
|
|
if (func0f03654c(chr, &prop->pos, prop->rooms, &nextpos, nextrooms, NULL, chr->radius * 1.2f, CDTYPE_PATHBLOCKER | CDTYPE_BG)) {
|
|
chrGoPosAdvanceWaypoint(chr);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
if (func0f03654c(chr, &prop->pos, prop->rooms, &nextpos, nextrooms, NULL, chr->radius * 1.2f, CDTYPE_PATHBLOCKER | CDTYPE_BG)) {
|
|
chrGoPosAdvanceWaypoint(chr);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
chr->act_gopos.flags &= ~GOPOSFLAG_INIT;
|
|
}
|
|
|
|
waypoint = chr->act_gopos.waypoints[chr->act_gopos.curindex];
|
|
|
|
if (waypoint) {
|
|
padUnpack(waypoint->padnum, PADFIELD_POS, &pad);
|
|
|
|
nextpos.x = pad.pos.x;
|
|
nextpos.y = pad.pos.y;
|
|
nextpos.z = pad.pos.z;
|
|
} else {
|
|
nextpos.x = chr->act_gopos.endpos.x;
|
|
nextpos.y = chr->act_gopos.endpos.y;
|
|
nextpos.z = chr->act_gopos.endpos.z;
|
|
|
|
if (chr->aibot && chr->myaction == MA_AIBOTGETITEM) {
|
|
sp240 = false;
|
|
}
|
|
}
|
|
|
|
chrNavTickMain(chr, &nextpos, &chr->act_gopos.waydata, sp240);
|
|
}
|
|
}
|
|
|
|
void chrTickPatrol(struct chrdata *chr)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
bool enteringmagic;
|
|
u32 flags = 0;
|
|
struct coord sp58;
|
|
s16 sp48[8];
|
|
s32 arrivinglaterally;
|
|
s32 arriving;
|
|
bool advance;
|
|
|
|
enteringmagic = 0;
|
|
|
|
if (chr->hidden & CHRHFLAG_NEEDANIM) {
|
|
if (modelIsAnimMerging(chr->model)) {
|
|
return;
|
|
}
|
|
|
|
chrPatrolChooseAnimation(chr);
|
|
chr->hidden &= ~CHRHFLAG_NEEDANIM;
|
|
}
|
|
|
|
chrPatrolGetCurWaypointInfoWithFlags(chr, &sp58, sp48, &flags);
|
|
|
|
chr->act_patrol.waydata.age++;
|
|
|
|
// Consider starting magic
|
|
if (chr->act_patrol.waydata.mode != WAYMODE_MAGIC
|
|
&& g_Vars.lvframe60 > chr->act_patrol.waydata.lastvisible60 + TICKS(180)
|
|
&& !g_Vars.normmplayerisrunning
|
|
&& chrIsRoomOffScreen(chr, &sp58, sp48)
|
|
&& (flags & (PADFLAG_AIWAITLIFT | PADFLAG_AIONLIFT)) == 0
|
|
&& !chr->inlift) {
|
|
enteringmagic = true;
|
|
chrGoPosInitMagic(chr, &chr->act_patrol.waydata, &sp58, &prop->pos);
|
|
}
|
|
|
|
if (chr->act_patrol.waydata.mode == WAYMODE_MAGIC) {
|
|
if ((!enteringmagic && ((prop->flags & (PROPFLAG_ONTHISSCREENTHISTICK | PROPFLAG_ONANYSCREENTHISTICK | PROPFLAG_ONANYSCREENPREVTICK)) || !chrIsRoomOffScreen(chr, &sp58, sp48)))
|
|
|| (flags & (PADFLAG_AIWAITLIFT | PADFLAG_AIONLIFT))
|
|
|| chr->inlift) {
|
|
// Exit magic for lifts
|
|
chr->act_patrol.waydata.lastvisible60 = g_Vars.lvframe60;
|
|
func0f037580(chr);
|
|
} else {
|
|
// Continue magic
|
|
chrNavTickMagic(chr, &chr->act_patrol.waydata, func0f0370a8(chr), &sp58, sp48);
|
|
}
|
|
|
|
footstepCheckMagic(chr);
|
|
} else {
|
|
arrivinglaterally = posIsArrivingLaterallyAtPos(&chr->prevpos, &prop->pos, &sp58, 30);
|
|
arriving = posIsArrivingAtPos(&chr->prevpos, &prop->pos, &sp58, 30);
|
|
advance = false;
|
|
|
|
if ((flags & PADFLAG_AIWAITLIFT) || (flags & PADFLAG_AIONLIFT)) {
|
|
advance = chrGoPosUpdateLiftAction(chr, flags, arrivinglaterally, arriving,
|
|
chrPatrolCalculatePadNum(chr, 0),
|
|
chrPatrolCalculatePadNum(chr, 1));
|
|
} else if (arriving) {
|
|
advance = true;
|
|
}
|
|
|
|
if (advance) {
|
|
func0f0375b0(chr);
|
|
chrPatrolGetCurWaypointInfo(chr, &sp58, sp48);
|
|
}
|
|
|
|
chrNavTickMain(chr, &sp58, &chr->act_patrol.waydata, true);
|
|
footstepCheckDefault(chr);
|
|
}
|
|
}
|
|
|
|
bool chrTrySkJump(struct chrdata *chr, u8 arg1, u8 arg2, s32 arg3, u8 arg4)
|
|
{
|
|
if (chr && chr->actiontype != ACT_SKJUMP
|
|
&& chrIsReadyForOrders(chr)
|
|
&& CHRRACE(chr) == RACE_SKEDAR) {
|
|
return chrStartSkJump(chr, arg1, arg2, arg3, arg4);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrStartSkJump(struct chrdata *chr, u8 arg1, u8 arg2, s32 arg3, u8 arg4)
|
|
{
|
|
f32 radius;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
struct prop *prop = chr->prop;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
bool iVar2;
|
|
f32 distance = chrGetDistanceToCoord(chr, &target->pos);
|
|
f32 diffs[2];
|
|
f32 thing;
|
|
s32 time60;
|
|
|
|
if (distance < 200 || distance > 550 || !target) {
|
|
return false;
|
|
}
|
|
|
|
chrGetBbox(prop, &radius, &ymax, &ymin);
|
|
chrSetPerimEnabled(chr, false);
|
|
propSetPerimEnabled(target, false);
|
|
iVar2 = cd0002d6ac(&prop->pos, prop->rooms, &target->pos, 51, 1,
|
|
ymax - prop->pos.y, ymin - prop->pos.y);
|
|
chrSetPerimEnabled(chr, true);
|
|
propSetPerimEnabled(target, true);
|
|
|
|
if (iVar2) {
|
|
diffs[0] = target->pos.x - chr->prop->pos.x;
|
|
diffs[1] = target->pos.z - chr->prop->pos.z;
|
|
thing = sqrtf(diffs[0] * diffs[0] + diffs[1] * diffs[1]) * 2.5f / PALUPF(21.0f);
|
|
time60 = thing;
|
|
|
|
if (time60 < TICKS(10)) {
|
|
time60 = TICKS(10);
|
|
}
|
|
|
|
chr->act_skjump.vel[0] = diffs[0] / time60;
|
|
chr->act_skjump.vel[1] = diffs[1] / time60;
|
|
chr->act_skjump.roty = chrGetInverseTheta(chr) + chrGetAngleToPos(chr, &target->pos);
|
|
chr->act_skjump.hit = false;
|
|
chr->act_skjump.timer60 = time60;
|
|
chr->act_skjump.total60 = time60;
|
|
chr->act_skjump.ground = cdFindGroundYSimple(&chr->prop->pos, chr->radius, chr->prop->rooms, NULL, NULL);
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
chr->actiontype = ACT_SKJUMP;
|
|
chr->act_skjump.needsnewanim = true;
|
|
chr->act_skjump.state = SKJUMPSTATE_TAKEOFF;
|
|
|
|
return true;
|
|
}
|
|
|
|
void chrTickSkJump(struct chrdata *chr)
|
|
{
|
|
if (g_Vars.lvupdate240_60 == 0) {
|
|
return;
|
|
}
|
|
|
|
if (chr->act_skjump.needsnewanim) {
|
|
chr->act_skjump.needsnewanim = false;
|
|
|
|
switch (chr->act_skjump.state) {
|
|
case SKJUMPSTATE_TAKEOFF:
|
|
modelSetAnimation(chr->model, ANIM_SKEDAR_JUMPSTART, 0, 0, -1, 8);
|
|
modelSetAnimSpeed(chr->model, 2.5, 0);
|
|
break;
|
|
case SKJUMPSTATE_AIRBORNE: {
|
|
u16 sounds[] = {
|
|
SFX_SKEDAR_ROAR_0532,
|
|
SFX_SKEDAR_ROAR_0533,
|
|
SFX_SKEDAR_ROAR_0534,
|
|
};
|
|
|
|
propsnd0f0939f8(NULL, chr->prop, sounds[random() % 3], -1,
|
|
-1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
modelSetAnimation(chr->model, ANIM_SKEDAR_JUMPAIR, 0, 0, -1, 16);
|
|
modelSetAnimSpeed(chr->model, 1, 0);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
{
|
|
f32 fVar5;
|
|
f32 fVar6;
|
|
f32 fVar7;
|
|
u32 stack[1];
|
|
f32 frame;
|
|
|
|
switch (chr->act_skjump.state) {
|
|
case SKJUMPSTATE_TAKEOFF:
|
|
fVar6 = chrGetInverseTheta(chr);
|
|
fVar5 = model0001afe8(fVar6, chr->act_skjump.roty, 0.35);
|
|
chrSetLookAngle(chr, fVar5);
|
|
frame = modelGetCurAnimFrame(chr->model);
|
|
|
|
if (frame >= modelGetAnimEndFrame(chr->model)) {
|
|
chr->act_skjump.state++;
|
|
chr->act_skjump.needsnewanim = true;
|
|
}
|
|
break;
|
|
case SKJUMPSTATE_AIRBORNE:
|
|
chr->act_skjump.pos.x = chr->act_skjump.vel[0] * g_Vars.lvupdate240_60 + chr->prop->pos.x;
|
|
chr->act_skjump.pos.z = chr->act_skjump.vel[1] * g_Vars.lvupdate240_60 + chr->prop->pos.z;
|
|
|
|
if (chr->act_skjump.total60 > 0) {
|
|
fVar6 = 1.0f - chr->act_skjump.timer60 / (f32)chr->act_skjump.total60;
|
|
fVar7 = sinf(M_PI * fVar6);
|
|
fVar7 = fVar7 * 160.0f + chr->act_skjump.ground;
|
|
} else {
|
|
fVar6 = 1;
|
|
fVar7 = chr->act_skjump.ground;
|
|
}
|
|
|
|
chr->act_skjump.pos.y = fVar7 - chr->prop->pos.y;
|
|
|
|
if (fVar6 < 0.5f && chr->act_skjump.pos.y < 0.0f) {
|
|
chr->act_skjump.pos.y = 0;
|
|
}
|
|
|
|
if (!chr->act_skjump.hit && chrGetDistanceToTarget(chr) < 150.0f) {
|
|
chrPunchInflictDamage(chr, 3, 150, false);
|
|
chr->act_skjump.hit = true;
|
|
}
|
|
|
|
if (chr->act_skjump.timer60 > 0) {
|
|
chr->act_skjump.timer60 -= g_Vars.lvupdate240_60;
|
|
} else {
|
|
chrTryStop(chr);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void chraTick(struct chrdata *chr)
|
|
{
|
|
u32 race = CHRRACE(chr);
|
|
|
|
if (g_Vars.lvupdate240 < 1) {
|
|
return;
|
|
}
|
|
|
|
if (chr->actiontype == ACT_INIT) {
|
|
chr->chrflags |= CHRCFLAG_00000001;
|
|
func0f02e9a0(chr, 0);
|
|
chr->sleep = 0;
|
|
}
|
|
|
|
if (race == RACE_DRCAROLL) {
|
|
g_DrCarollDyingTimer += g_Vars.lvupdate240_60;
|
|
}
|
|
|
|
chr->soundtimer += g_Vars.lvupdate240_60;
|
|
chr->talktimer += g_Vars.lvupdate240_60;
|
|
|
|
#if VERSION < VERSION_PAL_BETA
|
|
if (chr->aibot) {
|
|
chr->aibot->unk030 += g_Vars.lvupdate240_60;
|
|
}
|
|
#endif
|
|
|
|
if (chr->hidden & CHRHFLAG_TIMER_RUNNING) {
|
|
chr->timer60 += g_Vars.lvupdate240_60;
|
|
}
|
|
|
|
chr->sleep -= g_Vars.lvupdate240_60;
|
|
|
|
if (chr->sleep < 0
|
|
|| (chr->chrflags & CHRCFLAG_00040000)
|
|
|| chr->alertness >= 65
|
|
|| (chr->aibot && (chr->actiontype == ACT_DIE || chr->actiontype == ACT_DEAD))) {
|
|
u8 pass = race == RACE_HUMAN || race == RACE_SKEDAR;
|
|
chr->sleep = 0;
|
|
|
|
chraiExecute(chr, PROPTYPE_CHR);
|
|
|
|
// Consider setting shootingatmelist
|
|
if (chr->prop) {
|
|
if (chr->aimtesttimer60 < 1) {
|
|
chr->aimtesttimer60 = TICKS(30);
|
|
|
|
if (chr->aishootingatmelist >= 0
|
|
&& ailistFindById(chr->aishootingatmelist) != chr->ailist
|
|
&& chrCanSeeTargetWithExtraCheck(chr)) {
|
|
chr->chrflags |= CHRCFLAG_CONSIDER_DODGE;
|
|
}
|
|
} else {
|
|
chr->aimtesttimer60 -= g_Vars.lvupdate240_60;
|
|
}
|
|
}
|
|
|
|
// Consider setting darkroomlist
|
|
if (chr->prop
|
|
&& chr->aidarkroomlist >= 0
|
|
&& roomGetBrightness(chr->prop->rooms[0]) < 25
|
|
&& ailistFindById(chr->aidarkroomlist) != chr->ailist) {
|
|
chr->darkroomthing = true;
|
|
}
|
|
|
|
// Consider setting playerdeadlist
|
|
if (chr->prop && chr->aiplayerdeadlist >= 0 && g_Vars.currentplayer->isdead) {
|
|
u32 prevplayernum = g_Vars.currentplayernum;
|
|
s32 i;
|
|
s32 playercount = PLAYERCOUNT();
|
|
bool alldead = true;
|
|
|
|
if (playercount >= 2) {
|
|
for (i = 0; i < playercount && alldead; i++) {
|
|
if (i != prevplayernum) {
|
|
setCurrentPlayerNum(i);
|
|
|
|
if (g_Vars.currentplayer->isdead == false) {
|
|
alldead = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
setCurrentPlayerNum(prevplayernum);
|
|
}
|
|
|
|
if (alldead && ailistFindById(chr->aiplayerdeadlist) != chr->ailist) {
|
|
chr->playerdeadthing = true;
|
|
}
|
|
}
|
|
|
|
if (race == RACE_ROBOT) {
|
|
robotSetMuzzleFlash(chr, 0, false);
|
|
robotSetMuzzleFlash(chr, 1, false);
|
|
}
|
|
|
|
if (chr->prop) {
|
|
if (g_Vars.in_cutscene) {
|
|
switch (chr->actiontype) {
|
|
case ACT_ANIM: chrTickAnim(chr); break;
|
|
case ACT_PATROL: chrTickPatrol(chr); pass = false; break;
|
|
}
|
|
} else {
|
|
switch (chr->actiontype) {
|
|
case ACT_STAND: chrTickStand(chr); break;
|
|
case ACT_KNEEL: chrTickKneel(chr); break;
|
|
case ACT_ANIM: chrTickAnim(chr); break;
|
|
case ACT_DIE: chrTickDie(chr); break;
|
|
case ACT_ARGH: chrTickArgh(chr); break;
|
|
case ACT_PREARGH: chrTickPreArgh(chr); break;
|
|
case ACT_SIDESTEP: chrTickSidestep(chr); break;
|
|
case ACT_JUMPOUT: chrTickJumpOut(chr); break;
|
|
case ACT_DEAD: chrTickDead(chr); break;
|
|
case ACT_ATTACK: chrTickAttack(chr); break;
|
|
case ACT_ATTACKWALK: chrTickAttackWalk(chr); break;
|
|
case ACT_ATTACKROLL: chrTickAttackRoll(chr); break;
|
|
case ACT_RUNPOS: chrTickRunPos(chr); break;
|
|
case ACT_PATROL: chrTickPatrol(chr); pass = false; break;
|
|
case ACT_GOPOS: chrTickGoPos(chr); break;
|
|
case ACT_SURRENDER: chrTickSurrender(chr); break;
|
|
case ACT_TEST: chrTickTest(chr); break;
|
|
case ACT_SURPRISED: chrTickSurprised(chr); break;
|
|
case ACT_STARTALARM: chrTickStartAlarm(chr); break;
|
|
case ACT_THROWGRENADE: chrTickThrowGrenade(chr); break;
|
|
case ACT_BONDDIE: chrTickBondDie(chr); break;
|
|
case ACT_DRUGGEDCOMINGUP: chrTickDruggedComingUp(chr); break;
|
|
case ACT_DRUGGEDDROP: chrTickDruggedDrop(chr); break;
|
|
case ACT_DRUGGEDKO: chrTickDruggedKo(chr); break;
|
|
case ACT_ATTACKAMOUNT: chrTickAttackAmount(chr); break;
|
|
case ACT_ROBOTATTACK: chrTickRobotAttack(chr); break;
|
|
case ACT_SKJUMP: chrTickSkJump(chr); break;
|
|
}
|
|
}
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
chr->hidden &= ~CHRHFLAG_IS_HEARING_TARGET;
|
|
chr->hidden2 &= ~CHRH2FLAG_0040;
|
|
#else
|
|
chr->hidden &= ~(CHRHFLAG_IS_HEARING_TARGET | CHRHFLAG_00000200);
|
|
#endif
|
|
|
|
if (pass) {
|
|
footstepCheckDefault(chr);
|
|
}
|
|
} else {
|
|
footstepCheckMagic(chr);
|
|
}
|
|
}
|
|
|
|
void cutsceneStart(u32 ailistid)
|
|
{
|
|
struct prop *prop;
|
|
|
|
#if PAL
|
|
var8009e388pf = 0;
|
|
#else
|
|
g_CutsceneFrameOverrun240 = 0;
|
|
#endif
|
|
g_CutsceneSkipRequested = false;
|
|
g_CutsceneCurTotalFrame60f = 0;
|
|
|
|
prop = g_Vars.activeprops;
|
|
|
|
while (prop) {
|
|
prop->lastupdateframe = 0xffff;
|
|
prop->propupdate240 = 0;
|
|
prop->propupdate60err = 2;
|
|
|
|
prop = prop->next;
|
|
}
|
|
|
|
g_BgChrs[g_NumBgChrs - 1].ailist = ailistFindById(ailistid);
|
|
g_BgChrs[g_NumBgChrs - 1].aioffset = 0;
|
|
g_BgChrs[g_NumBgChrs - 1].aireturnlist = -1;
|
|
}
|
|
|
|
/**
|
|
* Execute background tasks.
|
|
*
|
|
* - Calculate number of engaged chrs
|
|
* - Handle switching to new cutscenes when playing all
|
|
* - Run BG scripts
|
|
* - Choose which corpses to fade
|
|
*/
|
|
void chraTickBg(void)
|
|
{
|
|
s32 i;
|
|
s32 numchrs = chrsGetNumSlots();
|
|
s32 numaliveonscreen;
|
|
s32 numdeadonscreen;
|
|
s32 onscreenlen;
|
|
s32 offscreenlen;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
s32 spawnslen;
|
|
#endif
|
|
struct chrdata *onscreen[5];
|
|
struct chrdata *offscreen[5];
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
struct chrdata *spawns[10];
|
|
#endif
|
|
s32 writeindex;
|
|
s32 maxdeadonscreen;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
static u32 var80068454 = 0;
|
|
#endif
|
|
|
|
static s32 mosteveralive = 0;
|
|
|
|
numaliveonscreen = 0;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
spawnslen = 0;
|
|
numdeadonscreen = 0;
|
|
#else
|
|
numdeadonscreen = 0;
|
|
onscreenlen = 0;
|
|
offscreenlen = 0;
|
|
#endif
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
// Count the number of chrs who are engaged with the player.
|
|
// When these numbers are high, chrs can ignore gopos commands.
|
|
// NTSC beta has a simple version of this logic in a loop
|
|
// near the end of this function.
|
|
g_NumChrsWithPlayerTarget = 0;
|
|
g_NumChrsSeenPlayer = 0;
|
|
g_NumChrsSeenPlayerRecently = 0;
|
|
g_NumChrsSeenPlayerRecently2 = 0;
|
|
|
|
if (g_Vars.normmplayerisrunning == false) {
|
|
for (i = 0; i < numchrs; i++) {
|
|
struct chrdata *chr = &g_ChrSlots[i];
|
|
|
|
if (chr->model && chr->prop && !chrIsDead(chr)) {
|
|
struct prop *targetprop = chrGetTargetProp(chr);
|
|
|
|
if (targetprop && (targetprop->type == PROPTYPE_CHR || targetprop->type == PROPTYPE_PLAYER)) {
|
|
if ((targetprop->type == PROPTYPE_PLAYER
|
|
&& !(g_Vars.antiplayernum >= 0 && g_Vars.anti && g_Vars.anti->prop == targetprop)
|
|
&& chrCompareTeams(chr, targetprop->chr, COMPARE_ENEMIES))
|
|
|| CHRRACE(targetprop->chr) == RACE_EYESPY) {
|
|
s32 time60;
|
|
s32 lastsee;
|
|
s32 lastvis;
|
|
|
|
g_NumChrsWithPlayerTarget++;
|
|
|
|
lastsee = chr->lastseetarget60;
|
|
lastvis = chr->lastvisibletarget60;
|
|
time60 = lastsee > lastvis ? lastsee : lastvis;
|
|
|
|
if (time60) {
|
|
g_NumChrsSeenPlayer++;
|
|
|
|
if (g_Vars.lvframe60 - time60 < TICKS(240)) {
|
|
g_NumChrsSeenPlayerRecently++;
|
|
g_NumChrsSeenPlayerRecently2++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
var80068454++;
|
|
|
|
if (var80068454 > 10) {
|
|
var80068454 = 0;
|
|
}
|
|
#endif
|
|
|
|
// If enabled, print a list of dangerous props to the developer's console
|
|
if (debugDangerousProps()) {
|
|
propPrintDangerous();
|
|
}
|
|
|
|
// Handle switching to a new cutscene when using "Play All" from the menu
|
|
if (g_Vars.autocutnum >= 0) {
|
|
cutsceneStart(g_Vars.autocutnum + 0xc00);
|
|
g_Vars.autocutnum = -1;
|
|
g_Vars.autocutplaying = true;
|
|
}
|
|
|
|
// Run BG scripts
|
|
for (i = 0; i < g_NumBgChrs; i++) {
|
|
if (!g_Vars.autocutplaying || (g_BgChrs[i].hidden2 & CHRH2FLAG_TICKDURINGAUTOCUT)) {
|
|
chraTick(&g_BgChrs[i]);
|
|
}
|
|
}
|
|
|
|
// Calculate alive/dead counters. For *spawned* chrs that have died,
|
|
// allow 10 corpses and start fading if there's more.
|
|
{
|
|
s32 numalive = 0;
|
|
|
|
for (i = 0; i < numchrs; i++) {
|
|
struct chrdata *chr = &g_ChrSlots[i];
|
|
|
|
if (chr->model && chr->prop) {
|
|
if (chr->actiontype != ACT_DEAD && chr->actiontype != ACT_DRUGGEDKO) {
|
|
numalive++;
|
|
}
|
|
|
|
if (chr->prop->flags & PROPFLAG_ONANYSCREENPREVTICK) {
|
|
if (chr->actiontype != ACT_DEAD && chr->actiontype != ACT_DRUGGEDKO) {
|
|
numaliveonscreen++;
|
|
} else if (chr->actiontype == ACT_DRUGGEDKO) {
|
|
if ((chr->chrflags & CHRCFLAG_KEEPCORPSEKO) == 0) {
|
|
numdeadonscreen++;
|
|
}
|
|
} else {
|
|
numdeadonscreen++;
|
|
}
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (chr->actiontype == ACT_DEAD
|
|
|| (chr->actiontype == ACT_DRUGGEDKO && (chr->chrflags & CHRCFLAG_KEEPCORPSEKO) == 0)) {
|
|
if (chr->hidden2 & CHRH2FLAG_SPAWNED) {
|
|
spawns[spawnslen] = chr;
|
|
spawnslen++;
|
|
|
|
if (spawnslen >= 10) {
|
|
writeindex = random() % spawnslen;
|
|
chrFadeCorpse(spawns[writeindex]);
|
|
spawns[writeindex] = spawns[spawnslen - 1];
|
|
spawnslen--;
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if (numalive > mosteveralive) {
|
|
mosteveralive = numalive;
|
|
}
|
|
}
|
|
|
|
// Calculate how many corpses are allowed on screen. Ideally no more than
|
|
// 5 chrs (alive or dead) to keep the number of polygons low.
|
|
maxdeadonscreen = 5 - numaliveonscreen;
|
|
|
|
// If the game is lagging, take the number of 60ths over 6 since the
|
|
// previous frame and reduce the limit by that amount. So if it's been, say,
|
|
// 8 60ths since the last frame then the max corpses will be reduced by 2.
|
|
// This is why corpses are more likely to fade on screen when you change
|
|
// weapons - the lag spike from changing guns triggers a lower corpse limit.
|
|
if (g_Vars.lvupdate240_60 > 6) {
|
|
maxdeadonscreen = maxdeadonscreen - g_Vars.lvupdate240_60 + 6;
|
|
}
|
|
|
|
if (maxdeadonscreen < 0) {
|
|
maxdeadonscreen = 0;
|
|
}
|
|
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
// JPN fades corpses immediately
|
|
if (numdeadonscreen && g_Vars.stagenum != STAGE_CITRAINING) {
|
|
for (i = 0; i < numchrs; i++) {
|
|
struct chrdata *chr = &g_ChrSlots[i];
|
|
|
|
if (chr->model
|
|
&& (chr->actiontype == ACT_DEAD || (chr->actiontype == ACT_DRUGGEDKO
|
|
&& chr->prop && (chr->chrflags & CHRCFLAG_KEEPCORPSEKO) == 0))
|
|
&& chr->act_dead.fadetimer60 < 0
|
|
&& !chr->act_dead.fadenow) {
|
|
chrFadeCorpse(chr);
|
|
}
|
|
}
|
|
}
|
|
#else
|
|
// Decide which corpses to fade.
|
|
// NTSC Beta implements its engagement counter here.
|
|
if (numdeadonscreen) {
|
|
numdeadonscreen = 0;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
onscreenlen = 0;
|
|
offscreenlen = 0;
|
|
#else
|
|
g_NumChrsSeenPlayerRecently2 = 0;
|
|
#endif
|
|
|
|
for (i = 0; i < numchrs; i++) {
|
|
struct chrdata *chr = &g_ChrSlots[i];
|
|
|
|
if (chr->model) {
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
if (!g_Vars.mplayerisrunning
|
|
&& chrGetTargetProp(chr)->type == PROPTYPE_PLAYER
|
|
&& chr->lastseetarget60 > 0
|
|
&& g_Vars.lvframe60 - chr->lastseetarget60 < TICKS(120)) {
|
|
g_NumChrsSeenPlayerRecently2++;
|
|
}
|
|
#endif
|
|
|
|
if (chr->actiontype == ACT_DEAD
|
|
|| (chr->actiontype == ACT_DRUGGEDKO && chr->prop && (chr->chrflags & CHRCFLAG_KEEPCORPSEKO) == 0)) {
|
|
if (chr->prop->flags & PROPFLAG_ONANYSCREENPREVTICK) {
|
|
// On-screen
|
|
if (chr->act_dead.fadetimer60 < 0 && !chr->act_dead.fadenow) {
|
|
numdeadonscreen++;
|
|
|
|
// If there's too many corpses on screen, start fading.
|
|
if (numdeadonscreen > maxdeadonscreen || chr->aibot) {
|
|
chrFadeCorpse(chr);
|
|
numdeadonscreen--;
|
|
} else if (!chr->act_dead.fadewheninvis) {
|
|
// If there are 2 or more corpses on screen,
|
|
// start marking them to be removed once off screen
|
|
onscreen[onscreenlen] = chr;
|
|
onscreenlen++;
|
|
|
|
if (onscreenlen >= (VERSION >= VERSION_NTSC_1_0 ? 2 : 3)) {
|
|
writeindex = random() % onscreenlen;
|
|
chrFadeCorpseWhenOffScreen(onscreen[writeindex]);
|
|
onscreen[writeindex] = onscreen[onscreenlen - 1];
|
|
onscreenlen--;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// Off-screen
|
|
if (!chr->act_dead.fadewheninvis) {
|
|
offscreen[offscreenlen] = chr;
|
|
offscreenlen++;
|
|
|
|
// Allow up to 5 corpses off-screen
|
|
if (offscreenlen >= (VERSION >= VERSION_NTSC_1_0 ? 5 : 6)) {
|
|
writeindex = random() % offscreenlen;
|
|
|
|
if (offscreen[writeindex]->actiontype != ACT_DEAD) {
|
|
chrBeginDead(offscreen[writeindex]);
|
|
}
|
|
|
|
chrFadeCorpseWhenOffScreen(offscreen[writeindex]);
|
|
offscreen[writeindex] = offscreen[offscreenlen - 1];
|
|
offscreenlen--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (1);
|
|
}
|
|
|
|
bool chrSawTargetRecently(struct chrdata *chr)
|
|
{
|
|
if (chr->lastseetarget60 > 0 && g_Vars.lvframe60 - chr->lastseetarget60 < TICKS(600)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrHeardTargetRecently(struct chrdata *chr)
|
|
{
|
|
if (chr->lastheartarget60 > 0 && g_Vars.lvframe60 - chr->lastheartarget60 < TICKS(600)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
f32 chrGetAngleToPos(struct chrdata *chr, struct coord *pos)
|
|
{
|
|
f32 fVar3;
|
|
f32 fVar2;
|
|
f32 fVar4;
|
|
struct prop *prop;
|
|
|
|
if (chr->prop->type == PROPTYPE_PLAYER) {
|
|
u32 playernum = playermgrGetPlayerNumByProp(chr->prop);
|
|
fVar3 = (360 - g_Vars.players[playernum]->vv_theta) * (M_BADTAU / 360);
|
|
} else {
|
|
fVar3 = chrGetInverseTheta(chr);
|
|
}
|
|
|
|
prop = chr->prop;
|
|
fVar2 = atan2f(pos->x - prop->pos.x, pos->z - prop->pos.z);
|
|
fVar4 = fVar2 - fVar3;
|
|
|
|
if (fVar2 < fVar3) {
|
|
fVar4 += M_BADTAU;
|
|
}
|
|
|
|
return fVar4;
|
|
}
|
|
|
|
f32 chrGetAngleToTarget(struct chrdata *chr)
|
|
{
|
|
struct prop *prop = chrGetTargetProp(chr);
|
|
return chrGetAngleToPos(chr, &prop->pos);
|
|
}
|
|
|
|
void chrGetAttackEntityPos(struct chrdata *chr, u32 attackflags, s32 entityid, struct coord *pos, s16 *rooms)
|
|
{
|
|
struct prop *targetprop;
|
|
struct chrdata *targetchr;
|
|
struct pad pad;
|
|
|
|
if (attackflags & ATTACKFLAG_AIMATCHR) {
|
|
// Aiming at a chr by chrnum
|
|
targetchr = chrFindById(chr, entityid);
|
|
|
|
if (!targetchr || !targetchr->prop) {
|
|
targetchr = chr;
|
|
}
|
|
|
|
pos->x = targetchr->prop->pos.x;
|
|
pos->y = targetchr->prop->pos.y;
|
|
pos->z = targetchr->prop->pos.z;
|
|
|
|
if (targetchr) {
|
|
chr = targetprop->chr;
|
|
} else {
|
|
chr = NULL;
|
|
}
|
|
|
|
if (chr);
|
|
|
|
roomsCopy(targetchr->prop->rooms, rooms);
|
|
} else if (attackflags & ATTACKFLAG_AIMATPAD) {
|
|
// Aiming at a pad by padnum
|
|
s32 padnum = chrResolvePadId(chr, entityid);
|
|
padUnpack(padnum, PADFIELD_POS | PADFIELD_ROOM, &pad);
|
|
|
|
pos->x = pad.pos.x;
|
|
pos->y = pad.pos.y;
|
|
pos->z = pad.pos.z;
|
|
|
|
rooms[0] = pad.room;
|
|
rooms[1] = -1;
|
|
} else {
|
|
// Aiming at the chr's preconfigured target
|
|
targetprop = chrGetTargetProp(chr);
|
|
|
|
pos->x = targetprop->pos.x;
|
|
pos->y = targetprop->pos.y;
|
|
pos->z = targetprop->pos.z;
|
|
|
|
if (targetprop->type == PROPTYPE_CHR && targetprop->chr) {
|
|
chr = targetprop->chr;
|
|
} else {
|
|
chr = NULL;
|
|
}
|
|
|
|
if (chr);
|
|
|
|
roomsCopy(targetprop->rooms, rooms);
|
|
}
|
|
}
|
|
|
|
f32 chrGetAngleFromTargetsFov(struct chrdata *chr)
|
|
{
|
|
f32 targetfacingangle = 0;
|
|
struct prop *prop = chr->prop;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
f32 angletotarget;
|
|
f32 result;
|
|
|
|
if (prop && target) {
|
|
xdiff = prop->pos.f[0] - target->pos.f[0];
|
|
zdiff = prop->pos.f[2] - target->pos.f[2];
|
|
angletotarget = atan2f(xdiff, zdiff);
|
|
|
|
if (target->type == PROPTYPE_PLAYER) {
|
|
s32 playernum = playermgrGetPlayerNumByProp(target);
|
|
targetfacingangle = (360.0f - g_Vars.players[playernum]->vv_theta) * M_BADTAU / 360.0f;
|
|
} else if (target->type == PROPTYPE_CHR) {
|
|
targetfacingangle = chrGetInverseTheta(target->chr);
|
|
}
|
|
|
|
result = angletotarget - targetfacingangle;
|
|
|
|
if (angletotarget < targetfacingangle) {
|
|
result += M_BADTAU;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
f32 chrGetVerticalAngleToTarget(struct chrdata *chr)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 result = 0;
|
|
|
|
if (prop && target) {
|
|
f32 ydiff;
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
|
|
xdiff = prop->pos.x - target->pos.x;
|
|
ydiff = prop->pos.y - target->pos.y;
|
|
zdiff = prop->pos.z - target->pos.z;
|
|
|
|
result = atan2f(ydiff, sqrtf(xdiff * xdiff + zdiff * zdiff));
|
|
|
|
if (result < 0) {
|
|
result += M_BADTAU;
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool chrIsInTargetsFovX(struct chrdata *chr, u8 fov360)
|
|
{
|
|
f32 angle = chrGetAngleFromTargetsFov(chr);
|
|
|
|
if ((angle < fov360 * 0.024539785459638f && angle < M_PI)
|
|
|| (angle > M_BADTAU - fov360 * 0.024539785459638f && angle > M_PI)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrIsVerticalAngleToTargetWithin(struct chrdata *chr, u8 fov360)
|
|
{
|
|
f32 val = chrGetVerticalAngleToTarget(chr);
|
|
|
|
if ((val < fov360 * 0.024539785459638f && val < M_PI)
|
|
|| (val > M_BADTAU - fov360 * 0.024539785459638f && val > M_PI)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
f32 func0f048fcc(struct chrdata *chr, u8 reverse)
|
|
{
|
|
f32 result;
|
|
|
|
struct prop *chrprop = chr->prop;
|
|
struct prop *targetprop = chrGetTargetProp(chr);
|
|
|
|
f32 xdiff = chrprop->pos.x - targetprop->pos.x;
|
|
f32 zdiff = chrprop->pos.z - targetprop->pos.z;
|
|
|
|
f32 angle1 = atan2f(-xdiff, -zdiff);
|
|
f32 angle2 = chrGetInverseTheta(chr) + M_PI * (s32)reverse;
|
|
|
|
result = angle1 - angle2;
|
|
|
|
if (angle1 < angle2) {
|
|
result += M_BADTAU;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool chrIsTargetInFov(struct chrdata *chr, u8 arg1, u8 reverse)
|
|
{
|
|
f32 angle = func0f048fcc(chr, reverse);
|
|
|
|
if ((angle < arg1 * 0.024539785459638f && angle < M_PI)
|
|
|| (angle > M_BADTAU - arg1 * 0.024539785459638f && angle > M_PI)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrIsLookingAtPos(struct chrdata *chr, struct coord *pos, u8 arg2)
|
|
{
|
|
f32 angle = chrGetAngleToPos(chr, pos);
|
|
|
|
if ((angle < arg2 * 0.024539785459638f && angle < M_PI) ||
|
|
(M_BADTAU - arg2 * 0.024539785459638f < angle && M_PI < angle)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
f32 chrGetDistanceToTarget(struct chrdata *chr)
|
|
{
|
|
struct prop *prop = chrGetTargetProp(chr);
|
|
return propGetDistanceToProp(chr->prop, prop);
|
|
}
|
|
|
|
// Redundant function - it's the same as above
|
|
f32 chrGetDistanceToTarget2(struct chrdata *chr)
|
|
{
|
|
struct prop *prop = chrGetTargetProp(chr);
|
|
return propGetDistanceToProp(chr->prop, prop);
|
|
}
|
|
|
|
f32 chrGetDistanceToCurrentPlayer(struct chrdata *chr)
|
|
{
|
|
return propGetDistanceToProp(chr->prop, g_Vars.currentplayer->prop);
|
|
}
|
|
|
|
f32 propGetDistanceToProp(struct prop *a, struct prop *b)
|
|
{
|
|
f32 xdiff = a->pos.x - b->pos.x;
|
|
f32 ydiff = a->pos.y - b->pos.y;
|
|
f32 zdiff = a->pos.z - b->pos.z;
|
|
|
|
return sqrtf(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
|
}
|
|
|
|
f32 propGetLateralDistanceToProp(struct prop *a, struct prop *b)
|
|
{
|
|
f32 xdiff = a->pos.x - b->pos.x;
|
|
f32 zdiff = a->pos.z - b->pos.z;
|
|
|
|
return sqrtf(xdiff * xdiff + zdiff * zdiff);
|
|
}
|
|
|
|
f32 chrGetDistanceToPad(struct chrdata *chr, s32 pad_id)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
f32 xdiff, ydiff, zdiff;
|
|
f32 distance = 0;
|
|
struct pad pad;
|
|
pad_id = chrResolvePadId(chr, pad_id);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (pad_id >= 0)
|
|
#endif
|
|
{
|
|
padUnpack(pad_id, PADFIELD_POS, &pad);
|
|
xdiff = pad.pos.x - prop->pos.x;
|
|
ydiff = pad.pos.y - prop->pos.y;
|
|
zdiff = pad.pos.z - prop->pos.z;
|
|
distance = sqrtf(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
|
}
|
|
|
|
return distance;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
f32 chrGetSameFloorDistanceToPad(struct chrdata *chr, s32 pad_id)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
f32 xdiff, ydiff, zdiff, ydiff_absolute;
|
|
struct pad pad;
|
|
f32 ret;
|
|
|
|
pad_id = chrResolvePadId(chr, pad_id);
|
|
padUnpack(pad_id, PADFIELD_POS, &pad);
|
|
xdiff = pad.pos.x - prop->pos.x;
|
|
ydiff = pad.pos.y - prop->pos.y;
|
|
zdiff = pad.pos.z - prop->pos.z;
|
|
|
|
if (ydiff > 0) {
|
|
ydiff_absolute = ydiff;
|
|
} else {
|
|
ydiff_absolute = -ydiff;
|
|
}
|
|
|
|
if (ydiff_absolute < 150) {
|
|
ret = sqrtf(xdiff * xdiff + zdiff * zdiff);
|
|
} else {
|
|
ret = 100000000;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
f32 chrGetDistanceToCoord(struct chrdata *chr, struct coord *pos)
|
|
{
|
|
f32 xdiff = pos->x - chr->prop->pos.x;
|
|
f32 ydiff = pos->y - chr->prop->pos.y;
|
|
f32 zdiff = pos->z - chr->prop->pos.z;
|
|
|
|
return sqrtf(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
|
}
|
|
|
|
f32 chrGetLateralDistanceToCoord(struct chrdata *chr, struct coord *pos)
|
|
{
|
|
f32 xdiff = pos->x - chr->prop->pos.x;
|
|
f32 zdiff = pos->z - chr->prop->pos.z;
|
|
|
|
return sqrtf(xdiff * xdiff + zdiff * zdiff);
|
|
}
|
|
|
|
f32 chrGetLateralDistanceToPad(struct chrdata *chr, s32 pad_id)
|
|
{
|
|
struct prop *prop = chr->prop;
|
|
f32 xdiff, zdiff;
|
|
struct pad pad;
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
f32 distance = 0;
|
|
|
|
pad_id = chrResolvePadId(chr, pad_id);
|
|
|
|
if (pad_id >= 0) {
|
|
padUnpack(pad_id, PADFIELD_POS, &pad);
|
|
xdiff = pad.pos.x - prop->pos.x;
|
|
zdiff = pad.pos.z - prop->pos.z;
|
|
distance = sqrtf(xdiff * xdiff + zdiff * zdiff);
|
|
}
|
|
|
|
return distance;
|
|
#else
|
|
pad_id = chrResolvePadId(chr, pad_id);
|
|
padUnpack(pad_id, PADFIELD_POS, &pad);
|
|
xdiff = pad.pos.x - prop->pos.x;
|
|
zdiff = pad.pos.z - prop->pos.z;
|
|
return sqrtf(xdiff * xdiff + zdiff * zdiff);
|
|
#endif
|
|
}
|
|
|
|
f32 chrGetSquaredDistanceToCoord(struct chrdata *chr, struct coord *pos)
|
|
{
|
|
f32 xdiff = pos->x - chr->prop->pos.x;
|
|
f32 ydiff = pos->y - chr->prop->pos.y;
|
|
f32 zdiff = pos->z - chr->prop->pos.z;
|
|
|
|
return xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
|
|
}
|
|
|
|
f32 coordGetSquaredDistanceToCoord(struct coord *a, struct coord *b)
|
|
{
|
|
f32 xdiff = a->x - b->x;
|
|
f32 ydiff = a->y - b->y;
|
|
f32 zdiff = a->z - b->z;
|
|
|
|
return xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
|
|
}
|
|
|
|
s32 chrGetPadRoom(struct chrdata *chr, s32 pad_id)
|
|
{
|
|
s32 ret = -1;
|
|
s32 pad_id_backup = pad_id;
|
|
struct pad pad;
|
|
|
|
if (pad_id >= 10000) {
|
|
s32 resolved_pad_id = chrResolvePadId(chr, pad_id - 10000);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (resolved_pad_id >= 0)
|
|
#endif
|
|
{
|
|
padUnpack(resolved_pad_id, PADFIELD_ROOM, &pad);
|
|
ret = pad.room;
|
|
}
|
|
} else {
|
|
ret = pad_id;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
s32 chrResolvePadId(struct chrdata *chr, s32 pad_id)
|
|
{
|
|
if (pad_id == 9000) {
|
|
pad_id = chr->padpreset1;
|
|
}
|
|
|
|
return pad_id;
|
|
}
|
|
|
|
/**
|
|
* For all chrs, clear their target and p1p2 values if set to the given player.
|
|
*
|
|
* This function is called when the given player has died. It causes all guards
|
|
* to switch their focus to the remaining coop player.
|
|
*/
|
|
void chrsClearRefsToPlayer(s32 playernum)
|
|
{
|
|
s32 otherplayernum;
|
|
s32 playerpropnum;
|
|
s32 i;
|
|
|
|
if (g_Vars.coopplayernum >= 0) {
|
|
if (playernum == g_Vars.bondplayernum) {
|
|
otherplayernum = g_Vars.coopplayernum;
|
|
playerpropnum = g_Vars.bond->prop - g_Vars.props;
|
|
} else {
|
|
otherplayernum = g_Vars.bondplayernum;
|
|
playerpropnum = g_Vars.coop->prop - g_Vars.props;
|
|
}
|
|
|
|
for (i = 0; i < chrsGetNumSlots(); i++) {
|
|
if (g_ChrSlots[i].p1p2 == playernum) {
|
|
g_ChrSlots[i].p1p2 = otherplayernum;
|
|
}
|
|
|
|
if (g_ChrSlots[i].target == playerpropnum) {
|
|
g_ChrSlots[i].target = -1;
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < g_NumBgChrs; i++) {
|
|
if (g_BgChrs[i].p1p2 == playernum) {
|
|
g_BgChrs[i].p1p2 = otherplayernum;
|
|
}
|
|
|
|
if (g_BgChrs[i].target == playerpropnum) {
|
|
g_BgChrs[i].target = -1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 chrResolveId(struct chrdata *ref, s32 id)
|
|
{
|
|
if (ref) {
|
|
switch (id) {
|
|
case CHR_SEESHOT:
|
|
id = ref->chrseeshot;
|
|
break;
|
|
case CHR_SEEDIE:
|
|
id = ref->chrseedie;
|
|
break;
|
|
case CHR_PRESET:
|
|
id = ref->chrpreset1;
|
|
break;
|
|
case CHR_SELF:
|
|
id = ref->chrnum;
|
|
break;
|
|
case CHR_CLONE:
|
|
id = ref->chrdup;
|
|
break;
|
|
case CHR_BOND:
|
|
if (g_Vars.bond && g_Vars.bond->prop && g_Vars.bond->prop->chr) {
|
|
id = g_Vars.bond->prop->chr->chrnum;
|
|
}
|
|
break;
|
|
case CHR_COOP:
|
|
if (g_Vars.coop && g_Vars.coop->prop && g_Vars.coop->prop->chr) {
|
|
id = g_Vars.coop->prop->chr->chrnum;
|
|
}
|
|
break;
|
|
case CHR_ANTI:
|
|
if (g_Vars.anti && g_Vars.anti->prop && g_Vars.anti->prop->chr) {
|
|
id = g_Vars.anti->prop->chr->chrnum;
|
|
}
|
|
break;
|
|
case CHR_P1P2:
|
|
{
|
|
u32 index = g_Vars.coopplayernum >= 0 ? ref->p1p2 : g_Vars.bondplayernum;
|
|
struct player *player = g_Vars.players[index];
|
|
if (player && player->prop && player->prop->chr) {
|
|
id = player->prop->chr->chrnum;
|
|
}
|
|
}
|
|
break;
|
|
case CHR_P1P2_OPPOSITE:
|
|
if (g_Vars.coopplayernum >= 0) {
|
|
struct player *player = g_Vars.players[1 - ref->p1p2];
|
|
if (player && player->prop && player->prop->chr) {
|
|
id = player->prop->chr->chrnum;
|
|
}
|
|
}
|
|
break;
|
|
case CHR_TARGET:
|
|
{
|
|
struct prop *target = chrGetTargetProp(ref);
|
|
if ((target->type == PROPTYPE_CHR || target->type == PROPTYPE_PLAYER) && target->chr) {
|
|
id = target->chr->chrnum;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
} else { // ref is NULL
|
|
switch (id) {
|
|
case CHR_BOND:
|
|
if (g_Vars.bond && g_Vars.bond->prop && g_Vars.bond->prop->chr) {
|
|
id = g_Vars.bond->prop->chr->chrnum;
|
|
}
|
|
break;
|
|
case CHR_COOP:
|
|
if (g_Vars.coop && g_Vars.coop->prop && g_Vars.coop->prop->chr) {
|
|
id = g_Vars.coop->prop->chr->chrnum;
|
|
}
|
|
break;
|
|
case CHR_ANTI:
|
|
if (g_Vars.anti && g_Vars.anti->prop && g_Vars.anti->prop->chr) {
|
|
id = g_Vars.anti->prop->chr->chrnum;
|
|
}
|
|
break;
|
|
case CHR_P1P2:
|
|
{
|
|
struct player *player = g_Vars.players[g_Vars.bondplayernum];
|
|
if (player && player->prop && player->prop->chr) {
|
|
id = player->prop->chr->chrnum;
|
|
}
|
|
}
|
|
break;
|
|
case CHR_P1P2_OPPOSITE:
|
|
if (g_Vars.coopplayernum >= 0) {
|
|
struct player *player = g_Vars.players[g_Vars.coopplayernum];
|
|
if (player && player->prop && player->prop->chr) {
|
|
id = player->prop->chr->chrnum;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
struct chrdata *chrFindById(struct chrdata *basechr, s32 chrnum)
|
|
{
|
|
struct chrdata *chr;
|
|
s32 lower;
|
|
s32 upper;
|
|
s32 i;
|
|
|
|
chrnum = chrResolveId(basechr, chrnum);
|
|
chr = chrFindByLiteralId(chrnum);
|
|
|
|
if (chr) {
|
|
return chr;
|
|
}
|
|
|
|
lower = 0;
|
|
upper = g_NumBgChrs;
|
|
|
|
while (upper >= lower) {
|
|
i = (lower + upper) / 2;
|
|
|
|
if (chrnum == g_BgChrnums[i]) {
|
|
return &g_BgChrs[i];
|
|
}
|
|
|
|
if (chrnum < g_BgChrnums[i]) {
|
|
upper = i - 1;
|
|
} else {
|
|
lower = i + 1;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
s32 propGetIndexByChrId(struct chrdata *basechr, s32 chrnum)
|
|
{
|
|
s32 index;
|
|
|
|
if (chrnum == CHR_BOND || chrnum == CHR_BOND) {
|
|
index = g_Vars.bond->prop - g_Vars.props;
|
|
} else {
|
|
struct chrdata *chr = chrFindById(basechr, chrnum);
|
|
|
|
if (chr && chr->prop) {
|
|
index = chr->prop - g_Vars.props;
|
|
} else {
|
|
index = -1;
|
|
}
|
|
}
|
|
|
|
return index;
|
|
}
|
|
|
|
f32 chrGetDistanceToChr(struct chrdata *chr1, s32 chr2num)
|
|
{
|
|
struct prop *prop1 = chr1->prop;
|
|
struct chrdata *chr2 = chrFindById(chr1, chr2num);
|
|
f32 distance = 0;
|
|
|
|
if (chr2 && chr2->prop) {
|
|
f32 xdiff = chr2->prop->pos.x - prop1->pos.x;
|
|
f32 ydiff = chr2->prop->pos.y - prop1->pos.y;
|
|
f32 zdiff = chr2->prop->pos.z - prop1->pos.z;
|
|
distance = sqrtf(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
|
}
|
|
|
|
return distance;
|
|
}
|
|
|
|
f32 chrGetDistanceFromTargetToPad(struct chrdata *chr, s32 pad_id)
|
|
{
|
|
struct prop *prop = chrGetTargetProp(chr);
|
|
f32 xdiff, ydiff, zdiff;
|
|
struct pad pad;
|
|
f32 distance = 0;
|
|
pad_id = chrResolvePadId(chr, pad_id);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (pad_id >= 0)
|
|
#endif
|
|
{
|
|
padUnpack(pad_id, PADFIELD_POS, &pad);
|
|
xdiff = pad.pos.x - prop->pos.x;
|
|
ydiff = pad.pos.y - prop->pos.y;
|
|
zdiff = pad.pos.z - prop->pos.z;
|
|
distance = sqrtf(xdiff * xdiff + ydiff * ydiff + zdiff * zdiff);
|
|
}
|
|
|
|
return distance;
|
|
}
|
|
|
|
void chrSetFlags(struct chrdata *chr, u32 flags, u8 bank)
|
|
{
|
|
if (bank == 0) {
|
|
chr->flags |= flags;
|
|
} else {
|
|
chr->flags2 |= flags;
|
|
}
|
|
}
|
|
|
|
void chrUnsetFlags(struct chrdata *chr, u32 flags, u8 bank)
|
|
{
|
|
if (bank == 0) {
|
|
chr->flags &= ~flags;
|
|
} else {
|
|
chr->flags2 &= ~flags;
|
|
}
|
|
}
|
|
|
|
bool chrHasFlag(struct chrdata *chr, u32 flag, u8 bank)
|
|
{
|
|
if (bank == 0) {
|
|
return (chr->flags & flag) != 0;
|
|
} else {
|
|
return (chr->flags2 & flag) != 0;
|
|
}
|
|
}
|
|
|
|
void chrSetFlagsById(struct chrdata *ref, u32 chrnum, u32 flags, u32 bank)
|
|
{
|
|
struct chrdata *chr = chrFindById(ref, chrnum);
|
|
|
|
if (chr) {
|
|
chrSetFlags(chr, flags, bank);
|
|
}
|
|
}
|
|
|
|
void chrUnsetFlagsById(struct chrdata *ref, u32 chrnum, u32 flags, u32 bank)
|
|
{
|
|
struct chrdata *chr = chrFindById(ref, chrnum);
|
|
|
|
if (chr) {
|
|
chrUnsetFlags(chr, flags, bank);
|
|
}
|
|
}
|
|
|
|
bool chrHasFlagById(struct chrdata *ref, u32 chrnum, u32 flag, u32 bank)
|
|
{
|
|
struct chrdata *chr = chrFindById(ref, chrnum);
|
|
|
|
if (chr) {
|
|
return chrHasFlag(chr, flag, bank);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void chrSetStageFlag(struct chrdata *chr, u32 flag)
|
|
{
|
|
g_StageFlags |= flag;
|
|
}
|
|
|
|
void chrUnsetStageFlag(struct chrdata *chr, u32 flag)
|
|
{
|
|
g_StageFlags = g_StageFlags & ~flag;
|
|
}
|
|
|
|
bool chrHasStageFlag(struct chrdata *chr, u32 flag)
|
|
{
|
|
return (g_StageFlags & flag) != 0;
|
|
}
|
|
|
|
bool chrIsHearingTarget(struct chrdata *chr)
|
|
{
|
|
return (chr->hidden & CHRHFLAG_IS_HEARING_TARGET) != 0;
|
|
}
|
|
|
|
void chrRestartTimer(struct chrdata *chr)
|
|
{
|
|
chr->timer60 = 0;
|
|
chr->hidden |= CHRHFLAG_TIMER_RUNNING;
|
|
}
|
|
|
|
f32 chrGetTimer(struct chrdata *chr)
|
|
{
|
|
return chr->timer60 * FRAMEDURATION;
|
|
}
|
|
|
|
bool chrCanSeeTargetWithExtraCheck(struct chrdata *chr)
|
|
{
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
|
|
if (target) {
|
|
if (target->type == PROPTYPE_CHR) {
|
|
if (!chrCanSeeTarget(chr)) {
|
|
return false;
|
|
}
|
|
|
|
return chrIsInTargetsFovX(chr, 20);
|
|
}
|
|
|
|
if (target->type == PROPTYPE_PLAYER) {
|
|
if (g_Vars.bondvisible &&
|
|
(cdHasLineOfSight(&target->pos, target->rooms, &chr->prop->pos, chr->prop->rooms, 51, 8))) {
|
|
struct model *model = chr->model;
|
|
struct coord sp68;
|
|
struct coord sp56;
|
|
struct coord sp44;
|
|
f32 somefloat = model0001af80(model) * 0.8f;
|
|
|
|
bgun0f0a0c08(&sp68, &sp56);
|
|
modelGetRootPosition(model, &sp44);
|
|
mtx4TransformVecInPlace(camGetWorldToScreenMtxf(), &sp44);
|
|
|
|
if (func0f06b39c(&sp68, &sp56, &sp44, somefloat)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrResetNearMiss(struct chrdata *chr)
|
|
{
|
|
bool has_flag = (chr->chrflags & CHRCFLAG_NEAR_MISS) != 0;
|
|
chr->chrflags &= ~CHRCFLAG_NEAR_MISS;
|
|
|
|
return has_flag;
|
|
}
|
|
|
|
s32 chrGetNumArghs(struct chrdata *chr)
|
|
{
|
|
return chr->numarghs;
|
|
}
|
|
|
|
s32 chrGetNumCloseArghs(struct chrdata *chr)
|
|
{
|
|
return chr->numclosearghs;
|
|
}
|
|
|
|
bool chrSawInjury(struct chrdata *chr, u8 arg1)
|
|
{
|
|
bool saw_injury = chr->chrseeshot >= 0;
|
|
|
|
if (saw_injury && arg1 == 0) {
|
|
chr->chrseeshot = -1;
|
|
} else if (saw_injury && arg1 == 1) {
|
|
struct chrdata *victim = chrFindById(chr, chr->chrseeshot);
|
|
|
|
if (victim && !chrCompareTeams(chr, victim, COMPARE_FRIENDS)) {
|
|
saw_injury = false;
|
|
}
|
|
} else {
|
|
chr->chrseeshot = -1;
|
|
}
|
|
|
|
return saw_injury;
|
|
}
|
|
|
|
bool chrSawDeath(struct chrdata *chr, u8 arg1)
|
|
{
|
|
bool saw_death = chr->chrseedie >= 0;
|
|
|
|
// The commented line below was likely originally there but removed before
|
|
// the final version. Compare with chrSawInjury above.
|
|
if (saw_death && arg1 == 0) {
|
|
//chr->chrseedie = -1;
|
|
} else if (saw_death && arg1 == 1) {
|
|
struct chrdata *victim = chrFindById(chr, chr->chrseedie);
|
|
|
|
if (victim && !chrCompareTeams(chr, victim, COMPARE_FRIENDS)) {
|
|
saw_death = false;
|
|
chr->chrseedie = -1;
|
|
}
|
|
} else {
|
|
chr->chrseedie = -1;
|
|
}
|
|
|
|
return saw_death;
|
|
}
|
|
|
|
void decrementByte(u8 *dst, u8 amount)
|
|
{
|
|
if (*dst < amount) {
|
|
*dst = 0;
|
|
return;
|
|
}
|
|
|
|
*dst -= amount;
|
|
}
|
|
|
|
void incrementByte(u8 *dst, u8 amount)
|
|
{
|
|
if (0xff - amount < *dst) {
|
|
*dst = 0xff;
|
|
return;
|
|
}
|
|
|
|
*dst += amount;
|
|
}
|
|
|
|
bool chrCanHearAlarm(struct chrdata *chr)
|
|
{
|
|
return alarmIsActive();
|
|
}
|
|
|
|
bool waypointIsWithin90DegreesOfPosAngle(struct waypoint *waypoint, struct coord *pos, f32 angle)
|
|
{
|
|
u32 stack[3];
|
|
f32 diffangle;
|
|
struct pad pad;
|
|
|
|
padUnpack(waypoint->padnum, PADFIELD_POS, &pad);
|
|
|
|
diffangle = angle - atan2f(pad.pos.x - pos->x, pad.pos.z - pos->z);
|
|
|
|
if (diffangle < 0) {
|
|
diffangle += M_BADTAU;
|
|
}
|
|
|
|
if (diffangle < 1.5705462694168f || diffangle > 4.7116389274597f) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Attempt to find a waypoint near pos which is in a particular quadrant to pos,
|
|
* then return its padnum.
|
|
*
|
|
* For example, pos is typically the player's position, angle is the direction
|
|
* the player is facing, and quadrant is which quadrant (front/back/left/right)
|
|
* that is desired relative to the player's position and angle.
|
|
*
|
|
* The function starts by finding the closest waypoint to the pos. If it's not
|
|
* in the quadrant then its neighouring waypoints are checked too. If none of
|
|
* those are in the quadrant then no further checks are made and the function
|
|
* returns -1.
|
|
*/
|
|
s32 chrFindWaypointWithinPosQuadrant(struct coord *pos, s16 *rooms, f32 angle, u8 quadrant)
|
|
{
|
|
struct waypoint *waypoint = waypointFindClosestToPos(pos, rooms);
|
|
s32 neighbournum;
|
|
s32 i;
|
|
|
|
if (waypoint) {
|
|
switch (quadrant) {
|
|
case QUADRANT_BACK:
|
|
angle += M_BADPI;
|
|
break;
|
|
case QUADRANT_SIDE1:
|
|
angle += 1.5705462694168f;
|
|
break;
|
|
case QUADRANT_SIDE2:
|
|
angle += 4.7116389274597f;
|
|
break;
|
|
case QUADRANT_FRONT:
|
|
break;
|
|
}
|
|
|
|
if (angle >= M_BADTAU) {
|
|
angle -= M_BADTAU;
|
|
}
|
|
|
|
if (waypointIsWithin90DegreesOfPosAngle(waypoint, pos, angle)) {
|
|
return waypoint->padnum;
|
|
}
|
|
|
|
for (i = 0; (neighbournum = waypoint->neighbours[i]) >= 0; i++) {
|
|
if ((neighbournum & 0x8000) == 0) {
|
|
neighbournum &= 0x3fff;
|
|
|
|
if (waypointIsWithin90DegreesOfPosAngle(&g_StageSetup.waypoints[neighbournum], pos, angle)) {
|
|
return g_StageSetup.waypoints[neighbournum].padnum;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
bool func0f04a4ec(struct chrdata *chr, u8 quadrant)
|
|
{
|
|
if (quadrant == QUADRANT_2NDWPTOTARGET || quadrant == QUADRANT_20) {
|
|
struct prop *prop = chr->prop;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
|
|
struct waypoint *fromwp = waypointFindClosestToPos(&prop->pos, prop->rooms);
|
|
struct waypoint *towp = waypointFindClosestToPos(&target->pos, target->rooms);
|
|
|
|
// @dangerous: I'm creating an array overflow here to get a match.
|
|
// waypoints should have len 3 but this causes a mismatch due to too
|
|
// much stack usage. If compiling using anything other than IDO and -O2
|
|
// then this will need to be changed to 3.
|
|
s32 numwaypoints;
|
|
struct waypoint *waypoints[2];
|
|
u32 hash;
|
|
|
|
if (fromwp && towp) {
|
|
if (quadrant == QUADRANT_2NDWPTOTARGET) {
|
|
hash = (g_Vars.lvframe60 >> 9) * 128 + chr->chrnum * 8;
|
|
|
|
waypointSetHashThing(hash, hash);
|
|
numwaypoints = waypointFindRoute(fromwp, towp, waypoints, 3);
|
|
waypointSetHashThing(0, 0);
|
|
|
|
if (numwaypoints >= 3) {
|
|
chr->padpreset1 = waypoints[1]->padnum;
|
|
return true;
|
|
}
|
|
} else {
|
|
hash = (g_Vars.lvframe60 >> 9) * 128 + chr->chrnum * 8;
|
|
|
|
waypointSetHashThing(hash, hash);
|
|
fromwp = func0f1155e0(fromwp, towp);
|
|
waypointSetHashThing(0, 0);
|
|
|
|
if (fromwp) {
|
|
chr->padpreset1 = fromwp->padnum;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
s32 padnum = chrFindWaypointWithinPosQuadrant(&chr->prop->pos, chr->prop->rooms, chrGetInverseTheta(chr), quadrant);
|
|
|
|
if (padnum >= 0) {
|
|
chr->padpreset1 = padnum;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrSetPadPresetToWaypointWithinTargetQuadrant(struct chrdata *chr, u8 quadrant)
|
|
{
|
|
f32 angle;
|
|
s32 padnum;
|
|
struct prop *prop;
|
|
|
|
if (quadrant == QUADRANT_2NDWPTOTARGET || quadrant == QUADRANT_20) {
|
|
return func0f04a4ec(chr, quadrant);
|
|
}
|
|
|
|
angle = 0;
|
|
prop = chrGetTargetProp(chr);
|
|
|
|
if (prop->type == PROPTYPE_PLAYER) {
|
|
angle = (360.0f - g_Vars.players[playermgrGetPlayerNumByProp(prop)]->vv_theta) * M_BADTAU / 360.0f;
|
|
} else if (prop->type == PROPTYPE_CHR) {
|
|
angle = chrGetInverseTheta(prop->chr);
|
|
}
|
|
|
|
padnum = chrFindWaypointWithinPosQuadrant(&prop->pos, prop->rooms, angle, quadrant);
|
|
|
|
if (padnum >= 0) {
|
|
chr->padpreset1 = padnum;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrSetChrPresetToAnyChrNearSelf(struct chrdata *chr, f32 distance)
|
|
{
|
|
return chrSetChrPresetToChrNearSelf(COMPARE_ANY, chr, distance);
|
|
}
|
|
|
|
bool chrSetChrPresetToChrNearSelf(u8 checktype, struct chrdata *chr, f32 distance)
|
|
{
|
|
return chrSetChrPresetToChrNearPos(checktype, chr, distance, &chr->prop->pos, chr->prop->rooms);
|
|
}
|
|
|
|
bool chrSetChrPresetToChrNearPad(u32 checktype, struct chrdata *chr, f32 distance, s32 padnum)
|
|
{
|
|
struct pad pad;
|
|
s16 rooms[2];
|
|
|
|
padnum = chrResolvePadId(chr, padnum);
|
|
padUnpack(padnum, PADFIELD_POS | PADFIELD_ROOM, &pad);
|
|
|
|
rooms[0] = pad.room;
|
|
rooms[1] = -1;
|
|
|
|
return chrSetChrPresetToChrNearPos(checktype, chr, distance, &pad.pos, rooms);
|
|
}
|
|
|
|
bool chrSetChrPresetToChrNearPos(u8 checktype, struct chrdata *chr, f32 distance, struct coord *pos, s16 *rooms)
|
|
{
|
|
s32 i;
|
|
s16 *propnumptr;
|
|
s16 propnums[256];
|
|
s16 allrooms[21];
|
|
f32 xmin = pos->x - distance;
|
|
f32 xmax = pos->x + distance;
|
|
f32 ymin = pos->y - distance;
|
|
f32 ymax = pos->y + distance;
|
|
f32 zmin = pos->z - distance;
|
|
f32 zmax = pos->z + distance;
|
|
s16 neighbours[11];
|
|
|
|
roomsCopy(rooms, allrooms);
|
|
|
|
for (i = 0; rooms[i] != -1; i++) {
|
|
roomGetNeighbours(rooms[i], neighbours, 10);
|
|
roomsAppend(neighbours, allrooms, 20);
|
|
}
|
|
|
|
roomGetProps(allrooms, propnums, 256);
|
|
|
|
propnumptr = propnums;
|
|
|
|
while (*propnumptr >= 0) {
|
|
struct prop *prop = &g_Vars.props[*propnumptr];
|
|
|
|
if (prop->type == PROPTYPE_CHR || prop->type == PROPTYPE_PLAYER) {
|
|
struct chrdata *loopchr = prop->chr;
|
|
|
|
if (loopchr->chrnum != chr->chrnum
|
|
&& !chrIsDead(loopchr)
|
|
&& prop->pos.x >= xmin
|
|
&& prop->pos.x <= xmax
|
|
&& prop->pos.y >= ymin
|
|
&& prop->pos.y <= ymax
|
|
&& prop->pos.z >= zmin
|
|
&& prop->pos.z <= zmax
|
|
&& chrCompareTeams(loopchr, chr, checktype)) {
|
|
chr->chrpreset1 = loopchr->chrnum;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
*propnumptr++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrCompareTeams(struct chrdata *chr1, struct chrdata *chr2, u8 checktype)
|
|
{
|
|
if (chr1 && chr1->prop) {
|
|
if (checktype == COMPARE_ANY) {
|
|
return true;
|
|
}
|
|
|
|
if (checktype == COMPARE_FRIENDS) { // Return true if chrs are friends
|
|
if (g_Vars.normmplayerisrunning) {
|
|
if ((g_MpSetup.options & MPOPTION_TEAMSENABLED) && chr2->team == chr1->team) {
|
|
return true;
|
|
}
|
|
} else {
|
|
if (g_Vars.bond && g_Vars.bond->prop) {
|
|
struct chrdata *playerchr = g_Vars.bond->prop->chr;
|
|
|
|
// @bug: This makes Jon an ally in Duel
|
|
if ((chr2 == playerchr && chr1->headnum == HEAD_JONATHAN) ||
|
|
(chr1 == playerchr && chr2->headnum == HEAD_JONATHAN)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if ((chr2->team & chr1->team) != 0) {
|
|
return true;
|
|
}
|
|
}
|
|
} else if (checktype == COMPARE_ENEMIES) { // Return true if chrs are enemies
|
|
if (g_Vars.normmplayerisrunning) {
|
|
if ((g_MpSetup.options & MPOPTION_TEAMSENABLED) == 0 || chr2->team != chr1->team) {
|
|
return true;
|
|
}
|
|
} else {
|
|
if (g_Vars.bond && g_Vars.bond->prop) {
|
|
struct chrdata *playerchr = g_Vars.bond->prop->chr;
|
|
|
|
// @bug: This makes Jon an ally in Duel
|
|
if ((chr2 == playerchr && chr1->headnum == HEAD_JONATHAN) ||
|
|
(chr1 == playerchr && chr2->headnum == HEAD_JONATHAN)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ((chr2->team & chr1->team) == 0) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void chrSetChrPreset(struct chrdata *chr, s32 chrpreset)
|
|
{
|
|
chr->chrpreset1 = chrResolveId(chr, chrpreset);
|
|
}
|
|
|
|
void chrSetChrPresetByChrnum(struct chrdata *basechr, s32 chrnum, s32 chrpreset)
|
|
{
|
|
struct chrdata *chr = chrFindById(basechr, chrnum);
|
|
|
|
if (chr) {
|
|
chr->chrpreset1 = chrResolveId(basechr, chrpreset);
|
|
}
|
|
}
|
|
|
|
void chrSetPadPreset(struct chrdata *chr, s32 pad_id)
|
|
{
|
|
chr->padpreset1 = chrResolvePadId(chr, pad_id);
|
|
}
|
|
|
|
void chrSetPadPresetByChrnum(struct chrdata *basechr, s32 chrnum, s32 pad_id)
|
|
{
|
|
struct chrdata *chr = chrFindById(basechr, chrnum);
|
|
|
|
if (chr) {
|
|
chr->padpreset1 = chrResolvePadId(basechr, pad_id);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if chr has line of sight (I think?) to their target. If so, find a
|
|
* route to them, then iterate the route backwards (from target to chr). Find
|
|
* the first waypoint with line of sight and store it as the chr's pad preset.
|
|
*/
|
|
bool chrSetPadPresetToPadOnRouteToTarget(struct chrdata *chr)
|
|
{
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
struct prop *prop = chr->prop;
|
|
struct waypoint *fromwp;
|
|
struct waypoint *towp;
|
|
struct waypoint *waypoints[5];
|
|
s32 numwaypoints;
|
|
s32 i;
|
|
struct pad pad;
|
|
|
|
if (target->type != PROPTYPE_PLAYER || g_Vars.bondvisible) {
|
|
if (cd0002dc18(&prop->pos, prop->rooms, &target->pos, CDTYPE_BG)) {
|
|
return false;
|
|
}
|
|
|
|
fromwp = waypointFindClosestToPos(&prop->pos, prop->rooms);
|
|
towp = waypointFindClosestToPos(&target->pos, target->rooms);
|
|
|
|
if (fromwp && towp) {
|
|
u32 hash = (g_Vars.lvframe60 >> 9) * 128 + chr->chrnum * 8;
|
|
|
|
// Note from/to are swapped here, so the route is from target to chr
|
|
waypointSetHashThing(hash, hash);
|
|
numwaypoints = waypointFindRoute(towp, fromwp, waypoints, 5);
|
|
waypointSetHashThing(0, 0);
|
|
|
|
if (numwaypoints >= 3) {
|
|
for (i = 0; waypoints[i] != NULL; i++) {
|
|
struct waypoint *wp = waypoints[i];
|
|
|
|
padUnpack(wp->padnum, PADFIELD_POS, &pad);
|
|
|
|
if (cd0002dc18(&target->pos, target->rooms, &pad.pos, CDTYPE_BG)) {
|
|
if (cd0002dc18(&prop->pos, prop->rooms, &pad.pos, CDTYPE_BG)) {
|
|
chr->padpreset1 = wp->padnum;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool chrIsPosOffScreen(struct coord *pos, s16 *rooms)
|
|
{
|
|
bool offscreen = true;
|
|
s32 i;
|
|
|
|
if (env0f1666f8(pos, 0)) {
|
|
for (i = 0; rooms[i] != -1; i++) {
|
|
if (roomIsOnscreen(rooms[i])) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (rooms[i] != -1) {
|
|
// Room is visible by player
|
|
offscreen = !camIsPosInScreenBox(pos, 200, func0f158140(rooms[i]));
|
|
}
|
|
}
|
|
|
|
return offscreen;
|
|
}
|
|
|
|
/**
|
|
* Test if a chr can be spawned into or nearby the given position, taking into
|
|
* consideration collision checks.
|
|
*
|
|
* If the spawn can happen, the position and rooms are updated with the actual
|
|
* position to be used and the function returns true.
|
|
*
|
|
* If the spawn cannot happen, the function return false.
|
|
*/
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
bool chrAdjustPosForSpawn(f32 chrradius, struct coord *pos, s16 *rooms, f32 angle, bool allowonscreen, bool ignorebg, bool arg6)
|
|
{
|
|
struct coord testpos;
|
|
s32 i;
|
|
u32 types;
|
|
s16 testrooms[8];
|
|
f32 ymin;
|
|
f32 ymax = 200;
|
|
f32 curangle = angle;
|
|
f32 ground;
|
|
|
|
if (ignorebg) {
|
|
types = CDTYPE_ALL & ~CDTYPE_BG;
|
|
allowonscreen = true;
|
|
} else {
|
|
types = CDTYPE_ALL;
|
|
}
|
|
|
|
if (arg6) {
|
|
// Skip testing the given pos, and just do the surrounding checks below.
|
|
// Add 45 degrees to the angle here, but this isn't necessary.
|
|
curangle += 0.7852731347084f;
|
|
|
|
if (curangle >= M_BADTAU) {
|
|
curangle -= M_BADTAU;
|
|
}
|
|
} else {
|
|
// Check that the chr isn't being spawned out of bounds, and do a volume
|
|
// test reaching 200cm above and below the chr's feet... unless there is
|
|
// ground under the chr (highly likely), in which case reduce the volume
|
|
// to be tested to the ground Y value. I'm not sure why this is useful,
|
|
// because if the chr was being spawned on top of another chr or object
|
|
// then the calculated ground value would be raised.
|
|
ymin = -200;
|
|
ground = cdFindGroundYSimple(pos, chrradius, rooms, NULL, NULL);
|
|
|
|
if (ground > -100000 && ground - pos->y < -200) {
|
|
ymin = ground - pos->y;
|
|
}
|
|
|
|
if (cdTestVolume(pos, chrradius, rooms, types, 1, ymax, ymin) != CDRESULT_COLLISION
|
|
&& (allowonscreen || chrIsPosOffScreen(pos, rooms))) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Try 60cm in 8 directions
|
|
for (i = 0; i < 8; i++) {
|
|
testpos.x = pos->x + sinf(curangle) * 60;
|
|
testpos.y = pos->y;
|
|
testpos.z = pos->z + cosf(curangle) * 60;
|
|
|
|
if ((arg6 && cd0002d840(pos, rooms, &testpos, testrooms, CDTYPE_ALL & ~CDTYPE_PLAYERS, 1, ymax, -200) != CDRESULT_COLLISION)
|
|
|| (!arg6 && cd0002deac(pos, rooms, &testpos, testrooms, CDTYPE_BG))) {
|
|
chr0f021fa8(NULL, &testpos, testrooms);
|
|
ground = cdFindGroundYSimple(&testpos, chrradius, testrooms, 0, 0);
|
|
ymin = -200;
|
|
|
|
if (ground > -100000 && ground - pos->y < -200) {
|
|
ymin = ground - pos->y;
|
|
}
|
|
|
|
if (cdTestVolume(&testpos, chrradius, testrooms, CDTYPE_ALL, 1, ymax, ymin) != CDRESULT_COLLISION
|
|
&& (allowonscreen || chrIsPosOffScreen(&testpos, testrooms))
|
|
&& (!arg6 || ground > -100000)) {
|
|
pos->x = testpos.x;
|
|
pos->y = testpos.y;
|
|
pos->z = testpos.z;
|
|
roomsCopy(testrooms, rooms);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
curangle += 0.7852731347084f;
|
|
|
|
if (curangle >= M_BADTAU) {
|
|
curangle -= M_BADTAU;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#else
|
|
/**
|
|
* ntsc-beta's version of this function doesn't have the arg6 argument
|
|
* nor out of bounds checking, and lacks the reduction for the volume test.
|
|
*/
|
|
bool chrAdjustPosForSpawn(f32 chrradius, struct coord *pos, s16 *rooms, f32 angle, bool allowonscreen, bool ignorebg)
|
|
{
|
|
struct coord testpos;
|
|
s32 i;
|
|
u32 types;
|
|
s16 testrooms[8];
|
|
f32 curangle = angle;
|
|
|
|
if (ignorebg) {
|
|
types = CDTYPE_ALL & ~CDTYPE_BG;
|
|
allowonscreen = true;
|
|
} else {
|
|
types = CDTYPE_ALL;
|
|
}
|
|
|
|
if (cdTestVolume(pos, chrradius, rooms, types, 1, 200, -200) != CDRESULT_COLLISION
|
|
&& (allowonscreen || chrIsPosOffScreen(pos, rooms))) {
|
|
return true;
|
|
}
|
|
|
|
for (i = 0; i < 8; i++) {
|
|
testpos.x = sinf(curangle) * 60 + pos->x;
|
|
testpos.y = pos->y;
|
|
testpos.z = cosf(curangle) * 60 + pos->z;
|
|
|
|
if (cd0002deac(pos, rooms, &testpos, testrooms, CDTYPE_BG)
|
|
&& cdTestVolume(&testpos, chrradius, testrooms, CDTYPE_ALL, 1, 200, -200.0f) != CDRESULT_COLLISION
|
|
&& (allowonscreen || chrIsPosOffScreen(&testpos, testrooms))) {
|
|
pos->x = testpos.x;
|
|
pos->y = testpos.y;
|
|
pos->z = testpos.z;
|
|
roomsCopy(testrooms, rooms);
|
|
return true;
|
|
}
|
|
|
|
curangle += 0.7852731347084f;
|
|
|
|
if (curangle >= M_BADTAU) {
|
|
curangle -= M_BADTAU;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* Attempts to spawn a chr at the given coordinates.
|
|
*
|
|
* In low memory conditions, the function will iterate all existing chrs in
|
|
* search of a corpse that can be reaped. If one is found then the reap will be
|
|
* triggered, but the function will not attempt to spawn the chr until the next
|
|
* time it's called.
|
|
*/
|
|
struct prop *chrSpawnAtCoord(s32 bodynum, s32 headnum, struct coord *pos, s16 *rooms, f32 angle, u8 *ailist, u32 spawnflags)
|
|
{
|
|
struct prop *prop;
|
|
struct coord pos2;
|
|
s16 rooms2[8];
|
|
s32 stack;
|
|
|
|
if (chrsGetNumFree() > 1) {
|
|
if (headnum < 0) {
|
|
headnum = bodyChooseHead(bodynum);
|
|
}
|
|
|
|
pos2.x = pos->x;
|
|
pos2.y = pos->y;
|
|
pos2.z = pos->z;
|
|
roomsCopy(rooms, rooms2);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (chrAdjustPosForSpawn(20, &pos2, rooms2, angle, (spawnflags & SPAWNFLAG_00000010) != 0, 0, 0))
|
|
#else
|
|
if (chrAdjustPosForSpawn(20, &pos2, rooms2, angle, (spawnflags & SPAWNFLAG_00000010) != 0, 0))
|
|
#endif
|
|
{
|
|
struct model *model = bodyAllocateModel(bodynum, headnum, spawnflags);
|
|
struct chrdata *chr;
|
|
|
|
if (model) {
|
|
prop = chrAllocate(model, &pos2, rooms2, angle, ailist);
|
|
|
|
if (prop) {
|
|
propActivateThisFrame(prop);
|
|
propEnable(prop);
|
|
|
|
chr = prop->chr;
|
|
chr->headnum = headnum;
|
|
chr->bodynum = bodynum;
|
|
chr->race = bodyGetRace(chr->bodynum);
|
|
chr->flags = 0;
|
|
chr->flags2 = 0;
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
chr->hidden2 |= CHRH2FLAG_SPAWNED;
|
|
#endif
|
|
|
|
if (spawnflags & SPAWNFLAG_NOBLOOD) {
|
|
chr->noblood = true;
|
|
}
|
|
|
|
return prop;
|
|
}
|
|
|
|
modelmgrFreeModel(model);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Low memory - find a corpse to reap
|
|
if (chrsGetNumFree() < 4) {
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
s32 stack2;
|
|
struct chrdata *replacechr;
|
|
s32 startindex;
|
|
s32 index;
|
|
#else
|
|
s32 startindex;
|
|
struct chrdata *replacechr;
|
|
s32 index;
|
|
#endif
|
|
|
|
replacechr = NULL;
|
|
startindex = random() % g_NumChrSlots;
|
|
index = startindex;
|
|
|
|
#if VERSION < VERSION_NTSC_1_0
|
|
if (startindex);
|
|
#endif
|
|
|
|
do {
|
|
if (g_ChrSlots[index].chrnum >= 0 && g_ChrSlots[index].model && g_ChrSlots[index].prop) {
|
|
if (g_ChrSlots[index].actiontype == ACT_DEAD
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
|| (g_ChrSlots[index].actiontype == ACT_DRUGGEDKO && (g_ChrSlots[index].chrflags & CHRCFLAG_KEEPCORPSEKO) == 0)
|
|
#endif
|
|
) {
|
|
// If we've found a chr that's ready to be reaped, great.
|
|
// Bail out of the loop.
|
|
if (g_ChrSlots[index].act_dead.invistimer60 >= TICKS(120)) {
|
|
replacechr = &g_ChrSlots[index];
|
|
break;
|
|
}
|
|
|
|
// Otherwise, this chr is dead/KO'ed and can be reaped as a
|
|
// last resort, so store them and keep looping in search of
|
|
// a better chr.
|
|
if (replacechr == NULL) {
|
|
replacechr = &g_ChrSlots[index];
|
|
}
|
|
}
|
|
}
|
|
|
|
index = (index + 1) % g_NumChrSlots;
|
|
} while (index != startindex);
|
|
|
|
if (replacechr) {
|
|
replacechr->act_dead.fadewheninvis = true;
|
|
replacechr->act_dead.fadenow = true;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
struct prop *chrSpawnAtPad(struct chrdata *basechr, s32 body, s32 head, s32 pad_id, u8 *ailist, u32 spawnflags)
|
|
{
|
|
s32 resolved_pad_id = chrResolvePadId(basechr, pad_id);
|
|
struct pad pad;
|
|
s16 room[2];
|
|
f32 fvalue;
|
|
padUnpack(resolved_pad_id, PADFIELD_POS | PADFIELD_LOOK | PADFIELD_ROOM, &pad);
|
|
fvalue = atan2f(pad.look.x, pad.look.z);
|
|
room[0] = pad.room;
|
|
room[1] = -1;
|
|
|
|
return chrSpawnAtCoord(body, head, &pad.pos, &room[0], fvalue, ailist, spawnflags);
|
|
}
|
|
|
|
struct prop *chrSpawnAtChr(struct chrdata *basechr, s32 body, s32 head, u32 chrnum, u8 *ailist, u32 spawnflags)
|
|
{
|
|
struct chrdata *chr = chrFindById(basechr, chrnum);
|
|
f32 fvalue;
|
|
|
|
if (1) {
|
|
fvalue = chrGetInverseTheta(chr);
|
|
}
|
|
|
|
return chrSpawnAtCoord(body, head, &chr->prop->pos, chr->prop->rooms, fvalue, ailist, spawnflags);
|
|
}
|
|
|
|
bool func0f04b658(struct chrdata *chr)
|
|
{
|
|
bool result = false;
|
|
struct prop *prop = chr->prop;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
|
|
if (chr->proppreset1 >= 0) {
|
|
chrSetPerimEnabled(chr, false);
|
|
propSetPerimEnabled(target, false);
|
|
|
|
if (!cd0002dc18(&prop->pos, prop->rooms, &target->pos, 0x33)) {
|
|
struct prop *thing = cdGetObstacle();
|
|
|
|
if (thing && thing->type == PROPTYPE_OBJ
|
|
&& chr->proppreset1 == (s16)(thing - g_Vars.props)) {
|
|
result = true;
|
|
}
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
propSetPerimEnabled(target, true);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void func0f04b740(void)
|
|
{
|
|
// empty
|
|
}
|
|
|
|
bool chrMoveToPos(struct chrdata *chr, struct coord *pos, s16 *rooms, f32 angle, bool allowonscreen)
|
|
{
|
|
struct coord pos2;
|
|
s16 rooms2[8];
|
|
bool result = false;
|
|
u32 nodetype;
|
|
union modelrwdata *rwdata;
|
|
struct player *player;
|
|
f32 ground;
|
|
|
|
pos2.x = pos->x;
|
|
pos2.y = pos->y;
|
|
pos2.z = pos->z;
|
|
|
|
roomsCopy(rooms, rooms2);
|
|
propSetPerimEnabled(chr->prop, false);
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
if (chrAdjustPosForSpawn(chr->radius, &pos2, rooms2, angle, (chr->hidden & CHRHFLAG_00100000) != 0, allowonscreen, (chr->hidden & CHRHFLAG_00000200) != 0))
|
|
#else
|
|
if (chrAdjustPosForSpawn(chr->radius, &pos2, rooms2, angle, (chr->hidden & CHRHFLAG_00100000) != 0, allowonscreen))
|
|
#endif
|
|
{
|
|
ground = cdFindGroundY(&pos2, chr->radius, rooms2, &chr->floorcol,
|
|
&chr->floortype, NULL, &chr->floorroom, NULL, NULL);
|
|
|
|
chr->ground = ground;
|
|
chr->manground = ground;
|
|
chr->sumground = ground * (PAL ? 8.4175090789795f : 9.999998f);
|
|
chr->prop->pos.x = pos2.x;
|
|
chr->prop->pos.y = pos2.y;
|
|
chr->prop->pos.z = pos2.z;
|
|
|
|
propDeregisterRooms(chr->prop);
|
|
roomsCopy(rooms2, chr->prop->rooms);
|
|
chr0f0220ac(chr);
|
|
modelSetRootPosition(chr->model, &pos2);
|
|
|
|
nodetype = chr->model->filedata->rootnode->type;
|
|
|
|
if ((nodetype & 0xff) == MODELNODETYPE_CHRINFO) {
|
|
rwdata = modelGetNodeRwData(chr->model, chr->model->filedata->rootnode);
|
|
rwdata->chrinfo.ground = ground;
|
|
}
|
|
|
|
chr->chrflags |= CHRCFLAG_00000001;
|
|
chrSetLookAngle(chr, angle);
|
|
|
|
if (chr->prop->type == PROPTYPE_PLAYER) {
|
|
player = g_Vars.players[playermgrGetPlayerNumByProp(chr->prop)];
|
|
player->vv_manground = ground;
|
|
player->vv_ground = ground;
|
|
player->vv_theta = ((M_BADTAU - angle) * 360.0f) / M_BADTAU;
|
|
player->vv_verta = 0;
|
|
player->unk1c64 = 1;
|
|
}
|
|
|
|
result = true;
|
|
}
|
|
|
|
propSetPerimEnabled(chr->prop, true);
|
|
|
|
return result;
|
|
}
|
|
|
|
bool chrCheckCoverOutOfSight(struct chrdata *chr, s32 covernum, bool soft)
|
|
{
|
|
struct cover cover;
|
|
struct prop *target;
|
|
bool targetcanseecover;
|
|
|
|
// @bug: Should be >= coverGetCount()
|
|
if (covernum < 0 || covernum > coverGetCount() || !coverUnpack(covernum, &cover)) {
|
|
return false;
|
|
}
|
|
|
|
target = chrGetTargetProp(chr);
|
|
|
|
if (!target) {
|
|
return false;
|
|
}
|
|
|
|
if (soft) {
|
|
targetcanseecover = cd0002db98(&target->pos, target->rooms, cover.pos, CDTYPE_OBJS | CDTYPE_DOORS | CDTYPE_BG, 8);
|
|
} else {
|
|
targetcanseecover = cd0002f450(&target->pos, target->rooms, cover.pos, 50, 35);
|
|
}
|
|
|
|
if (!targetcanseecover != false) {
|
|
// Target can't see cover
|
|
coverSetFlag0001(covernum, true);
|
|
return true;
|
|
}
|
|
|
|
coverSetFlag0001(covernum, false);
|
|
return false;
|
|
}
|
|
|
|
s32 chrAssignCoverByCriteria(struct chrdata *chr, u16 criteria, s32 refdist)
|
|
{
|
|
s16 rooms[8];
|
|
struct cover cover;
|
|
struct covercandidate tmp;
|
|
s32 oldcover;
|
|
s32 i;
|
|
struct prop *roomprop;
|
|
s32 numcovers = coverGetCount();
|
|
s32 numcandidates = 0;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
bool userandomdist = false;
|
|
bool changed;
|
|
f32 sqdist;
|
|
f32 y = chr->prop->pos.y + 170;
|
|
s32 currefdist = refdist;
|
|
struct prop *gotoprop;
|
|
|
|
if (criteria & COVERCRITERIA_DISTTOFETCHPROP) {
|
|
if (!chr->aibot || !chr->aibot->gotoprop) {
|
|
return -1;
|
|
}
|
|
|
|
gotoprop = chr->aibot->gotoprop;
|
|
}
|
|
|
|
if (chr == NULL) {
|
|
return 0;
|
|
}
|
|
|
|
oldcover = chr->cover;
|
|
refdist *= refdist;
|
|
|
|
// Iterate all cover, filter them by criteria and store them in g_CoverCandidates
|
|
for (i = 0; i < numcovers; i++) {
|
|
if (coverUnpack(i, &cover)
|
|
&& !coverIsSpecial(&cover)
|
|
&& ((criteria & COVERCRITERIA_2000) == 0 || (cover.flags & COVERFLAG_OMNIDIRECTIONAL))
|
|
&& ((criteria & COVERCRITERIA_1000) || (cover.flags & COVERFLAG_AIMDIFFROOM) == 0 || !arrayIntersects(cover.rooms, target->rooms))) {
|
|
userandomdist = false;
|
|
|
|
if ((criteria & COVERCRITERIA_0001) && (criteria & COVERCRITERIA_FURTHEREST)) {
|
|
userandomdist = true;
|
|
criteria &= ~(COVERCRITERIA_0001 | COVERCRITERIA_FURTHEREST);
|
|
}
|
|
|
|
if (((criteria & COVERCRITERIA_FORCENEWCOVER) == 0 || i != oldcover)
|
|
&& ((criteria & COVERCRITERIA_2000) || !(coverIsInUse(i) || cover.pos->y > y))) {
|
|
if (criteria & COVERCRITERIA_ROOMSFROMME) {
|
|
roomprop = chr->prop;
|
|
} else if (criteria & COVERCRITERIA_ROOMSFROMTARGET) {
|
|
roomprop = target;
|
|
} else if (criteria & COVERCRITERIA_DISTTOTARGET) {
|
|
roomprop = target;
|
|
} else {
|
|
roomprop = chr->prop;
|
|
}
|
|
|
|
rooms[0] = roomprop->rooms[0];
|
|
rooms[1] = -1;
|
|
|
|
if (criteria & COVERCRITERIA_ALLOWNEIGHBOURINGROOMS) {
|
|
roomGetNeighbours(roomprop->rooms[0], &rooms[1], 6);
|
|
} else if (criteria & COVERCRITERIA_ONLYNEIGHBOURINGROOMS) {
|
|
roomGetNeighbours(roomprop->rooms[0], &rooms[0], 7);
|
|
}
|
|
|
|
if (((criteria & COVERCRITERIA_0040) == 0 || !arrayIntersects(cover.rooms, rooms))
|
|
&& ((criteria & COVERCRITERIA_0020) == 0 || arrayIntersects(cover.rooms, rooms))
|
|
&& (rooms[1] == -1
|
|
|| chr->oldrooms[0] == -1
|
|
|| (criteria & COVERCRITERIA_0200) == 0
|
|
|| !arrayIntersects(cover.rooms, chr->oldrooms))) {
|
|
if (criteria & COVERCRITERIA_DISTTOME) {
|
|
sqdist = chrGetSquaredDistanceToCoord(chr, cover.pos);
|
|
} else if (criteria & COVERCRITERIA_DISTTOTARGET) {
|
|
sqdist = coordGetSquaredDistanceToCoord(&target->pos, cover.pos);
|
|
} else if (criteria & COVERCRITERIA_DISTTOFETCHPROP) {
|
|
sqdist = coordGetSquaredDistanceToCoord(&gotoprop->pos, cover.pos);
|
|
} else if (userandomdist) {
|
|
sqdist = random() % 0xf000;
|
|
} else {
|
|
sqdist = 0;
|
|
currefdist = 0;
|
|
}
|
|
|
|
if (!currefdist
|
|
|| (currefdist < 0 && sqdist > refdist)
|
|
|| (currefdist > 0 && sqdist < refdist)) {
|
|
g_CoverCandidates[numcandidates].sqdist = sqdist;
|
|
g_CoverCandidates[numcandidates].covernum = i;
|
|
numcandidates++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Sort candidates by distance ascending, or descending if using COVERCRITERIA_FURTHEREST
|
|
if (numcandidates >= 2) {
|
|
do {
|
|
changed = false;
|
|
|
|
for (i = 0; i < numcandidates - 1; i++) {
|
|
if ((((criteria & COVERCRITERIA_0001) || (criteria & COVERCRITERIA_DISTTOFETCHPROP) || userandomdist) && (g_CoverCandidates[i].sqdist > g_CoverCandidates[i + 1].sqdist))
|
|
|| ((criteria & COVERCRITERIA_FURTHEREST) && g_CoverCandidates[i].sqdist < g_CoverCandidates[i + 1].sqdist)) {
|
|
changed = true;
|
|
|
|
tmp = g_CoverCandidates[i];
|
|
g_CoverCandidates[i] = g_CoverCandidates[i + 1];
|
|
g_CoverCandidates[i + 1] = tmp;
|
|
}
|
|
}
|
|
} while (changed);
|
|
}
|
|
|
|
// Assign the first out of sight cover
|
|
for (i = 0; i < numcandidates; i++) {
|
|
if (1 && chrCheckCoverOutOfSight(chr, g_CoverCandidates[i].covernum, criteria & COVERCRITERIA_ALLOWSOFT)) {
|
|
chr->cover = g_CoverCandidates[i].covernum;
|
|
|
|
if (oldcover != -1) {
|
|
coverSetInUse(oldcover, false);
|
|
}
|
|
|
|
coverSetInUse(chr->cover, true);
|
|
|
|
return g_CoverCandidates[i].covernum;
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Find cover in the opposite direction (?) of the chr's runfrompos and assign
|
|
* it to the chr. The distance from the runfrompos to the cover must be between
|
|
* mindist and maxdist along the X/Z plane. The chr will not choose cover more
|
|
* than 170cm higher than their current elevation, but strangely there is no
|
|
* lower Y limit.
|
|
*
|
|
* Testing with this function logic results in the following, where:
|
|
* R = run from pos
|
|
* C = chr's pos
|
|
* A = available cover
|
|
* . = unavailable cover
|
|
*
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A R A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . .
|
|
* A A A A A A A A A A A A A A . . . . . A
|
|
* A A A A A A A A A A A A A A . . . A A A
|
|
* A A A A A A A A A A A A A A . A A A A A
|
|
* A A A A A A A A A A A A A C A A A A A A
|
|
* . . . . . . . . . . . A A A A A A A A A
|
|
* . . . . . . . . . A A A A A A A A A A A
|
|
*
|
|
* The block of available cover around the runfrompos might be a bug, but if
|
|
* this function is called with mindist = chr - runfrompos or higher then it
|
|
* will work as expected.
|
|
*
|
|
* Preference is given to cover which is the "most opposite", meaning ones
|
|
* which are directly behind the chr from the perspective of runfrompos.
|
|
*/
|
|
s32 chrAssignCoverAwayFromDanger(struct chrdata *chr, s32 mindist, s32 maxdist)
|
|
{
|
|
s32 i;
|
|
f32 vecfromdanger[2];
|
|
f32 vectocover[2];
|
|
f32 y;
|
|
f32 ymax;
|
|
f32 bestsqdist;
|
|
f32 sqdist;
|
|
s32 numcovers;
|
|
s32 prevcover;
|
|
s32 newcover;
|
|
f32 coversqdistfrompos;
|
|
struct cover cover;
|
|
|
|
ymax = chr->prop->pos.y + 170;
|
|
y = 0;
|
|
bestsqdist = 0;
|
|
newcover = -1;
|
|
|
|
numcovers = coverGetCount();
|
|
prevcover = chr->cover;
|
|
|
|
mindist *= mindist;
|
|
maxdist *= maxdist;
|
|
|
|
if (mindist);
|
|
if (maxdist);
|
|
|
|
vecfromdanger[0] = chr->prop->pos.x - chr->runfrompos.x;
|
|
vecfromdanger[1] = chr->prop->pos.z - chr->runfrompos.z;
|
|
|
|
guNormalize(&vecfromdanger[0], &y, &vecfromdanger[1]);
|
|
|
|
for (i = 0; i < numcovers; i++) {
|
|
if (coverUnpack(i, &cover) && !coverIsInUse(i) && !(cover.pos->y > ymax) && !coverIsSpecial(&cover)) {
|
|
coversqdistfrompos = coordGetSquaredDistanceToCoord(&chr->runfrompos, cover.pos);
|
|
|
|
if (!(coversqdistfrompos < mindist) && !(coversqdistfrompos > maxdist)) {
|
|
vectocover[0] = cover.pos->x - chr->prop->pos.x;
|
|
vectocover[1] = cover.pos->z - chr->prop->pos.z;
|
|
|
|
guNormalize(&vectocover[0], &y, &vectocover[1]);
|
|
|
|
sqdist = vecfromdanger[0] * vectocover[0] + vecfromdanger[1] * vectocover[1];
|
|
|
|
if (!(sqdist < 0) && sqdist > bestsqdist) {
|
|
bestsqdist = sqdist;
|
|
newcover = i;
|
|
if (1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (numcovers);
|
|
}
|
|
|
|
chr->cover = newcover;
|
|
|
|
if (newcover != -1) {
|
|
if (prevcover != -1) {
|
|
coverSetInUse(prevcover, false);
|
|
}
|
|
|
|
coverSetInUse(chr->cover, true);
|
|
}
|
|
|
|
return newcover;
|
|
}
|
|
|
|
s16 chrGoToCover(struct chrdata *chr, u8 speed)
|
|
{
|
|
struct cover cover;
|
|
|
|
if (!chr) {
|
|
return 0;
|
|
}
|
|
|
|
if (chrIsReadyForOrders(chr) && chr->cover != -1 && coverUnpack(chr->cover, &cover)) {
|
|
chrGoToRoomPos(chr, cover.pos, &cover.rooms[0], speed);
|
|
return chr->cover;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
bool chrRunFromPos(struct chrdata *chr, u32 speed, f32 rundist, struct coord *frompos)
|
|
{
|
|
f32 curdistfrompos;
|
|
struct coord delta;
|
|
s16 rooms[8];
|
|
|
|
if (chrIsReadyForOrders(chr)) {
|
|
delta.x = chr->prop->pos.x - frompos->x;
|
|
delta.y = chr->prop->pos.y;
|
|
delta.z = chr->prop->pos.z - frompos->z;
|
|
|
|
// @bug: This check should be &&. The runfrompos will fail if the
|
|
// frompos is on the same X or Z axis as the chr, which is unlikely
|
|
// because it's a floating point number.
|
|
if (delta.f[0] == 0.0f || delta.f[2] == 0.0f) {
|
|
return false;
|
|
}
|
|
|
|
curdistfrompos = sqrtf(delta.f[0] * delta.f[0] + delta.f[2] * delta.f[2]);
|
|
delta.x *= rundist / curdistfrompos;
|
|
delta.z *= rundist / curdistfrompos;
|
|
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
if (cdTestAToB4(&chr->prop->pos, chr->prop->rooms, &delta, CDTYPE_ALL, 4) == CDRESULT_COLLISION) {
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cdGetPos(&delta, 18592, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_FINAL
|
|
cdGetPos(&delta, 18555, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_BETA
|
|
cdGetPos(&delta, 18550, "chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cdGetPos(&delta, 18547, "chraction.c");
|
|
#else
|
|
cdGetPos(&delta, 18277, "chraction.c");
|
|
#endif
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
|
|
func0f065e74(&chr->prop->pos, chr->prop->rooms, &delta, rooms);
|
|
|
|
return chrGoToRoomPos(chr, &delta, rooms, speed);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void chrAddTargetToBdlist(struct chrdata *chr)
|
|
{
|
|
if (chr->prop) {
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
s32 i;
|
|
|
|
if (target) {
|
|
for (i = 0; i < g_Vars.lvupdate240_60; i++) {
|
|
chr->bdlist[chr->bdstart] = target->pos.x - chr->prop->pos.x;
|
|
chr->bdstart++;
|
|
chr->bdstart %= 60;
|
|
|
|
chr->bdlist[chr->bdstart] = target->pos.z - chr->prop->pos.z;
|
|
chr->bdstart++;
|
|
chr->bdstart %= 60;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
s32 chrGetDistanceLostToTargetInLastSecond(struct chrdata *chr)
|
|
{
|
|
s32 *bdlist = &chr->bdlist[0];
|
|
s32 index = chr->bdstart;
|
|
u32 stack[2];
|
|
|
|
s32 x1 = bdlist[(index + 1) % 60];
|
|
s32 z1 = bdlist[index];
|
|
s32 olddist = sqrtf(x1 * x1 + z1 * z1);
|
|
|
|
s32 x2 = bdlist[(index + 59) % 60];
|
|
s32 z2 = bdlist[(index + 58) % 60];
|
|
s32 curdist = sqrtf(x2 * x2 + z2 * z2);
|
|
|
|
return curdist - olddist;
|
|
}
|
|
|
|
bool chrIsTargetNearlyInSight(struct chrdata *chr, u32 distance)
|
|
{
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
|
|
return cd0002f450(&chr->prop->pos, chr->prop->rooms, &target->pos, distance, 32);
|
|
}
|
|
|
|
bool chrIsNearlyInTargetsSight(struct chrdata *chr, u32 distance)
|
|
{
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
|
|
return cd0002f450(&target->pos, target->rooms, &chr->prop->pos, distance, 32);
|
|
}
|
|
|
|
f32 func0f04c784(struct chrdata *chr)
|
|
{
|
|
f32 targetfacingangle = 0;
|
|
u32 stack;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 angletotarget;
|
|
f32 result;
|
|
|
|
if (target->type == PROPTYPE_CHR) {
|
|
targetfacingangle = chrGetInverseTheta(target->chr);
|
|
} else if (target->type == PROPTYPE_PLAYER) {
|
|
s32 playernum = playermgrGetPlayerNumByProp(target);
|
|
targetfacingangle = g_Vars.players[playernum]->vv_theta;
|
|
}
|
|
|
|
angletotarget = atan2f(target->pos.z - chr->prop->pos.z, target->pos.x - chr->prop->pos.x);
|
|
result = (angletotarget * 360 / M_BADTAU - targetfacingangle) + 90;
|
|
|
|
if (result > 180) {
|
|
result -= 360;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
bool chr0f04c874(struct chrdata *chr, u32 angle360, struct coord *pos, u8 arg3, u8 arg4)
|
|
{
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 sqdist = 0;
|
|
f32 f24 = func0f04c784(chr);
|
|
f32 cosine;
|
|
f32 sine;
|
|
struct coord chrpos;
|
|
f32 xdiff;
|
|
f32 ydiff;
|
|
f32 zdiff;
|
|
f32 scale;
|
|
bool again;
|
|
struct coord saved;
|
|
s32 result;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
|
|
chrpos.x = chr->prop->pos.x;
|
|
chrpos.y = chr->prop->pos.y;
|
|
chrpos.z = chr->prop->pos.z;
|
|
|
|
do {
|
|
f32 angle360f = angle360;
|
|
|
|
if (angle360f > 180) {
|
|
angle360f -= 360;
|
|
}
|
|
|
|
angle360f -= f24;
|
|
angle360f *= 0.017450513318181f;
|
|
|
|
cosine = cosf(angle360f);
|
|
sine = sinf(angle360f);
|
|
xdiff = chrpos.x - target->pos.x;
|
|
zdiff = chrpos.z - target->pos.z;
|
|
|
|
pos->x = target->pos.x + (xdiff * cosine - zdiff * sine);
|
|
pos->y = chrpos.y;
|
|
pos->z = target->pos.z + (xdiff * sine + zdiff * cosine);
|
|
|
|
chrGetBbox(chr->prop, &radius, &ymax, &ymin);
|
|
|
|
result = cd0002d7c0(&chrpos, chr->prop->rooms, pos,
|
|
CDTYPE_BG | CDTYPE_OBJS | CDTYPE_DOORS, 1,
|
|
ymax - chrpos.f[1],
|
|
ymin - chrpos.f[1]);
|
|
|
|
if (result == CDRESULT_COLLISION) {
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
f32 tmp;
|
|
|
|
#if VERSION >= VERSION_JPN_FINAL
|
|
cdGetPos(pos, 18731, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_FINAL
|
|
cdGetPos(pos, 18694, "chr/chraction.c");
|
|
#elif VERSION >= VERSION_PAL_BETA
|
|
cdGetPos(pos, 18689, "chraction.c");
|
|
#elif VERSION >= VERSION_NTSC_1_0
|
|
cdGetPos(pos, 18686, "chraction.c");
|
|
#else
|
|
cdGetPos(pos, 18416, "chraction.c");
|
|
#endif
|
|
|
|
xdiff = pos->x - chrpos.x;
|
|
zdiff = pos->z - chrpos.z;
|
|
tmp = sqrtf(xdiff * xdiff + zdiff * zdiff);
|
|
scale = (tmp - 50.0f) / tmp;
|
|
|
|
if (scale < 0) {
|
|
pos->x = chrpos.x;
|
|
pos->y = chrpos.y;
|
|
pos->z = chrpos.z;
|
|
} else {
|
|
xdiff *= scale;
|
|
zdiff *= scale;
|
|
|
|
pos->x = chrpos.x + xdiff;
|
|
pos->y = chrpos.y;
|
|
pos->z = chrpos.z + zdiff;
|
|
}
|
|
}
|
|
|
|
if (arg3) {
|
|
xdiff = chrpos.x - pos->x;
|
|
ydiff = chrpos.y - pos->y;
|
|
zdiff = chrpos.z - pos->z;
|
|
|
|
sqdist = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
|
|
|
|
saved.x = pos->x;
|
|
saved.y = pos->y;
|
|
saved.z = pos->z;
|
|
|
|
angle360 = 360 - angle360;
|
|
again = true;
|
|
arg3 = 0;
|
|
} else {
|
|
again = false;
|
|
}
|
|
} while (again);
|
|
|
|
if (sqdist != 0) {
|
|
f32 sqdist2;
|
|
xdiff = chrpos.x - pos->x;
|
|
ydiff = chrpos.y - pos->y;
|
|
zdiff = chrpos.z - pos->z;
|
|
|
|
sqdist2 = xdiff * xdiff + ydiff * ydiff + zdiff * zdiff;
|
|
|
|
if (sqdist2 < sqdist) {
|
|
pos->x = saved.f[0];
|
|
pos->y = saved.f[1];
|
|
pos->z = saved.f[2];
|
|
}
|
|
}
|
|
|
|
chrGoToPos(chr, pos, arg4);
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Chrs are assigned to teams, and they can be assigned to more than one.
|
|
* The team assignments determine if a chr considers another chr to be friendly
|
|
* or not.
|
|
*
|
|
* The chr->team value is a bitmask of which teams they belong to. There are 8
|
|
* teams total.
|
|
*
|
|
* The team list is an array of 264 shorts. The first 7 are indexes into
|
|
* the same list which mark the start of each team. Team 0 does not have
|
|
* an entry in this list because it always starts at offset 7.
|
|
*
|
|
* Elements 7 onwards are chrnums. Each team is terminated with -2.
|
|
*/
|
|
void rebuildTeams(void)
|
|
{
|
|
s32 numchrs = chrsGetNumSlots();
|
|
s16 index = 7;
|
|
s32 team;
|
|
s32 i;
|
|
struct chrdata *chr;
|
|
u8 teammasks[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
|
|
|
|
for (team = 0; team < 8; team++) {
|
|
if (team != 0) {
|
|
g_TeamList[team - 1] = index;
|
|
}
|
|
|
|
for (i = 0; i < numchrs; i++) {
|
|
chr = &g_ChrSlots[i];
|
|
|
|
if (chr->chrnum >= 0 && (chr->team & teammasks[team])) {
|
|
g_TeamList[index] = chr->chrnum;
|
|
index++;
|
|
}
|
|
}
|
|
|
|
g_TeamList[index] = -2;
|
|
index++;
|
|
|
|
if (index >= 264) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Chrs are partitioned into squadrons for AI scripting purposes, where their
|
|
* squadron number is in the range 0-15.
|
|
*
|
|
* The squadron list is an array of 272 shorts. The first 15 are indexes into
|
|
* the same list which mark the start of each squadron. Squadron 0 does not have
|
|
* an entry in this list because it always starts at offset 15.
|
|
*
|
|
* Elements 15 onwards are chrnums. Each squadron is terminated with -2.
|
|
*/
|
|
void rebuildSquadrons(void)
|
|
{
|
|
s32 numchrs = chrsGetNumSlots();
|
|
s16 index = 15;
|
|
s32 squadron;
|
|
s32 i;
|
|
|
|
for (squadron = 0; squadron < 16; squadron++) {
|
|
if (squadron != 0) {
|
|
g_SquadronList[squadron - 1] = index;
|
|
}
|
|
|
|
for (i = 0; i < numchrs; i++) {
|
|
struct chrdata *chr = &g_ChrSlots[i];
|
|
|
|
if (chr->chrnum >= 0 && chr->squadron == squadron) {
|
|
if (chr->prop == NULL || chr->prop->type != PROPTYPE_PLAYER) {
|
|
g_SquadronList[index] = chr->chrnum;
|
|
index++;
|
|
}
|
|
}
|
|
}
|
|
|
|
g_SquadronList[index] = -2;
|
|
index++;
|
|
|
|
if (index >= 272) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
s16 *teamGetChrIds(s32 team_id)
|
|
{
|
|
s32 i;
|
|
u8 lookup[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
|
|
|
|
for (i = 0; i != MAX_TEAMS; i++) {
|
|
if (lookup[i] == team_id) {
|
|
team_id = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (team_id < 0 || team_id >= MAX_TEAMS) {
|
|
return NULL;
|
|
}
|
|
|
|
if (team_id != 0) {
|
|
return &g_TeamList[g_TeamList[team_id - 1]];
|
|
}
|
|
|
|
return &g_TeamList[MAX_TEAMS - 1];
|
|
}
|
|
|
|
s16 *squadronGetChrIds(s32 squadron_id)
|
|
{
|
|
if (squadron_id < 0 || squadron_id >= MAX_SQUADRONS) {
|
|
return NULL;
|
|
}
|
|
|
|
if (squadron_id != 0) {
|
|
return &g_SquadronList[g_SquadronList[squadron_id - 1]];
|
|
}
|
|
|
|
return &g_SquadronList[MAX_SQUADRONS - 1];
|
|
}
|
|
|
|
void audioMarkAsRecentlyPlayed(s16 audioid)
|
|
{
|
|
g_RecentQuipsPlayed[g_RecentQuipsIndex++] = audioid;
|
|
|
|
if (g_RecentQuipsIndex > 4) {
|
|
g_RecentQuipsIndex = 0;
|
|
}
|
|
}
|
|
|
|
bool audioWasNotPlayedRecently(s16 audioid)
|
|
{
|
|
u8 i;
|
|
|
|
for (i = 0; i < 5; i++) {
|
|
if (g_RecentQuipsPlayed[i] == audioid) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#if VERSION >= VERSION_NTSC_1_0
|
|
Gfx *chrsRenderChrStats(Gfx *gdl, s16 *rooms)
|
|
{
|
|
return gdl;
|
|
}
|
|
#else
|
|
Gfx *chrsRenderChrStats(Gfx *gdl, s16 *rooms)
|
|
{
|
|
s32 x;
|
|
s32 y;
|
|
s32 textwidth = 0;
|
|
s32 textheight = 0;
|
|
s32 x2;
|
|
s32 y2;
|
|
struct coord sp20c;
|
|
f32 sp204[2];
|
|
char fullbuffer[256];
|
|
char aibotbuffer[120];
|
|
u8 aibot = 0;
|
|
s32 i;
|
|
s32 numchrs = chrsGetNumSlots();
|
|
|
|
gdl = text0f153628(gdl);
|
|
|
|
for (i = 0; i < numchrs; i++) {
|
|
struct chrdata *chr = &g_ChrSlots[i];
|
|
|
|
if (chr && chr->prop && arrayIntersects(chr->prop->rooms, rooms)) {
|
|
sp20c.x = chr->prop->pos.x;
|
|
sp20c.y = chr->ground + chr->height - 30;
|
|
sp20c.z = chr->prop->pos.z;
|
|
|
|
mtx4TransformVecInPlace(g_Vars.currentplayer->worldtoscreenmtx, &sp20c);
|
|
|
|
if (sp20c.z < -100 && sp20c.z > -1000) {
|
|
cam0f0b4eb8(&sp20c, sp204, g_Vars.currentplayer->c_perspfovy, g_Vars.currentplayer->c_perspaspect);
|
|
x = sp204[0];
|
|
y = sp204[1];
|
|
|
|
if (chr->aibot) {
|
|
if (g_MpSetup.options & MPOPTION_TEAMSENABLED) {
|
|
aibot = 1;
|
|
sprintf(aibotbuffer, "\nTEAM %d: Cmd: %s", chr->team, botGetCommandName(chr->aibot->command));
|
|
}
|
|
}
|
|
|
|
sprintf(fullbuffer, "CHR[%d]\n%s\n%s\n%s%s", chr->chrnum,
|
|
chr->myaction >= ARRAYCOUNT(g_ChrMyActionNames) ? "myaction?" : g_ChrMyActionNames[chr->myaction],
|
|
chr->actiontype >= ARRAYCOUNT(g_ChrActionNames) || chr->actiontype < 0 ? "ACT_?" : g_ChrActionNames2[chr->actiontype],
|
|
chr->actiontype == ACT_GOPOS || chr->actiontype == ACT_PATROL ? g_ChrLiftActionNames[chr->liftaction] : g_ChrLiftActionNames[0],
|
|
aibot ? aibotbuffer : "");
|
|
|
|
textMeasure(&textheight, &textwidth, fullbuffer, g_CharsHandelGothicXs, g_FontHandelGothicXs, 0);
|
|
|
|
x2 = x + textwidth;
|
|
y2 = y + textheight;
|
|
|
|
gdl = text0f153858(gdl, &x, &y, &x2, &y2);
|
|
gdl = textRender(gdl, &x, &y, fullbuffer,
|
|
g_CharsHandelGothicXs, g_FontHandelGothicXs,
|
|
0xff8800aa, 0x00000088, viGetWidth(), viGetHeight(), 0, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
gdl = text0f153780(gdl);
|
|
|
|
return gdl;
|
|
}
|
|
#endif
|
|
|
|
void chrToggleModelPart(struct chrdata *chr, s32 partnum)
|
|
{
|
|
if (chr && chr->model && chr->model->filedata) {
|
|
struct modelnode *node = modelGetPart(chr->model->filedata, partnum);
|
|
union modelrwdata *rwdata = NULL;
|
|
|
|
if (node) {
|
|
rwdata = modelGetNodeRwData(chr->model, node);
|
|
}
|
|
|
|
if (rwdata) {
|
|
bool visible = rwdata->toggle.visible;
|
|
rwdata->toggle.visible = !visible;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Make the chr do an avoiding animation, as if they are avoiding some object
|
|
* being thrown at them.
|
|
*
|
|
* The chosen animation is based on the chr's relative angle to their target.
|
|
*
|
|
* Collision checks are done, and no animation will be done if there would be a
|
|
* collision.
|
|
*/
|
|
void chrAvoid(struct chrdata *chr)
|
|
{
|
|
// The first 4 items here are animation numbers
|
|
// and the second 4 are their corresponding end frames.
|
|
s32 anims[] = {
|
|
ANIM_0064, ANIM_0065, ANIM_0066, ANIM_0067,
|
|
48, 58, 35, 35
|
|
};
|
|
|
|
s32 animindex;
|
|
struct prop *target = chrGetTargetProp(chr);
|
|
f32 relangle = chrGetAngleToPos(chr, &target->pos) / M_BADTAU * 360;
|
|
u32 chranimflags = 0;
|
|
f32 ymax;
|
|
f32 ymin;
|
|
f32 radius;
|
|
s32 cdresult = CDRESULT_NOCOLLISION;
|
|
f32 xdiff;
|
|
f32 zdiff;
|
|
f32 halfchrradius;
|
|
f32 chrangle = model0001ae44(chr->model);
|
|
s16 dstrooms[8];
|
|
struct coord dstpos;
|
|
|
|
// @bug: This shouldn't be here, and the perim is not enabled again
|
|
// if the chr is not ready for orders.
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
if (chrIsReadyForOrders(chr)) {
|
|
chrSetPerimEnabled(chr, false);
|
|
|
|
if (relangle > 45 && relangle <= 135) {
|
|
animindex = 3;
|
|
chranimflags = CHRANIMFLAG_FLIP;
|
|
chrangle += M_PI;
|
|
} else if (relangle > 135 && relangle < 225) {
|
|
animindex = 2;
|
|
|
|
if ((random() % 255) >= 2) {
|
|
cdresult = CDRESULT_COLLISION;
|
|
chr->chrflags &= ~CHRCFLAG_10000000;
|
|
}
|
|
} else if (relangle > 225 && relangle < 315) {
|
|
animindex = 3;
|
|
chrangle += M_PI;
|
|
} else {
|
|
animindex = (random() % 100 < 50) ? 0 : 1;
|
|
|
|
if (animindex == 0) {
|
|
chrangle -= 1.5707963705063f;
|
|
} else {
|
|
chrangle += 1.5707963705063f;
|
|
}
|
|
}
|
|
|
|
if (cdresult != CDRESULT_COLLISION) {
|
|
dstpos.x = chr->prop->pos.x - sinf(chrangle) * 100;
|
|
dstpos.y = chr->prop->pos.y;
|
|
dstpos.z = chr->prop->pos.z + cosf(chrangle) * 100;
|
|
|
|
chrGetBbox(chr->prop, &radius, &ymax, &ymin);
|
|
|
|
halfchrradius = radius * 0.5f;
|
|
|
|
func0f065e74(&chr->prop->pos, chr->prop->rooms, &dstpos, dstrooms);
|
|
chr0f021fa8(chr, &dstpos, dstrooms);
|
|
|
|
xdiff = dstpos.x - chr->prop->pos.x;
|
|
zdiff = dstpos.z - chr->prop->pos.z;
|
|
|
|
if (xdiff > halfchrradius || zdiff > halfchrradius || xdiff < -halfchrradius || zdiff < -halfchrradius) {
|
|
cdresult = cd0002d8b8(&chr->prop->pos, chr->prop->rooms, &dstpos, dstrooms, CDTYPE_ALL, true, ymax - chr->prop->pos.y, ymin - chr->prop->pos.y);
|
|
}
|
|
|
|
if (cdresult == CDRESULT_ERROR) {
|
|
chr->chrflags &= ~CHRCFLAG_10000000;
|
|
} else if (cdresult == CDRESULT_NOCOLLISION) {
|
|
chrStartAnim(chr, anims[animindex], 0, anims[4 + animindex], chranimflags, 2, 0.6f);
|
|
} else {
|
|
chr->chrflags &= ~CHRCFLAG_10000000;
|
|
}
|
|
}
|
|
|
|
chrSetPerimEnabled(chr, true);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Checks if the chr is doing an avoiding animation.
|
|
*
|
|
* These animations are possibly unused. In each one, the chr jumps backwards or
|
|
* to the side as if avoiding something, then looks at whatever it was that just
|
|
* went past.
|
|
*/
|
|
bool chrIsAvoiding(struct chrdata *chr)
|
|
{
|
|
s32 anim = modelGetAnimNum(chr->model);
|
|
chr->chrflags &= ~CHRCFLAG_10000000;
|
|
|
|
// Possible @bug or just sloppy code: The flag check below can never pass
|
|
// because that flag was just turned off above.
|
|
if (anim == ANIM_0064
|
|
|| anim == ANIM_0065
|
|
|| anim == ANIM_0066
|
|
|| anim == ANIM_0067
|
|
|| (chr->chrflags & CHRCFLAG_10000000)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void chrDrCarollEmitSparks(struct chrdata *chr)
|
|
{
|
|
if (chr && chr->prop) {
|
|
propsnd0f0939f8(0, chr->prop, SFX_SHIELD_DAMAGE, -1, -1, 0, 0, 0, 0, -1, 0, -1, -1, -1, -1);
|
|
sparksCreate(chr->prop->rooms[0], chr->prop, &chr->prop->pos, NULL, 0, SPARKTYPE_ELECTRICAL);
|
|
}
|
|
}
|