Skip to main content

veloren_rtsim/rule/
report.rs

1use crate::{
2    RtState, Rule, RuleError,
3    data::{Report, report::ReportKind},
4    event::{EventCtx, OnDeath, OnTheft},
5};
6use common::rtsim::NpcInput;
7
8pub struct ReportEvents;
9
10impl Rule for ReportEvents {
11    fn start(rtstate: &mut RtState) -> Result<Self, RuleError> {
12        rtstate.bind::<Self, OnDeath>(on_death);
13        rtstate.bind::<Self, OnTheft>(on_theft);
14
15        Ok(Self)
16    }
17}
18
19fn on_death(ctx: EventCtx<ReportEvents, OnDeath>) {
20    let data = &mut *ctx.state.data_mut();
21
22    if let Some(wpos) = ctx.event.wpos {
23        let nearby = data.actors.nearby(None, wpos, 32.0).collect::<Vec<_>>();
24
25        let report = std::cell::LazyCell::new(|| {
26            data.reports.create(Report {
27                kind: ReportKind::Death {
28                    actor: ctx.event.actor,
29                    killer: ctx.event.killer,
30                },
31                at_tod: data.time_of_day,
32            })
33        });
34
35        // TODO: Don't push report to NPC inboxes, have a dedicated data structure that
36        // tracks reports by chunks and then have NPCs decide to query this
37        // data structure in their own time.
38        for actor_id in nearby {
39            if let Some(actor) = data.actors.get_mut(actor_id)
40                && let Some(npc) = actor.npc_mut()
41            {
42                npc.inbox.push_back(NpcInput::Report(*report));
43            }
44        }
45    }
46}
47
48fn on_theft(ctx: EventCtx<ReportEvents, OnTheft>) {
49    let data = &mut *ctx.state.data_mut();
50
51    let nearby = data
52        .actors
53        .nearby(None, ctx.event.wpos.as_(), 24.0)
54        .collect::<Vec<_>>();
55
56    let report = std::cell::LazyCell::new(|| {
57        data.reports.create(Report {
58            kind: ReportKind::Theft {
59                thief: ctx.event.actor,
60                site: ctx.event.site,
61                sprite: ctx.event.sprite,
62            },
63            at_tod: data.time_of_day,
64        })
65    });
66
67    for actor_id in nearby {
68        if let Some(actor) = data.actors.get_mut(actor_id)
69            && let Some(npc) = actor.npc_mut()
70        {
71            npc.inbox.push_back(NpcInput::Report(*report));
72        }
73    }
74}