Commit 02fa43e7 authored by Byurrrer's avatar Byurrrer

Много всяких изменений

parent 80f2a309
[npc_zombie]
model = "models/zombie/zombie.dse"
......@@ -10,6 +10,7 @@ TODO: возможно надо будет в первом проходе обн
half4 LightPos;
half2 SizeMap;
half RadiusSun;
half4 Color;
sampler2D DepthSampler:register(s0);
......@@ -17,9 +18,10 @@ half4 main(vs_out_pp IN) : COLOR0
{
half2 SunPosProj = LightPos.xy;
half depth = tex2D(DepthSampler,IN.TexUV).r;
clip(depth - 0.999f);
half2 ntc = IN.TexUV;
ntc.y *= SizeMap.y/SizeMap.x;
SunPosProj.y *= SizeMap.y/SizeMap.x;
half tmpcolor = lerp(0.f,1.f,1.f-(saturate((distance(ntc, SunPosProj)) * (1.f / (((RadiusSun)/0.9f)/SizeMap.x))))) * 0.7f * saturate(depth);
return tmpcolor;
half tmpcolor = lerp(0.f,1.f,1.f-(saturate((distance(ntc, SunPosProj)) * (1.f / (((RadiusSun)/0.9f)/SizeMap.x))))) * 0.7f;// * saturate(depth);
return tmpcolor*Color;
}
\ No newline at end of file
......@@ -23,6 +23,8 @@ half4 main(vs_out_pp IN) : COLOR0
half2 SunPosProj = LightPos.xy;
half depth = tex2D(DepthSampler, IN.TexUV).r;
clip(depth - 0.999f);
half2 ntc = IN.TexUV;
......@@ -33,7 +35,7 @@ half4 main(vs_out_pp IN) : COLOR0
half4 texColor = tex2D(SunSampler, fSunTexUV);
screen.a *= 1.f - depth;
//screen.a *= 1.f - depth;
texColor.rgb *= LightColor.rgb;
texColor.rgb = lerp(texColor.rgb,Color.rgb,Color.a);
......
......@@ -13,6 +13,7 @@ bind space +jump
bind mouse1 +attack
bind mouse3 +attack2
bind r reload
bind t flashlight
bind f12 screenshot
bind f11 save_worktex
......
docs/html/particles_editor/image26.png

15.6 KB | W: | H:

docs/html/particles_editor/image26.png

8.66 KB | W: | H:

docs/html/particles_editor/image26.png
docs/html/particles_editor/image26.png
docs/html/particles_editor/image26.png
docs/html/particles_editor/image26.png
  • 2-up
  • Swipe
  • Onion skin
docs/html/particles_editor/image28.png

13.3 KB | W: | H:

docs/html/particles_editor/image28.png

8.66 KB | W: | H:

docs/html/particles_editor/image28.png
docs/html/particles_editor/image28.png
docs/html/particles_editor/image28.png
docs/html/particles_editor/image28.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -97,6 +97,8 @@
<ClCompile Include="..\..\..\source\game\EntityManager.cpp" />
<ClCompile Include="..\..\..\source\game\FuncTrain.cpp" />
<ClCompile Include="..\..\..\source\game\GameData.cpp" />
<ClCompile Include="..\..\..\source\game\NPCBase.cpp" />
<ClCompile Include="..\..\..\source\game\NPCZombie.cpp" />
<ClCompile Include="..\..\..\source\game\PathCorner.cpp" />
<ClCompile Include="..\..\..\source\game\proptable.cpp" />
<ClCompile Include="..\..\..\source\game\SXbaseAmmo.cpp" />
......@@ -125,6 +127,8 @@
<ClInclude Include="..\..\..\source\game\EntityManager.h" />
<ClInclude Include="..\..\..\source\game\FuncTrain.h" />
<ClInclude Include="..\..\..\source\game\GameData.h" />
<ClInclude Include="..\..\..\source\game\NPCBase.h" />
<ClInclude Include="..\..\..\source\game\NPCZombie.h" />
<ClInclude Include="..\..\..\source\game\PathCorner.h" />
<ClInclude Include="..\..\..\source\game\proptable.h" />
<ClInclude Include="..\..\..\source\game\SXbaseAmmo.h" />
......
......@@ -111,6 +111,12 @@
<ClCompile Include="..\..\..\source\game\ambient_sounds.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\source\game\NPCBase.cpp">
<Filter>Source Files\ents</Filter>
</ClCompile>
<ClCompile Include="..\..\..\source\game\NPCZombie.cpp">
<Filter>Source Files\ents</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\source\game\sxgame.h">
......@@ -191,5 +197,11 @@
<ClInclude Include="..\..\..\source\game\ambient_sounds.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\source\game\NPCBase.h">
<Filter>Header Files\ents</Filter>
</ClInclude>
<ClInclude Include="..\..\..\source\game\NPCZombie.h">
<Filter>Header Files\ents</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -140,6 +140,8 @@
<Image Include="..\..\..\source\sxleveleditor\resource\arrow.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\axes.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\grid.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\lvl_in.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\lvl_out.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\new.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\open.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\pos.bmp" />
......@@ -157,12 +159,15 @@
<Image Include="..\..\..\source\sxleveleditor\resource\sel_m.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\sel_s.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\sel_z.bmp" />
<Image Include="..\..\..\source\sxleveleditor\resource\sun.bmp" />
<Image Include="resource\aigrid_bound.bmp" />
<Image Include="resource\aigrid_graphpoint.bmp" />
<Image Include="resource\aigrid_quad.bmp" />
<Image Include="resource\arrow.bmp" />
<Image Include="resource\axes.bmp" />
<Image Include="resource\grid.bmp" />
<Image Include="resource\lvl_in.bmp" />
<Image Include="resource\lvl_out.bmp" />
<Image Include="resource\open.bmp" />
<Image Include="resource\pos.bmp" />
<Image Include="resource\rot.bmp" />
......@@ -179,6 +184,7 @@
<Image Include="resource\sel_m.bmp" />
<Image Include="resource\sel_s.bmp" />
<Image Include="resource\sel_z.bmp" />
<Image Include="resource\sun.bmp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
......
......@@ -207,5 +207,23 @@
<Image Include="..\..\..\source\sxleveleditor\resource\aigrid_graphpoint.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resource\lvl_in.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resource\lvl_out.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="resource\sun.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="..\..\..\source\sxleveleditor\resource\lvl_in.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="..\..\..\source\sxleveleditor\resource\lvl_out.bmp">
<Filter>Resource Files</Filter>
</Image>
<Image Include="..\..\..\source\sxleveleditor\resource\sun.bmp">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -56,6 +56,8 @@ See the license in LICENSE
#define G_RI_INT_TIMER_RENDER 4 /*!< время для рендера */
#define G_RI_INT_TIMER_GAME 5 /*!< время для игры */
#define G_RI_INT_TIME_DELTA 6 /*!< время рендера кадра */
//! @}
#endif
......@@ -12,8 +12,6 @@ See the license in LICENSE
#include <SkyXEngine.cpp>
#include <physics/sxphysics.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
SkyXEngine_PreviewCreate();
......@@ -28,6 +26,19 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLin
SGeom_0SettGreenSetFreqGrass(30);
/*NPCBase* npc = new NPCBase();
npc->SetModel("models/stalker_zombi/stalker_zombi_a.dse");
npc->SetPos(&float3(0, 0, 0));*/
for (int i = 0; i < 10; ++i)
{
SXbaseEntity* bEnt = SXGame_CreateEntity("npc_zombie");
bEnt->SetFlags(bEnt->GetFlags() | EF_EXPORT | EF_LEVEL);
char pos[256];
//sprintf(pos, "%f %f %f", randf(-0.1, 0.1), randf(-0.1, 0.1), randf(-0.1, 0.1));
bEnt->SetKV("origin", "0 0 0");
}
/*for (int i = 0; i < 10; ++i)
{
for (int k = 0; k < 10; ++k)
......
......@@ -174,6 +174,7 @@ void AIGrid::GridLoad(const char* path)
AIQuad* tmpaq = AllocAIQuad.Alloc();
fread(tmpaq, sizeof(AIQuad), 1, file);
ArrQuads.push_back(tmpaq);
ArrLongCoordQuads[tmpaq->Id] = int3(toint100(tmpaq->pos.x), toint100(tmpaq->pos.y), toint100(tmpaq->pos.z));
}
CountObject = 0;
......@@ -225,6 +226,7 @@ void AIGrid::ReCreateBuffs()
ArrParentIDs.resize(ArrQuads.size());
ArrCloseIDs.resize(ArrQuads.size());
ArrState.resize(ArrQuads.size());
ArrStateWho.resize(ArrQuads.size());
ArrPreCondFreeState.resize(ArrQuads.size());
memset(&(ArrColor[0]), 0, ArrColor.size() * sizeof(uint32_t));
memset(&(ArrIDsInOpen[0]), -1, ArrIDsInOpen.size() * sizeof(ID));
......@@ -233,6 +235,7 @@ void AIGrid::ReCreateBuffs()
memset(&(ArrParentIDs[0]), -1, ArrParentIDs.size() * sizeof(ID));
memset(&(ArrCloseIDs[0]), 0, ArrCloseIDs.size() * sizeof(bool));
memset(&(ArrState[0]), (int)AIQUAD_STATE_FREE, ArrState.size() * sizeof(AIQUAD_STATE));
memset(&(ArrStateWho[0]), -1, ArrStateWho.size() * sizeof(ID));
memset(&(ArrPreCondFreeState[0]), false, ArrPreCondFreeState.size() * sizeof(bool));
}
......@@ -262,6 +265,7 @@ void AIGrid::DefInitBuffs(ID id)
ArrParentIDs[id] = -1;
ArrCloseIDs[id] = 0;
ArrState[id] = AIQUAD_STATE_FREE;
ArrStateWho[id] = -1;
ArrPreCondFreeState[id] = true;
}
......@@ -452,6 +456,18 @@ void AIGrid::QuadSetState(ID id, AIQUAD_STATE state)
ArrState[id] = state;
}
void AIGrid::QuadSetStateWho(ID id, ID who)
{
AIGRID_QUAD_PRECOND(id, _VOID);
ArrStateWho[id] = who;
}
ID AIGrid::QuadGetStateWho(ID id)
{
AIGRID_QUAD_PRECOND(id, -1);
return ArrStateWho[id];
}
void AIGrid::QuadSetPosY(ID id, float posy)
{
AIGRID_QUAD_PRECOND(id, _VOID);
......@@ -755,6 +771,7 @@ void AIGrid::QuadDelete2(ID id)
ArrParentIDs.erase(id);
ArrCloseIDs.erase(id);
ArrState.erase(id);
ArrStateWho.erase(id);
ArrPreCondFreeState.erase(id);
}
......@@ -986,6 +1003,7 @@ void AIGrid::Clear()
ArrParentIDs.clear();
ArrCloseIDs.clear();
ArrState.clear();
ArrStateWho.clear();
ArrPreCondFreeState.clear();
ArrGraphPointsIDs.clear();
ArrCostGPIDs.clear();
......@@ -1010,6 +1028,7 @@ void AIGrid::GridClear()
ArrParentIDs.clear();
ArrCloseIDs.clear();
ArrState.clear();
ArrStateWho.clear();
ArrPreCondFreeState.clear();
ArrGraphPointsIDs.clear();
ArrCostGPIDs.clear();
......@@ -1958,18 +1977,21 @@ ID AIGrid::QuadGet(const float3* pos, bool isnear_or_permissible) const
long tmpy = toint100(pos->y);
long tmpz = toint100(pos->z);
for (long i = 1, il = ArrBound.size(); i<il; ++i)
int3 tiv;
for (int i = 1, il = ArrBound.size(); i<il; ++i)
{
if (
ArrBound[i]->lmin.x - LAIGRID_QUAD_SIZE <= tmpx && ArrBound[i]->lmin.z - LAIGRID_QUAD_SIZE <= tmpz &&
ArrBound[i]->lmax.x + LAIGRID_QUAD_SIZE >= tmpx && ArrBound[i]->lmax.z + LAIGRID_QUAD_SIZE >= tmpz
)
{
for (DWORD k = 0, kl = ArrBound[i]->ArrIdsQuads.size(); k<kl; ++k)
for (int k = 0, kl = ArrBound[i]->ArrIdsQuads.size(); k<kl; ++k)
{
tiv = ArrLongCoordQuads[ArrBound[i]->ArrIdsQuads[k]];
if (
abs((ArrLongCoordQuads[ArrBound[i]->ArrIdsQuads[k]].x) - (tmpx)) <= LAIGRID_QUAD_SIZEDIV2 &&
abs((ArrLongCoordQuads[ArrBound[i]->ArrIdsQuads[k]].z) - (tmpz)) <= LAIGRID_QUAD_SIZEDIV2
abs((tiv.x) - (tmpx)) <= LAIGRID_QUAD_SIZEDIV2 &&
abs((tiv.z) - (tmpz)) <= LAIGRID_QUAD_SIZEDIV2
)
{
......@@ -1990,6 +2012,17 @@ ID AIGrid::QuadGet(const float3* pos, bool isnear_or_permissible) const
return howf;
}
bool AIGrid::QuadGetPos(ID id, float3* pos)
{
if (pos && id >= 0 && id < ArrQuads.size())
{
*pos = ArrQuads[id]->pos;
return false;
}
return false;
}
ID AIGrid::GridTraceBeam(const float3* start, const float3* dir) const
{
ID idf = -1;
......@@ -2889,11 +2922,19 @@ UINT AIGrid::GridGetSizePath()
return ArrPathIDs.size();
}
bool AIGrid::GridGetPath(ID * pmem, UINT count)
bool AIGrid::GridGetPath(ID * pmem, UINT count, bool reverse)
{
if (pmem)
{
memcpy(pmem, &(ArrPathIDs[0]), count * sizeof(ID));
if (!reverse)
memcpy(pmem, &(ArrPathIDs[0]), count * sizeof(ID));
else
{
for (int i = 0, il = ArrPathIDs.size(); i < il; ++i)
{
pmem[i] = ArrPathIDs[(il - 1) - i];
}
}
return true;
}
......
......@@ -161,6 +161,8 @@ public:
//установка/возвращение состояния квада
inline void QuadSetState(ID id, AIQUAD_STATE state);
inline AIQUAD_STATE QuadGetState(ID id) const;
inline void QuadSetStateWho(ID id, ID who);
inline ID QuadGetStateWho(ID id);
//установка/возвращение позиции по оси Y для квада
inline void QuadSetPosY(ID id, float posy);
......@@ -176,6 +178,7 @@ public:
inline bool QuadIsFree(ID id, int radius); //свободен ли квад id в радиусе radius (radius - количество квадов вокруг указанного в id, 1 - значит только указанный, 2 - значит все соседние и т.д.)
ID QuadGetNear(const float3* pos, bool isfree = false, int raius = 1); //возвращает id ближайшего квада (если isfree == true то ищет только свободные) С радиусом свободности radius
inline ID QuadGet(const float3* pos, bool isnear_or_permissible) const; //получить id квада по позиции, isnear_or_permissible - самый ближний квад, или самый ближний в пределах допустимой разницы начальной точки?
inline bool QuadGetPos(ID id, float3* pos);
//}
//сетка
......@@ -190,7 +193,7 @@ public:
inline UINT GridGetCountQuads(); //возвращает количество квадов в сетке
bool GridFindPath(ID beginq, ID endq); //поиск пути, (beginq,beginq]
inline UINT GridGetSizePath(); //размер найденного пути в количестве квадратов
inline bool GridGetPath(ID * pmem, UINT count); //запись найденного пути в уже выделенную память
inline bool GridGetPath(ID * pmem, UINT count, bool reverse); //запись найденного пути в уже выделенную память
inline void GridSetColorArr(const ID * pmem, DWORD color, UINT count);
inline void GridSetNullColor();
......@@ -233,6 +236,7 @@ protected:
Array<AIQuad*, 1000> ArrQuads; //массив готовых квадов (порядковый номер и есть id)
Array<AIQuad*, 1000> ArrQuadsCheck; //массив квадов на проверку (используется при генерации)
Array<AIQUAD_STATE> ArrState; //массив состояний для каждого квада (по id квада)
Array<ID> ArrStateWho; //массив идентификаторов объектов которые занимают квады (по id квада)
Array<bool> ArrPreCondFreeState; //массив состояния проверка занятости для каждого квада (по id квада)
Array<BoundAIQuad*> ArrBound; //массив ограничивающих объемов для разбиения сетки
......
......@@ -175,6 +175,20 @@ void SAIG_QuadSetState(ID id, AIQUAD_STATE state)
ObjAIGrid->QuadSetState(id, state);
}
void SAIG_QuadSetStateWho(ID id, ID who)
{
AIG_PRECOND(_VOID);
ObjAIGrid->QuadSetStateWho(id, who);
}
ID SAIG_QuadGetStateWho(ID id)
{
AIG_PRECOND(-1);
return ObjAIGrid->QuadGetStateWho(id);
}
ID SAIG_QuadGet(const float3* pos, bool isnear_or_permissible)
{
AIG_PRECOND(-1);
......@@ -182,6 +196,13 @@ ID SAIG_QuadGet(const float3* pos, bool isnear_or_permissible)
return ObjAIGrid->QuadGet(pos, isnear_or_permissible);
}
bool SAIG_QuadGetPos(ID id, float3* pos)
{
AIG_PRECOND(false);
return ObjAIGrid->QuadGetPos(id, pos);
}
void SAIG_QuadSetPosY(ID id, float posy)
{
AIG_PRECOND(_VOID);
......@@ -295,7 +316,7 @@ void SAIG_GridGenerate()
ObjAIGrid->GridGenerate();
}
int SAIG_GridFindPath(ID beginq, ID endq)
bool SAIG_GridFindPath(ID beginq, ID endq)
{
AIG_PRECOND(false);
......@@ -309,11 +330,11 @@ UINT SAIG_GridGetSizePath()
return ObjAIGrid->GridGetSizePath();
}
bool SAIG_GridGetPath(ID * pmem, UINT count)
bool SAIG_GridGetPath(ID * pmem, UINT count, bool reverse)
{
AIG_PRECOND(false);
return ObjAIGrid->GridGetPath(pmem, count);
return ObjAIGrid->GridGetPath(pmem, count, reverse);
}
void SAIG_GridSetColorArr(const ID * pmem, DWORD color, UINT count)
......
......@@ -137,9 +137,11 @@ SX_LIB_API bool SAIG_GridGetMarkSplits(); //!< возвращает сост
SX_LIB_API void SAIG_GridGenerate(); //!< функция просчетов, ее нужно вызывать чтобы просчитать всю аи сетку
SX_LIB_API UINT SAIG_GridGetCountQuads(); //!< возвращает количество квадов в сетке
SX_LIB_API int SAIG_GridFindPath(ID beginq, ID endq); //!< поиск пути, (beginq,beginq]
SX_LIB_API bool SAIG_GridFindPath(ID beginq, ID endq); //!< поиск пути, (beginq,beginq]
SX_LIB_API UINT SAIG_GridGetSizePath(); //!< размер найденного пути в количестве квадратов
SX_LIB_API bool SAIG_GridGetPath(ID * pmem, UINT count); //!< запись найденного пути в уже выделенную память
//! запись найденного пути в уже выделенную память, если reverse == true то будет записано от начала до конца пути, иначе от конца до начала пути
SX_LIB_API bool SAIG_GridGetPath(ID * pmem, UINT count, bool reverse);
SX_LIB_API void SAIG_GridSetColorArr(const ID * pmem, DWORD color, UINT count); //!< установка цвета массиву квадов
SX_LIB_API void SAIG_GridSetNullColor(); //!< обнуление увета у всех квадов
......@@ -151,9 +153,11 @@ SX_LIB_API void SAIG_GridSetNullColor(); //!< обнуление увета
SX_LIB_API void SAIG_QuadSetState(ID id, AIQUAD_STATE state); //!< устанавливает состояние для квада
SX_LIB_API AIQUAD_STATE SAIG_QuadGetState(ID id); //!< возвращает текущее состояние квада
SX_LIB_API void SAIG_QuadSetStateWho(ID id, ID who);
SX_LIB_API ID SAIG_QuadGetStateWho(ID id);
SX_LIB_API ID SAIG_QuadGet(const float3* pos, bool isnear_or_permissible); //!< получить id квада по позиции, isnear_or_permissible - самый ближний квад (true), или самый ближний в пределах допустимой разницы начальной точки (false)?
SX_LIB_API ID SAIG_QuadGet(const float3* pos, bool isnear_or_permissible); //!< получить id квада по позиции, isnear_or_permissible - самый ближний квад (true), или самый ближний в пределах допустимой разницы начальной точки (false)?
SX_LIB_API bool SAIG_QuadGetPos(ID id, float3* pos);
SX_LIB_API void SAIG_QuadSetPosY(ID id, float posy); //!< установка позиции по оси Y для квада
SX_LIB_API float SAIG_QuadGetPosY(ID id); //!< возвращает позицию по оси Y квада
......
......@@ -29,6 +29,7 @@ GameData::GameData()
Core_0RegisterConcmd("+attack2", ccmd_attack2_on);
Core_0RegisterConcmd("-attack2", ccmd_attack2_off);
Core_0RegisterConcmd("reload", ccmd_reload);
Core_0RegisterConcmd("flashlight", ccmd_toggleflashlight);
Core_0RegisterConcmd("spawn", ccmd_spawn);
Core_0RegisterConcmd("observe", ccmd_observe);
......@@ -165,3 +166,8 @@ void GameData::ccmd_reload()
{
m_pPlayer->Reload();
}
void GameData::ccmd_toggleflashlight()
{
m_pPlayer->ToggleFlashlight();
}
......@@ -51,6 +51,8 @@ protected:
static void ccmd_reload();
static void ccmd_toggleflashlight();
};
#endif
#include "NPCBase.h"
BEGIN_PROPTABLE(NPCBase)
// empty
END_PROPTABLE()
REGISTER_ENTITY_NOLISTING(NPCBase, npc_base);
NPCBase::NPCBase(EntityManager * pMgr) :
BaseClass(pMgr)
{
m_health = 1.f;
m_speed_walk = 0.07f;
m_speed_run = 0.12f;
m_immunity_weapon = 1.f;
m_curr_quaid_in_path = -1;
m_fBaseScale = 0.01f;
m_curr_aiquad = -1;
m_move_state = NPC_MOVE_STATE_IDLE;
m_angle_y_last = 0;
m_angle_y_next = 0;
m_alltime_rot = 0;
m_time_rot = 0;
}
NPCBase::~NPCBase()
{
}
void NPCBase::InitPhysics()
{
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(F3_BTVEC(m_vPosition));
//startTransform.setOrigin(btVector3(0, 12, 10));
m_pGhostObject = new btPairCachingGhostObject();
m_pGhostObject->setWorldTransform(startTransform);
//sweepBP->getOverlappingPairCache()->setInternalGhostPairCallback(new btGhostPairCallback());
m_pCollideShape = new btCapsuleShape(0.3f, 1.4f);
m_pGhostObject->setCollisionShape(m_pCollideShape);
m_pGhostObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
btScalar stepHeight = 0.4f;
m_pCharacter = new btKinematicCharacterController(m_pGhostObject, (btConvexShape*)m_pCollideShape, stepHeight, btVector3(0.0f, 1.0f, 0.0f));
m_pCharacter->setMaxJumpHeight(0.60f);
m_pCharacter->setJumpSpeed(3.50f);
m_pCharacter->setGravity(btVector3(0, -10.0f, 0));
m_pCharacter->setFallSpeed(300.0f);
SXPhysics_GetDynWorld()->addCollisionObject(m_pGhostObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::AllFilter & ~btBroadphaseProxy::DebrisFilter);
//m_pGhostObject->setCollisionFlags(m_pGhostObject->getCollisionFlags() /*| btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT*/);
SXPhysics_GetDynWorld()->addAction(m_pCharacter);
}
void NPCBase::SetPos(const float3 & pos)
{
float3 tpos = pos;
m_curr_aiquad = SAIG_QuadGet(&tpos, true);
if (m_curr_aiquad >= 0)
{
if (SAIG_QuadGetState(m_curr_aiquad) == AIQUAD_STATE_FREE)
{
SAIG_QuadSetState(m_curr_aiquad, AIQUAD_STATE_BUSY);
SAIG_QuadSetStateWho(m_curr_aiquad, this->GetId());
}
else
{
if (SAIG_QuadGetStateWho(m_curr_aiquad) != this->GetId())
{
ID idquad = SAIG_QuadGetNear(&(float3)m_vPosition, true, 2);
if (idquad >= 0)
{
m_curr_aiquad = idquad;
SAIG_QuadSetState(m_curr_aiquad, AIQUAD_STATE_BUSY);
SAIG_QuadSetStateWho(m_curr_aiquad, this->GetId());
SAIG_QuadGetPos(m_curr_aiquad, &tpos);
tpos.y += 0.7f;
SetPos(tpos);
}
}
}
}
BaseClass::SetPos(tpos);
m_pGhostObject->getWorldTransform().setOrigin(F3_BTVEC(tpos));
}
bool NPCBase::SetKV(const char * name, const char * value)
{
if (stricmp("origin", name) == 0)
{
propdata_t * field = GetField(name);
if (!field)
{
return(false);
}
float3_t f3;
if (3 == sscanf(value, "%f %f %f", &f3.x, &f3.y, &f3.z))
{
SetPos(f3);
return true;
}
else
return false;
}
return BaseClass::SetKV(name, value);
}
ID NPCBase::GetAIQuad()
{
return m_curr_aiquad;
}
bool NPCBase::PathFind(ID endq)
{
if (m_curr_aiquad >= 0 && SAIG_GridFindPath(m_curr_aiquad, endq))
{
m_arr_path.resize(SAIG_GridGetSizePath());
SAIG_GridGetPath(&(m_arr_path[0]), m_arr_path.size(), true);
SAIG_GridSetColorArr(&(m_arr_path[0]), D3DCOLOR_ARGB(128, 0, 255, 0), m_arr_path.size());
m_last_path_pos = m_vPosition;
return true;
}
return false;
}
void NPCBase::OnSync()
{
BaseClass::OnSync();
btTransform trans;
trans = m_pGhostObject->getWorldTransform();
m_vPosition = (float3)(float3(trans.getOrigin().x(), trans.getOrigin().y()-0.9, trans.getOrigin().z()));
// id
m_curr_aiquad = SAIG_QuadGet(&(float3)m_vPosition, false);
//
if (m_curr_aiquad < 0)
{
//
if (m_curr_quaid_in_path < 0 || m_curr_quaid_in_path >= m_arr_path.size())
{
if (m_health > 0.f)
{
// , -1
m_health = -1.f;
}
return;
}
// , id
else
m_curr_aiquad = m_arr_path[m_curr_quaid_in_path];
}
UpdateOrientLerp();
}
void NPCBase::PathWalk()
{
//
if (m_curr_quaid_in_path >= m_arr_path.size() || m_curr_quaid_in_path < 0)
{
m_curr_quaid_in_path = -1;
m_move_state = NPC_MOVE_STATE_IDLE_START;
return;
}
SAIG_QuadGetPos(m_arr_path[m_curr_quaid_in_path], &m_next_path_pos);
if (m_curr_quaid_in_path == 0)
OrientAtPoint(&m_next_path_pos, NPC_TIME_ORIENT_IN_PATH);
float r_curr = SMVector3Distance(m_vPosition, m_next_path_pos);
float r_last = SMVector3Distance(m_last_path_pos, m_next_path_pos);
if (SMVector3Distance(m_vPosition, m_next_path_pos) <= 0.05f || r_curr > r_last)
{
++m_curr_quaid_in_path;
if (m_curr_quaid_in_path < m_arr_path.size() && m_curr_quaid_in_path > 0)
{
SAIG_QuadGetPos(m_arr_path[m_curr_quaid_in_path], &m_next_path_pos);
OrientAtPoint(&m_next_path_pos, NPC_TIME_ORIENT_IN_PATH);
}
else
{
m_pCharacter->setWalkDirection(F3_BTVEC(float3(0,0,0)));
}
}
m_last_path_pos = m_vPosition;
}
void NPCBase::OrientAtPoint(const float3 * pos, DWORD ttime)
{
float3 curr_pos = GetPos();
curr_pos.y = 0;
float3 poscam = float3(pos->x, 0, pos->z);
float3 dircam = poscam - curr_pos;
dircam = SMVector3Normalize(dircam);
float angle = (acosf(SMVector3Dot(NPC_BASE_DIR, dircam)) * sign2(SMVector3Cross(NPC_BASE_DIR, dircam).y));
angle = (-angle);
float3 dir = SMVector3Normalize(SMQuaternion(angle, 'y') * NPC_BASE_DIR);
m_pCharacter->setWalkDirection(F3_BTVEC(dir * m_speed_walk));
if (ttime > 0)
{
m_angle_y_next = angle;
m_alltime_rot = 0;
m_time_rot = ttime;