Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion game/game/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ enum Guild: uint32_t {
};

enum {
MAX_AI_USE_DISTANCE = 150
MAX_AI_USE_DISTANCE = 165,
MOBSI_SEARCH_DISTANCE = 100*10,
};

enum {
Expand Down
16 changes: 11 additions & 5 deletions game/game/gamescript.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -766,8 +766,8 @@ void GameScript::fixNpcPosition(Npc& npc, float angle0, float distBias) {
auto pos0 = npc.position();

for(int r = 0; r<=800; r+=20) {
for(float ang = 0; ang<360; ang+=30.f) {
float a = float((ang+angle0)*M_PI/180.0);
for(int ang = 0; ang<360; ang+=30) {
float a = float((float(ang)+angle0)*M_PI/180.0);
float d = float(r)+distBias;
auto p = pos0+Vec3(std::cos(a)*d, 0, std::sin(a)*d);

Expand All @@ -776,12 +776,18 @@ void GameScript::fixNpcPosition(Npc& npc, float angle0, float distBias) {
continue;
p.y = ray.v.y;
npc.setPosition(p);
if(!npc.hasCollision())
if(!npc.hasCollision()) {
npc.updateTransform();
return;
}
if(d==0) {
// no need to loop multiple angles, with R of zero
break;
}
}
}

npc.setPosition(pos0);
// npc.setPosition(pos0);
}

void GameScript::eventPlayAni(Npc& npc, std::string_view ani) {
Expand Down Expand Up @@ -3384,7 +3390,7 @@ void GameScript::snd_play3d(std::shared_ptr<zenkit::INpc> npcRef, std::string_vi
return;
for(auto& c:file)
c = char(std::toupper(c));
auto sfx = ::Sound(*owner.world(),::Sound::T_3D,file,npc->position(),0.f,false);
auto sfx = ::Sound(*owner.world(),::Sound::T_3D,file,npc->centerPosition(),0.f,false);
sfx.play();
}

Expand Down
23 changes: 6 additions & 17 deletions game/game/movealgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -709,14 +709,6 @@ int32_t MoveAlgo::diveTime() const {
bool MoveAlgo::isClose(const Npc& npc, const Npc& p, float dist) {
float len = npc.qDistTo(p);
return (len<dist*dist);
/*
auto dp = npc.position()-p;
dp.y = 0;
float len = dp.quadLength();
if(len<dist*dist)
return true;
return false;
*/
}

bool MoveAlgo::isClose(const Npc& npc, const WayPoint& p) {
Expand All @@ -727,20 +719,17 @@ bool MoveAlgo::isClose(const Npc& npc, const WayPoint& p) {
}

bool MoveAlgo::isClose(const Npc& npc, const WayPoint& p, float dist) {
auto px = p.position();
px.y += npc.translateY();

float len = npc.qDistTo(px);
auto dp = p.groundPos - npc.position();
float len = dp.quadLength();
return (len<dist*dist);
}

bool MoveAlgo::isClose(const Npc& npc, const Tempest::Vec3& p, float dist) {
// NOTE: this need to be consistent with current go2 point implementation
auto dp = (p - npc.position());
if(std::abs(dp.y)<250)
dp.y = 0;
auto dp = (p - npc.centerPosition());
float len = dp.quadLength();
return (len<dist*dist);
// NOTE: extra check fo vertical only distances:
// some repair planks are too high (~5 meters) in the air
return (len<dist*dist) || Tempest::Vec2(dp.x,dp.z).quadLength() < 1.f;
}

bool MoveAlgo::startClimb(JumpStatus jump) {
Expand Down
23 changes: 20 additions & 3 deletions game/game/playercontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,23 @@ void PlayerControl::onRotateMouse(float dAngleX, float dAngleY) {
rotMouseY += dAngleY;
}

void PlayerControl::drawVobRay(DbgPainter& p) const {
auto w = Gothic::inst().world();
if(w==nullptr || w->player()==nullptr)
return;
auto pl = w->player();
auto focus = findFocus(&currentFocus);
if(focus.interactive!=nullptr) {
focus.interactive->drawVobRay(p, *pl);
}
if(focus.item!=nullptr) {
focus.item->drawVobRay(p, *pl);
}
if(focus.npc!=nullptr) {
pl->drawVobRay(p, *focus.npc);
}
}

void PlayerControl::tickFocus() {
currentFocus = findFocus(&currentFocus);
setTarget(currentFocus.npc);
Expand Down Expand Up @@ -358,7 +375,7 @@ void PlayerControl::moveFocus(FocusAction act) {
return;

auto vp = c->viewProj();
auto pos = currentFocus.npc->position()+Tempest::Vec3(0,currentFocus.npc->translateY(),0);
auto pos = currentFocus.npc->centerPosition();
vp.project(pos);

Npc* next = nullptr;
Expand All @@ -367,7 +384,7 @@ void PlayerControl::moveFocus(FocusAction act) {
auto npc = w->npcById(i);
if(npc->isPlayer())
continue;
auto p = npc->position()+Tempest::Vec3(0,npc->translateY(),0);
auto p = npc->centerPosition();
vp.project(p);

if(std::abs(p.x)>1.f || std::abs(p.y)>1.f || p.z<0.f)
Expand Down Expand Up @@ -481,7 +498,7 @@ void PlayerControl::marvinO() {
w->setPlayer(target);
}

Focus PlayerControl::findFocus(Focus* prev) {
Focus PlayerControl::findFocus(const Focus* prev) const {
auto w = Gothic::inst().world();
auto c = Gothic::inst().camera();
if(w==nullptr)
Expand Down
5 changes: 4 additions & 1 deletion game/game/playercontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

class DialogMenu;
class InventoryMenu;
class DbgPainter;
class World;
class Interactive;
class Npc;
Expand All @@ -25,6 +26,8 @@ class PlayerControl final {
bool isPressed(KeyCodec::Action a) const;
void onRotateMouse(float dAngleX, float dAngleY);

void drawVobRay(DbgPainter& p) const;

void changeZoom(int delta);
void tickFocus();
void clearFocus();
Expand Down Expand Up @@ -161,7 +164,7 @@ class PlayerControl final {
void toggleWalkMode();
void toggleSneakMode();
void moveFocus(FocusAction act);
Focus findFocus(Focus *prev);
Focus findFocus(const Focus* prev) const;

void clrDraw();
void implMove(uint64_t dt);
Expand Down
4 changes: 4 additions & 0 deletions game/gothic.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ class Gothic final {
bool doVobBox() const { return vobBox; }
void setVobBox(bool v) { vobBox = v; }

bool doVobRays() const { return vobRays; }
void setVobRays(bool v) { vobRays = v; }

bool isBenchmarkMode() const;
bool isBenchmarkModeCi() const;
void setBenchmarkMode(Benchmark b);
Expand Down Expand Up @@ -221,6 +224,7 @@ class Gothic final {
bool showFpsCounter = false;
bool showTime = false;
bool vobBox = false;
bool vobRays = false;
Benchmark isBenchmark = Benchmark::None;

std::string wrldDef, plDef, gameDatDef, ouDef;
Expand Down
2 changes: 1 addition & 1 deletion game/graphics/effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Effect::Effect(PfxEmitter&& pfx, std::string_view node)
}

Effect::Effect(const VisualFx& vfx, World& owner, const Npc& src, SpellFxKey key)
:Effect(vfx, owner, src.position(), key) {
:Effect(vfx, owner, src.centerPosition(), key) {
}

Effect::Effect(const VisualFx& v, World& owner, const Vec3& inPos, SpellFxKey k) {
Expand Down
20 changes: 6 additions & 14 deletions game/graphics/mesh/protomesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,26 +318,18 @@ size_t ProtoMesh::skinedNodesCount() const {
return ret;
}

Tempest::Matrix4x4 ProtoMesh::mapToRoot(size_t n) const {
Tempest::Matrix4x4 m;
m.identity();

while(n<nodes.size()) {
auto& nx = nodes[n];
auto mx = nx.transform;
mx.mul(m);
m = mx;
n = nx.parentId;
}
return m;
}

size_t ProtoMesh::findNode(std::string_view name, size_t def) const {
if(skeleton==nullptr)
return def;
return skeleton->findNode(name,def);
}

const Vec3* ProtoMesh::bboxCol() const {
if(skeleton==nullptr)
return bbox;
return skeleton->bboxCol;
}

void ProtoMesh::setupScheme(std::string_view s) {
auto sep = s.find("_");
if(sep!=std::string::npos) {
Expand Down
2 changes: 1 addition & 1 deletion game/graphics/mesh/protomesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ class ProtoMesh {
std::string scheme, fname;

size_t skinedNodesCount() const;
Tempest::Matrix4x4 mapToRoot(size_t node) const;
size_t findNode(std::string_view name,size_t def=size_t(-1)) const;
const Tempest::Vec3* bboxCol() const;

private:
void setupScheme(std::string_view s);
Expand Down
7 changes: 6 additions & 1 deletion game/graphics/mesh/skeleton.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ Skeleton::Skeleton(const zenkit::ModelHierarchy& src, const Animation* anim, std
bboxCol[0] = {src.collision_bbox.min.x, src.collision_bbox.min.y, src.collision_bbox.min.z};
bboxCol[1] = {src.collision_bbox.max.x, src.collision_bbox.max.y, src.collision_bbox.max.z};

// bbox size apears to be halfed in source file
bboxCol[0] *= 2.f;
bboxCol[1] *= 2.f;

nodes.resize(src.nodes.size());
tr.resize(src.nodes.size());

Expand Down Expand Up @@ -83,7 +87,8 @@ std::string_view Skeleton::defaultMesh() const {
}

float Skeleton::colisionHeight() const {
return std::fabs(bboxCol[1].y-bboxCol[0].y);
// scale by 0.5, to be compatible with old behaviour for now
return std::fabs(bboxCol[1].y-bboxCol[0].y) * 0.5f;
}

void Skeleton::mkSkeleton() {
Expand Down
13 changes: 8 additions & 5 deletions game/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,22 +263,25 @@ void MainWindow::paintEvent(PaintEvent& event) {
fnt.drawText(p,5,fnt.pixelSize()+5,fpsT);
}

if(Gothic::inst().doClock() && world!=nullptr) {
if (!Gothic::inst().isDesktop()) {
if(!Gothic::inst().isDesktop() && world!=nullptr) {
if(Gothic::inst().doClock()) {
auto hour = world->time().hour();
auto min = world->time().minute();
auto& fnt = Resources::font(scale);
string_frm clockT(int(hour),":",int(min));
fnt.drawText(p,w()-fnt.textSize(clockT).w-5,fnt.pixelSize()+5,clockT);
}
}

if(Gothic::inst().doVobBox() && !Gothic::inst().isDesktop()) {
auto c = Gothic::inst().camera();
if(world!=nullptr && c!=nullptr) {
if(Gothic::inst().doVobBox() && c!=nullptr) {
DbgPainter dbg(p,c->viewProj(),w(),h());
world->drawVobBoxNpcNear(dbg);
}

if(Gothic::inst().doVobRays() && c!=nullptr) {
DbgPainter dbg(p,c->viewProj(),w(),h());
player.drawVobRay(dbg);
}
}

if(auto wx = Gothic::inst().worldView()) {
Expand Down
6 changes: 5 additions & 1 deletion game/marvin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ Marvin::Marvin() {
{"ztoggle renderportals", C_Invalid},
{"ztoggle rendervob", C_Invalid},
{"ztoggle showportals", C_Invalid},
{"ztoggle showtraceray", C_Invalid},
{"ztoggle showtraceray", C_ToggleShowRay},
{"ztoggle tnl", C_Invalid},
{"ztoggle vobbox", C_ToggleVobBox},
{"zvideores %d %d %d", C_Invalid},
Expand Down Expand Up @@ -352,6 +352,10 @@ bool Marvin::exec(std::string_view v) {
Gothic::inst().setFRate(!Gothic::inst().doFrate());
return true;
}
case C_ToggleShowRay:{
Gothic::inst().setVobRays(!Gothic::inst().doVobRays());
return true;
}
case C_ToggleVobBox:{
Gothic::inst().setVobBox(!Gothic::inst().doVobBox());
return true;
Expand Down
1 change: 1 addition & 0 deletions game/marvin.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class Marvin {

// rendering
C_ToggleFrame,
C_ToggleShowRay,
C_ToggleVobBox,

// game
Expand Down
58 changes: 55 additions & 3 deletions game/physics/dynamicworld.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -700,9 +700,10 @@ float DynamicWorld::soundOclusion(const Tempest::Vec3& from, const Tempest::Vec3

DynamicWorld::NpcItem DynamicWorld::ghostObj(std::string_view visual) {
Tempest::Vec3 min={0,0,0}, max={0,0,0};
if(auto sk=Resources::loadSkeleton(visual)) {
min = sk->bboxCol[0];
max = sk->bboxCol[1];
if(auto sk = Resources::loadSkeleton(visual)) {
// scale by 0.5, to be compatible with old behaviour for now
min = sk->bboxCol[0] * 0.5f;
max = sk->bboxCol[1] * 0.5f;
}
auto obj = npcList->create(min,max);
float dim = std::max(obj->rX,obj->rZ);
Expand Down Expand Up @@ -921,6 +922,48 @@ float DynamicWorld::materialDensity(zenkit::MaterialGroup mat) {
return 2000.f;
}

float DynamicWorld::rayBox(const Tempest::Vec3& orig, const Tempest::Vec3& dir, const float TMax,
const Tempest::Matrix4x4& obj, const Tempest::Vec3& min, const Tempest::Vec3& max,
const float padd) {
using namespace Tempest;

auto tmp = obj;
tmp.inverse();

auto tOri = orig;
auto tDir = dir;
auto zero = 0.f;
tmp.project(tOri);
tmp.project(tDir.x, tDir.y, tDir.z, zero);

float tHit = rayBox(tOri, Vec3(tDir.x, tDir.y, tDir.z), TMax, min, max, padd);
if(tHit==TMax)
return TMax;

//NOTE: worry about non-uniform scale matrix
tDir *= tHit; zero = 0;
tmp.project(tDir.x, tDir.y, tDir.z, zero);
return tDir.length();
}

float DynamicWorld::rayBox(const Tempest::Vec3& orig, const Tempest::Vec3& dir, const float TMax,
const Tempest::Vec3& boxMin, const Tempest::Vec3& boxMax,
const float padd) {
using namespace Tempest;

Vec3 invDir = Vec3(1.f/dir.x, 1.f/dir.y, 1.f/dir.z);

Vec3 tMin = (boxMin - orig)*invDir;
Vec3 tMax = (boxMax - orig)*invDir;
Vec3 t1 = Vec3{std::min(tMin.x, tMax.x), std::min(tMin.y, tMax.y), std::min(tMin.z, tMax.z)};
Vec3 t2 = Vec3{std::max(tMin.x, tMax.x), std::max(tMin.y, tMax.y), std::max(tMin.z, tMax.z)};

float tNear = std::max(0.f, std::max(t1.x, std::max(t1.y, t1.z)));
float tFar = std::min(TMax, std::min(t2.x, std::min(t2.y, t2.z)));

return tNear > tFar ? TMax : std::max(0.f, tNear-padd);
}

std::string_view DynamicWorld::validateSectorName(std::string_view name) const {
return landMesh->validateSectorName(name);
}
Expand Down Expand Up @@ -965,6 +1008,15 @@ void DynamicWorld::NpcItem::setUserPointer(void *p) {
obj->setUserPointer(p);
}

auto DynamicWorld::NpcItem::center() const -> Tempest::Vec3 {
if(obj) {
const btTransform& tr = obj->getWorldTransform();
const Tempest::Vec3 ret = {tr.getOrigin().x(), tr.getOrigin().y(), tr.getOrigin().z()};
return ret*100.f;
}
return {};
}

float DynamicWorld::NpcItem::centerY() const {
if(obj) {
const btTransform& tr = obj->getWorldTransform();
Expand Down
Loading
Loading