Skip to content
Closed
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
12 changes: 11 additions & 1 deletion common/game/movealgo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,12 @@ void MoveAlgo::clearSpeed() {
fallCount = 0;
}

void MoveAlgo::startFall(const Tempest::Vec3& speed) {
fallSpeed = speed;
fallCount = 0;
setState(InAir);
}

bool MoveAlgo::accessDamFly(float dx, float dz, char hitType) {
if(flags!=Run && flags!=Falling && flags!=InAir)
return false;
Expand Down Expand Up @@ -984,7 +990,11 @@ void MoveAlgo::onMoveFailed(const Tempest::Vec3& dp, const DynamicWorld::Collisi
case Npc::GT_EnemyG:
case Npc::GT_Way:
case Npc::GT_Point: {
if(info.npc!=nullptr || info.preFall) {
if(npc.moveHint()==Npc::GT_Point && npc.isPlayer()) {
// marvin 'Y': give up on obstacle
npc.clearGoTo();
}
else if(info.npc!=nullptr || info.preFall) {
npc.setDirection(npc.rotation()+stp);
} else {
auto jc = npc.tryJump();
Expand Down
1 change: 1 addition & 0 deletions common/game/movealgo.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class MoveAlgo final {

void multSpeed(float s){ mulSpeed=s; }
void clearSpeed();
void startFall(const Tempest::Vec3& speed);
bool accessDamFly(float dx, float dz, char hitType);

bool testSlide(const Tempest::Vec3& p, DynamicWorld::CollisionTest& out) const;
Expand Down
114 changes: 100 additions & 14 deletions common/game/playercontrol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "world/objects/item.h"
#include "world/objects/interactive.h"
#include "world/world.h"
#include "game/damagecalculator.h"
#include "ui/dialogmenu.h"
#include "ui/inventorymenu.h"
#include "gothic.h"
Expand Down Expand Up @@ -45,7 +46,7 @@ void PlayerControl::setTarget(Npc *other) {
}
}

void PlayerControl::onKeyPressed(KeyCodec::Action a, Tempest::KeyEvent::KeyType key, KeyCodec::Mapping mapping) {
void PlayerControl::onKeyPressed(KeyCodec::Action a, Tempest::KeyEvent::KeyType key, KeyCodec::Mapping mapping, Tempest::Event::Modifier mod) {
auto w = Gothic::inst().world();
auto c = Gothic::inst().camera();
auto pl = w ? w->player() : nullptr;
Expand Down Expand Up @@ -195,6 +196,18 @@ void PlayerControl::onKeyPressed(KeyCodec::Action a, Tempest::KeyEvent::KeyType

if(a==Action::K_O && Gothic::inst().isMarvinEnabled())
marvinO();
if(a==Action::K_K && Gothic::inst().isMarvinEnabled())
marvinK();
if(a==Action::K_F8 && Gothic::inst().isMarvinEnabled())
marvinF8();
if(key==Tempest::KeyEvent::K_H && Gothic::inst().isMarvinEnabled() && Gothic::inst().settingsGetI("GAME","usePotionKeys")==0)
marvinH(mod);
if(a==Action::K_Y && Gothic::inst().isMarvinEnabled())
marvinY();
if(a==Action::K_G && Gothic::inst().isMarvinEnabled())
marvinG(mod);
if(a==Action::K_T && Gothic::inst().isMarvinEnabled())
marvinT(mod);

ctrl[a] = true;
}
Expand Down Expand Up @@ -446,33 +459,32 @@ void PlayerControl::clearInput() {
std::memset(wctrl,0,sizeof(wctrl));
}

void PlayerControl::marvinF8(uint64_t dt) {
void PlayerControl::marvinF8() {
auto w = Gothic::inst().world();
if(w==nullptr || w->player()==nullptr)
return;

// reset position, like oCNpc::ResetPos
auto& pl = *w->player();
auto pos = pl.position();
auto pos = pl.position() + Tempest::Vec3(0,150,0);
float rot = pl.rotationRad();
float s = std::sin(rot), c = std::cos(rot);

Tempest::Vec3 dp(c,0.8f,s);
pos += dp*6000*float(dt)/1000.f;
// forward impulse 30000, player mass 80
auto dp = Tempest::Vec3(std::cos(rot), 0, std::sin(rot)) * (30000.f/80.f/1000.f);

pl.changeAttribute(ATR_HITPOINTS,pl.attribute(ATR_HITPOINTSMAX),false);
pl.changeAttribute(ATR_MANA, pl.attribute(ATR_MANAMAX), false);
pl.clearState(false);
pl.clearSpeed();
pl.clearAiQueue();
pl.setPosition(pos);
pl.setInteraction(nullptr,true);
pl.setAnim(AnimationSolver::Idle);
pl.startFall(dp);

if(auto c = Gothic::inst().camera())
c->reset();
}

void PlayerControl::marvinK(uint64_t dt) {
void PlayerControl::marvinK() {
auto w = Gothic::inst().world();
if (w == nullptr || w->player() == nullptr)
return;
Expand All @@ -483,13 +495,15 @@ void PlayerControl::marvinK(uint64_t dt) {
float s = std::sin(rot), c = std::cos(rot);

Tempest::Vec3 dp(c, 0.0f, s);
pos += dp * 6000 * float(dt) / 1000.f;
pos += dp * 300;

pl.clearState(false);
pl.clearSpeed();
pl.setPosition(pos);
pl.setInteraction(nullptr,true);
// pl.setAnim(AnimationSolver::Idle); // Original G2 behaviour: K doesn't stop running
if(auto c = Gothic::inst().camera())
c->reset(&pl);
}

void PlayerControl::marvinO() {
Expand All @@ -502,6 +516,82 @@ void PlayerControl::marvinO() {
w->setPlayer(target);
}

void PlayerControl::marvinH(Tempest::Event::Modifier mod) {
auto w = Gothic::inst().world();
if(w == nullptr || w->player() == nullptr)
return;

auto& pl = *w->player();
if(mod & Tempest::Event::M_Shift) {
// hit focus npc
if(auto npc = focus().npc)
npc->takeDamage(pl,nullptr);
return;
}
if(mod & Tempest::Event::M_Ctrl) {
// damage without attacker
DamageCalculator::Damage dmg = {};
dmg[zenkit::DamageType::FIRE] = 5;
dmg[zenkit::DamageType::MAGIC] = 5;
auto ret = DamageCalculator::damageValue(pl,pl,nullptr,true,dmg,COLL_DOEVERYTHING);
if(ret.hasHit && !ret.invincible)
pl.changeAttribute(ATR_HITPOINTS,-ret.value,false);
return;
}
// hit self, like in vanilla
pl.takeDamage(pl,nullptr);
}

void PlayerControl::marvinY() {
auto w = Gothic::inst().world();
if(w == nullptr || w->player() == nullptr)
return;

auto& pl = *w->player();
if(!pl.setInteraction(nullptr))
return;

float rot = pl.rotationRad();
float s = std::sin(rot), c = std::cos(rot);
pl.goToPoint(pl.position() + Tempest::Vec3(c, 0.0f, s) * 1000);
}

void PlayerControl::marvinG(Tempest::Event::Modifier mod) {
auto w = Gothic::inst().world();
if(w == nullptr || w->player() == nullptr)
return;

// show ai of player or focus npc, only one at time
Npc* npc = w->player();
if(mod & Tempest::Event::M_Shift)
npc = focus().npc;
for(uint32_t i=0; i<w->npcCount(); ++i) {
auto n = w->npcById(i);
if(n!=nullptr && n!=npc)
n->dbgAi = false;
}
if(npc!=nullptr)
npc->dbgAi = !npc->dbgAi;
}

void PlayerControl::marvinT(Tempest::Event::Modifier mod) {
auto w = Gothic::inst().world();
if(w == nullptr || w->player() == nullptr)
return;

if(mod & Tempest::Event::M_Shift) {
w->player()->dbgInfo = !w->player()->dbgInfo;
return;
}
auto f = focus();
if(f.npc!=nullptr)
f.npc->dbgInfo = !f.npc->dbgInfo;
else if(f.interactive!=nullptr)
f.interactive->dbgInfo = !f.interactive->dbgInfo;
else if(f.item!=nullptr)
f.item->dbgInfo = !f.item->dbgInfo;
}

Focus PlayerControl::findFocus(const Focus* prev) const {
auto w = Gothic::inst().world();
auto c = Gothic::inst().camera();
Expand Down Expand Up @@ -568,10 +658,6 @@ bool PlayerControl::tickMove(uint64_t dt) {
if(tickCameraMove(dt))
return true;

if(ctrl[Action::K_F8] && Gothic::inst().isMarvinEnabled())
marvinF8(dt);
if(ctrl[Action::K_K] && Gothic::inst().isMarvinEnabled())
marvinK(dt);
cacheFocus = ctrl[Action::ActionGeneric];
if(camera!=nullptr)
camera->setLookBack(ctrl[Action::LookBack]);
Expand Down
10 changes: 7 additions & 3 deletions common/game/playercontrol.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class PlayerControl final {
PlayerControl(DialogMenu& dlg, InventoryMenu& inv);
~PlayerControl();

void onKeyPressed (KeyCodec::Action a, Tempest::Event::KeyType key, KeyCodec::Mapping mapping);
void onKeyPressed (KeyCodec::Action a, Tempest::Event::KeyType key, KeyCodec::Mapping mapping, Tempest::Event::Modifier mod = Tempest::Event::M_NoModifier);
void onKeyReleased(KeyCodec::Action a, KeyCodec::Mapping mapping);
bool isPressed(KeyCodec::Action a) const;
void onRotateMouse(float dAngleX, float dAngleY);
Expand Down Expand Up @@ -158,9 +158,13 @@ class PlayerControl final {

void setupSettings();
bool canInteract() const;
void marvinF8(uint64_t dt);
void marvinK(uint64_t dt);
void marvinF8();
void marvinK();
void marvinO();
void marvinH(Tempest::Event::Modifier mod);
void marvinY();
void marvinG(Tempest::Event::Modifier mod);
void marvinT(Tempest::Event::Modifier mod);
void toggleWalkMode();
void toggleSneakMode();
void moveFocus(FocusAction act);
Expand Down
2 changes: 2 additions & 0 deletions common/graphics/mesh/pose.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ class Pose final {
bool isInAnim(std::string_view sq) const;
bool isInAnim(const Animation::Sequence* sq) const;
bool hasAnim() const;
template<class F>
void forEachLayer(F f) const { for(auto& i:lay) f(*i.seq, i.sAnim); }
uint64_t animationTotalTime() const;
uint64_t atkTotalTime() const;

Expand Down
7 changes: 6 additions & 1 deletion common/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ void MainWindow::paintEvent(PaintEvent& event) {
DbgPainter dbg(p,c->viewProj(),w(),h());
player.drawVobRay(dbg);
}

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

if(auto wx = Gothic::inst().worldView()) {
Expand Down Expand Up @@ -455,7 +460,7 @@ void MainWindow::keyDownEvent(KeyEvent &event) {

auto act = keycodec.tr(event);
auto mapping = keycodec.mapping(event);
player.onKeyPressed(act,event.key,mapping);
player.onKeyPressed(act,event.key,mapping,event.modifier);

if(event.key==Event::K_F11) {
auto tex = renderer.screenshoot(cmdId, Size(int(swapchain.w()),int(swapchain.h())));
Expand Down
6 changes: 6 additions & 0 deletions common/utils/keycodec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ KeyCodec::Action KeyCodec::tr(Tempest::KeyEvent const& e) const {
return K_K;
if(e.key == Tempest::Event::K_O)
return K_O;
if(e.key == Tempest::Event::K_Y)
return K_Y;
if(e.key == Tempest::Event::K_G)
return K_G;
if(e.key == Tempest::Event::K_T)
return K_T;
return Idle;
}

Expand Down
3 changes: 3 additions & 0 deletions common/utils/keycodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ class KeyCodec final {
K_F8, // Marvin Mode's F8
K_K, // Marvin Mode's K
K_O, // Marvin Mode's O
K_Y, // Marvin Mode's Y
K_G, // Marvin Mode's G
K_T, // Marvin Mode's T
K_Del, // Settings menu

Last
Expand Down
1 change: 1 addition & 0 deletions common/world/aiqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class AiQueue {
void load(Serialize& fin);

size_t size() const { return aiActions.size(); }
auto operator[](size_t i) const -> const AiAction& { return aiActions[i]; }
void clear();
void pushBack (AiAction&& a);
void pushFront(AiAction&& a);
Expand Down
6 changes: 6 additions & 0 deletions common/world/objects/interactive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,12 @@ void Interactive::drawVobBox(DbgPainter& p) const {
}
}

void Interactive::drawDbgInfo(DbgPainter& p) const {
// like oCVob::ShowDebugInfo for oCMobInter
auto pos = displayPosition();
p.drawText(pos, string_frm("ST:",state," SC:",schemeName()));
}

void Interactive::drawVobRay(DbgPainter& p, const Npc& npc) const {
auto head = npc.mapHeadBone();

Expand Down
1 change: 1 addition & 0 deletions common/world/objects/interactive.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class Interactive : public Vob {

void drawVobBox(DbgPainter& p) const;
void drawVobRay(DbgPainter& p, const Npc& npc) const;
void drawDbgInfo(DbgPainter& p) const;

void resetPositionToTA(int32_t state);
void updateAnimation(uint64_t dt);
Expand Down
6 changes: 6 additions & 0 deletions common/world/objects/item.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "world/world.h"
#include "utils/versioninfo.h"
#include "utils/fileext.h"
#include "utils/string_frm.h"
#include "utils/dbgpainter.h"

using namespace Tempest;
Expand Down Expand Up @@ -93,6 +94,11 @@ void Item::drawVobBox(DbgPainter& p) const {
}
}

void Item::drawDbgInfo(DbgPainter& p) const {
auto pos = midPosition();
p.drawText(pos, string_frm(displayName()," x",count()));
}

void Item::drawVobRay(DbgPainter& p, const Npc& npc) const {
if(auto bbox = this->bBox()) {
// npc eyesight height
Expand Down
1 change: 1 addition & 0 deletions common/world/objects/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class Item : public Vob {

void drawVobBox(DbgPainter& p) const;
void drawVobRay(DbgPainter& p, const Npc& npc) const;
void drawDbgInfo(DbgPainter& p) const;

void save(Serialize& fout) const override;

Expand Down
Loading