Newer
Older
/***********************************************************
Copyright © Vitaliy Buturlin, Evgeny Danilovich, 2017, 2018
See the license in LICENSE
***********************************************************/
#include <decals/sxdecals.h>
/*! \skydocent base_tool
Базовый класс для инструмента (в т.ч оружие). То, что игрок может взять в руки и использовать
*/
DEFINE_FIELD_FLOAT(m_fReloadTime, PDFF_NOEDIT | PDFF_NOEXPORT, "reload_time", "", EDITOR_NONE)
DEFINE_FIELD_FLOAT(m_fZoomTime, PDFF_NOEDIT | PDFF_NOEXPORT, "zoom_time", "", EDITOR_NONE)
DEFINE_FIELD_VECTOR(m_vSlotPos, PDFF_NOEDIT | PDFF_NOEXPORT, "slot_offset", "", EDITOR_NONE)
DEFINE_FIELD_ANGLES(m_qSlotRot, PDFF_NOEDIT | PDFF_NOEXPORT, "slot_rotation", "", EDITOR_NONE)
DEFINE_FIELD_VECTOR(m_vSlotPosAim, PDFF_NOEDIT | PDFF_NOEXPORT, "slot_offset_aim", "", EDITOR_NONE)
DEFINE_FIELD_ANGLES(m_qSlotRotAim, PDFF_NOEDIT | PDFF_NOEXPORT, "slot_rotation_aim", "", EDITOR_NONE)
//! Смещение визуальной модели при приближении к стене
DEFINE_FIELD_VECTOR(m_vSlotPosClose, PDFF_NOEDIT | PDFF_NOEXPORT, "slot_offset_close", "", EDITOR_NONE)
//! Вращение визуальной модели при приближении к стене
DEFINE_FIELD_ANGLES(m_qSlotRotClose, PDFF_NOEDIT | PDFF_NOEXPORT, "slot_rotation_close", "", EDITOR_NONE)
//! Расстояние от центра модели до кончика ствола
DEFINE_FIELD_FLOAT(m_fCenterLength, PDFF_NOEDIT | PDFF_NOEXPORT, "center_length", "", EDITOR_NONE)
DEFINE_FIELD_INT(m_iZoomable, PDFF_NOEDIT | PDFF_NOEXPORT, "zoomable", "", EDITOR_NONE)
DEFINE_FIELD_STRING(m_szPrimaryActionSound, PDFF_NOEDIT | PDFF_NOEXPORT, "action1_sound", "", EDITOR_NONE)
DEFINE_FIELD_STRING(m_szSecondaryActionSound, PDFF_NOEDIT | PDFF_NOEXPORT, "action2_sound", "", EDITOR_NONE)
DEFINE_FIELD_STRING(m_szPrimaryActionMuzzleflash, PDFF_NOEDIT | PDFF_NOEXPORT, "action1_muzzle", "", EDITOR_NONE)
DEFINE_FIELD_STRING(m_szSecondaryActionMuzzleflash, PDFF_NOEDIT | PDFF_NOEXPORT, "action2_muzzle", "", EDITOR_NONE)
DEFINE_FIELD_FLOAT(m_fMaxDistance, PDFF_NOEDIT | PDFF_NOEXPORT, "max_distance", "", EDITOR_NONE)
DEFINE_FIELD_STRING(m_szUsableAmmos, PDFF_NOEDIT | PDFF_NOEXPORT, "ammos", "", EDITOR_NONE)
//! Класс заряженного в данный момент припаса
DEFINE_FIELD_STRING(m_szLoadedAmmo, PDFF_NOEDIT | PDFF_NOEXPORT, "loaded_ammo", "", EDITOR_NONE)
REGISTER_ENTITY_NOLISTING(CBaseTool, base_tool);
CBaseTool::CBaseTool(CEntityManager * pMgr):
BaseClass(pMgr),
m_bInPrimaryAction(false),
m_bInSecondaryAction(false),
m_bWorldModel(false),
m_bCanUse(true),
m_fZoomTime(0.0f),
m_iZoomable(1),
m_iSoundAction1(-1),
m_iSoundAction2(-1),
m_iMuzzleFlash(-1),
m_iMuzzleFlash2(-1),
m_fMaxDistance(1000.0f),
m_iIvalUpdate = SET_INTERVAL(_update, 0);
Byurrrer
committed
m_iSoundAction1 = SSCore_SndCreate3dInst(m_szPrimaryActionSound, SX_SOUND_CHANNEL_GAME, 100);
Byurrrer
committed
m_iSoundAction2 = SSCore_SndCreate3dInst(m_szSecondaryActionSound, SX_SOUND_CHANNEL_GAME, 100);
}
if(m_szPrimaryActionMuzzleflash[0])
{
m_iMuzzleFlash = SPE_EffectInstanceByName(m_szPrimaryActionMuzzleflash);
}
if(m_szSecondaryActionMuzzleflash[0])
{
m_iMuzzleFlash2 = SPE_EffectInstanceByName(m_szSecondaryActionMuzzleflash);
}
}
void CBaseTool::setNextUse(float time)
void CBaseTool::primaryAction(BOOL st)
SPE_EffectSetEnable(m_iMuzzleFlash, true);
Byurrrer
committed
SSCore_SndInstancePlay3d(m_iSoundAction1, false, false, &getPos());
float3 start = getPos();
float3 dir = m_pParent->getOrient() * float3(0.0f, 0.0f, 1.0f);
btCollisionWorld::ClosestRayResultCallback cb(F3_BTVEC(start), F3_BTVEC(end));
SPhysics_GetDynWorld()->rayTest(F3_BTVEC(start), F3_BTVEC(end), cb);
if(cb.hasHit())
{
//shoot decal
SXDecals_ShootDecal(DECAL_TYPE_CONCRETE, BTVEC_F3(cb.m_hitPointWorld), BTVEC_F3(cb.m_hitNormalWorld));
Byurrrer
committed
SPE_EffectPlayByName("fire", &BTVEC_F3(cb.m_hitPointWorld), &BTVEC_F3(cb.m_hitNormalWorld));
if(!cb.m_collisionObject->isStaticOrKinematicObject())
{
((btRigidBody*)cb.m_collisionObject)->applyCentralImpulse(F3_BTVEC(dir * 10.0f));
cb.m_collisionObject->activate();
}
}
void CBaseTool::secondaryAction(BOOL st)
((CPlayer*)m_pOwner)->getCrosshair()->enable(!st);
void CBaseTool::setIsWorldModel(bool b)
setNextUse(m_fReloadTime);
playAnimation("reload");
void CBaseTool::dbgMove(int dir, float dy)
case DSM_LEN:
m_fCenterLength += dy;
break;
printf(COLOR_GREEN "slot_offset = " COLOR_LGREEN "%f %f %f\n"
COLOR_GREEN "slot_rotation = " COLOR_LGREEN "%f %f %f %f\n"
COLOR_GREEN "center_length = " COLOR_LGREEN "%f\n" COLOR_RESET
, m_qSlotRotResult.x, m_qSlotRotResult.y, m_qSlotRotResult.z, m_qSlotRotResult.w
, m_fCenterLength);
if(m_pOwner)
{
float3_t ang = ((CPlayer*)m_pOwner)->getWeaponDeltaAngles();
m_vOffsetOrient = m_qSlotRotResult * SMQuaternion(ang.x, 'x') * SMQuaternion(ang.y, 'y') * SMQuaternion(ang.z, 'z');
}
else
{
m_vOffsetOrient = m_qSlotRotResult;
}
Byurrrer
committed
{
float3 pos = m_pModel->asAnimatedModel()->getBoneTransformPos(m_pModel->asAnimatedModel()->getBoneId("muzzle_rifle1"));
SPE_EffectSetPos(m_iMuzzleFlash, &pos);
SPE_EffectSetRotQ(m_iMuzzleFlash, m_vOrientation);
Byurrrer
committed
}
if(m_inventoryMode == IIM_EQUIPPED && m_fCenterLength > 0.4f /* player capsule radius */)
{
// raycast towards to check if
float3 start = m_pParent->getPos();
float3 dir = m_pParent->getOrient() * float3(0.0f, 0.0f, 1.0f);
float3 end = start + dir * m_fCenterLength;
btCollisionWorld::ClosestRayResultCallback cb(F3_BTVEC(start), F3_BTVEC(end));
SPhysics_GetDynWorld()->rayTest(F3_BTVEC(start), F3_BTVEC(end), cb);
m_isClose = cb.hasHit();
}
bool needRezoom = false;
float speed = 1.0f / m_fZoomTime;
if(m_bInSecondaryAction && m_iZoomable)
if(m_fZoomProgress > 1.0f)
{
m_fZoomProgress = 1.0f;
}
if(m_fZoomProgress < 0.0f)
{
m_fZoomProgress = 0.0f;
}
needRezoom = true;
}
}
if(m_isClose)
{
if(m_fCloseProgress < 1.0f)
{
m_fCloseProgress += dt * speed;
if(m_fCloseProgress > 1.0f)
{
m_fCloseProgress = 1.0f;
}
needRezoom = true;
else
{
if(m_fCloseProgress > 0.0f)
{
m_fCloseProgress -= dt * speed;
if(m_fCloseProgress < 0.0f)
{
m_fCloseProgress = 0.0f;
}
needRezoom = true;
}
}
if(needRezoom)
{
_rezoom();
}
void CBaseTool::setParent(CBaseEntity * pEnt, int attachment)
BaseClass::setParent(pEnt, attachment);
const float * r_default_fov = GET_PCVAR_FLOAT("r_default_fov");
m_vSlotPosResult = (float3)vlerp(vlerp(m_vSlotPos, m_vSlotPosClose, m_fCloseProgress), m_vSlotPosAim, m_fZoomProgress);
m_qSlotRotResult = SMquaternionSlerp(SMquaternionSlerp(m_qSlotRot, m_qSlotRotClose, m_fCloseProgress), m_qSlotRotAim, m_fZoomProgress);
if(m_pOwner && m_pOwner->getClassName() && !fstrcmp(m_pOwner->getClassName(), "player"))
((CPlayer*)m_pOwner)->getCamera()->getCamera()->setFOV(SMToRadian(vlerp(*r_default_fov, *r_default_fov - 10.0f, m_fZoomProgress)));
{
return(m_bIsWeapon);
}
float CBaseTool::getCondition() const
{
return(1.0f);
}
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
CBaseSupply *CBaseTool::getAmmo() const
{
return(m_pLoadedAmmo);
}
void CBaseTool::chargeAmmo(CBaseSupply *pAmmo)
{
if(!pAmmo || !isValidAmmo(pAmmo))
{
return;
}
if(getAmmo())
{
uncharge();
}
m_pLoadedAmmo = pAmmo;
m_pLoadedAmmo->setParent(this);
_setStrVal(&m_szLoadedAmmo, m_pLoadedAmmo->getClassName());
}
void CBaseTool::uncharge()
{
if(!getAmmo())
{
return;
}
_setStrVal(&m_szLoadedAmmo, "");
m_pLoadedAmmo->setParent(NULL);
//getOwner()->getInventory()->put(getAmmo());
m_pLoadedAmmo = NULL;
}
bool CBaseTool::isValidAmmo(CBaseSupply *pAmmo)
{
const char * str = strstr(m_szUsableAmmos, pAmmo->getClassName());
if(str)
{
char chr = str[strlen(pAmmo->getClassName())];
return(chr == ',' || chr == 0);
}
return(false);
}
float CBaseTool::getMaxDistance() const
{
return(m_fMaxDistance);
}