Skip to content

Commit

Permalink
deferred triggers
Browse files Browse the repository at this point in the history
  • Loading branch information
Try committed Mar 10, 2024
1 parent 45a9d2d commit d3196b6
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 17 deletions.
2 changes: 1 addition & 1 deletion game/game/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class SaveGameHeader;
class Serialize {
public:
enum Version : uint16_t {
Current = 46
Current = 47
};
Serialize(Tempest::ODevice& fout);
Serialize(Tempest::IDevice& fin);
Expand Down
50 changes: 45 additions & 5 deletions game/world/triggers/abstracttrigger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,12 @@ AbstractTrigger::AbstractTrigger(Vob* parent, World &world, const zenkit::Virtua
data.type == VirtualObjectType::oCTriggerScript || data.type == VirtualObjectType::zCMover ||
data.type == VirtualObjectType::oCTriggerChangeLevel || data.type == VirtualObjectType::oCCSTrigger) {
auto& trigger = reinterpret_cast<const zenkit::VTrigger&>(data);
fireDelaySec = trigger.fire_delay_sec;
fireDelay = uint64_t(trigger.fire_delay_sec*1000.f);
retriggerDelay = uint64_t(trigger.retrigger_delay_sec*1000.f);
maxActivationCount = uint32_t(trigger.max_activation_count);
filterFlags = trigger.filter_flags;
triggerFlags = trigger.flags;
target = trigger.target;
filterFlags = trigger.filter_flags;
triggerFlags = trigger.flags;
target = trigger.target;
}

world.addTrigger(this);
Expand All @@ -52,13 +53,34 @@ bool AbstractTrigger::isEnabled() const {
return !disabled;
}

void AbstractTrigger::processDelayedEvents() {
auto evt = std::move(delayedEvents);
for(auto& i:evt) {
if(world.tickCount()<i.timeBarrier) {
delayedEvents.push_back(i);
continue;
}
implProcessEvent(i, true);
}
}

void AbstractTrigger::processEvent(const TriggerEvent& evt) {
if(emitTimeLast>0 && world.tickCount()<emitTimeLast+uint64_t(fireDelaySec*1000.f)) {
implProcessEvent(evt, false);
}

void AbstractTrigger::implProcessEvent(const TriggerEvent& evt, bool delayed) {
if(emitTimeLast>0 && world.tickCount()<emitTimeLast+retriggerDelay) {
world.triggerEvent(evt);
return;
}
emitTimeLast = world.tickCount();

if(fireDelay>0 && !delayed) {
TriggerEvent ex(evt.target, evt.emitter, world.tickCount() + fireDelay, evt.type);
delayedEvents.push_back(std::move(ex));
return;
}

switch(evt.type) {
case TriggerEvent::T_Startup:
case TriggerEvent::T_StartupFirstTime:
Expand Down Expand Up @@ -163,13 +185,31 @@ void AbstractTrigger::save(Serialize& fout) const {
boxNpc.save(fout);
fout.write(emitCount,disabled);
fout.write(emitTimeLast);

fout.write(uint32_t(delayedEvents.size()));
for(auto& i:delayedEvents) {
i.save(fout);
}
}

void AbstractTrigger::load(Serialize& fin) {
Vob::load(fin);
boxNpc.load(fin);
fin.read(emitCount,disabled);
fin.read(emitTimeLast);

if(fin.version()>=47) {
uint32_t size = 0;
fin.read(size);
delayedEvents.resize(size);
for(auto& i:delayedEvents) {
i.load(fin);
}
}
}

bool AbstractTrigger::hasDelayerEvents() const {
return delayedEvents.size()>0;
}

void AbstractTrigger::enableTicks() {
Expand Down
13 changes: 10 additions & 3 deletions game/world/triggers/abstracttrigger.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ class AbstractTrigger : public Vob {

std::string_view name() const;
bool isEnabled() const;
bool hasDelayerEvents() const;

void processDelayedEvents();
void processEvent(const TriggerEvent& evt);
virtual void onIntersect(Npc& n);
virtual void tick(uint64_t dt);
Expand Down Expand Up @@ -89,21 +91,26 @@ class AbstractTrigger : public Vob {
void disableTicks();
const std::vector<Npc*>& intersections() const;

void implProcessEvent(const TriggerEvent& evt, bool delayed);

private:
Cb callback;
DynamicWorld::BBoxBody box;
CollisionZone boxNpc;
Tempest::Vec3 bboxSize, bboxOrigin;

float fireDelaySec = 0;
uint64_t fireDelay = 0;
uint64_t retriggerDelay = 0;
uint32_t maxActivationCount = 0;
uint32_t triggerFlags = 0;
uint32_t filterFlags = 0;
uint32_t triggerFlags = 0;
uint32_t filterFlags = 0;

uint32_t emitCount = 0;
bool disabled = false;
uint64_t emitTimeLast = 0;

std::vector<TriggerEvent> delayedEvents;

protected:
std::string vobName;
std::string target;
Expand Down
28 changes: 22 additions & 6 deletions game/world/worldobjects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -395,26 +395,42 @@ void WorldObjects::tickNear(uint64_t /*dt*/) {
}
}

void WorldObjects::triggerEvent(const TriggerEvent &e) {
triggerEvents.push_back(e);
}

void WorldObjects::tickTriggers(uint64_t /*dt*/) {
execDelayedEvents();

auto evt = std::move(triggerEvents);
triggerEvents.clear();

for(auto& e:evt)
owner.execTriggerEvent(e);
}

void WorldObjects::triggerEvent(const TriggerEvent &e) {
triggerEvents.push_back(e);
void WorldObjects::execDelayedEvents() {
auto def = std::move(triggersDef);
for(auto i:def) {
i->processDelayedEvents();
if(i->hasDelayerEvents())
triggersDef.push_back(i);
}
}

bool WorldObjects::execTriggerEvent(const TriggerEvent& e) {
bool emitted=false;

for(auto& i:triggers) {
auto& t = *i;
if(t.name()==e.target) { // NOTE: trigger name is not unique - more then one trigger can be activated
t.processEvent(e);
emitted=true;
}
if(t.name()!=e.target)
continue; // NOTE: trigger name is not unique - more then one trigger can be activated

const bool hadDelayedEvt = t.hasDelayerEvents();
t.processEvent(e);
if(!hadDelayedEvt && t.hasDelayerEvents())
triggersDef.push_back(&t);
emitted = true;
}

return emitted;
Expand Down
7 changes: 5 additions & 2 deletions game/world/worldobjects.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,16 @@ class WorldObjects final {
Interactive& mobsi(size_t i) { return **(interactiveObj.begin()+i); }
uint32_t mobsiId(const void* ptr) const;

void setCurrentCs(CsCamera* cs);
CsCamera* currentCs() const;

void addTrigger(AbstractTrigger* trigger);
void triggerEvent(const TriggerEvent& e);
bool triggerOnStart(bool firstTime);
void execDelayedEvents();
bool execTriggerEvent(const TriggerEvent& e);
void enableTicks (AbstractTrigger& t);
void disableTicks(AbstractTrigger& t);
void setCurrentCs(CsCamera* cs);
CsCamera* currentCs() const;
void enableCollizionZone (CollisionZone& z);
void disableCollizionZone(CollisionZone& z);

Expand Down Expand Up @@ -170,6 +172,7 @@ class WorldObjects final {
std::vector<AbstractTrigger*> triggers;
std::vector<AbstractTrigger*> triggersZn;
std::vector<AbstractTrigger*> triggersTk;
std::vector<AbstractTrigger*> triggersDef;
std::vector<PerceptionMsg> sndPerc;
std::vector<TriggerEvent> triggerEvents;
CsCamera* currentCsCamera = nullptr;
Expand Down

0 comments on commit d3196b6

Please sign in to comment.