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
24            .npcs
25            .nearby(None, wpos, 32.0)
26            .filter_map(|actor| actor.npc())
27            .collect::<Vec<_>>();
28
29        if !nearby.is_empty() {
30            let report = data.reports.create(Report {
31                kind: ReportKind::Death {
32                    actor: ctx.event.actor,
33                    killer: ctx.event.killer,
34                },
35                at_tod: data.time_of_day,
36            });
37
38            // TODO: Don't push report to NPC inboxes, have a dedicated data structure that
39            // tracks reports by chunks and then have NPCs decide to query this
40            // data structure in their own time.
41            for npc_id in nearby {
42                if let Some(npc) = data.npcs.get_mut(npc_id) {
43                    npc.inbox.push_back(NpcInput::Report(report));
44                }
45            }
46        }
47    }
48}
49
50fn on_theft(ctx: EventCtx<ReportEvents, OnTheft>) {
51    let data = &mut *ctx.state.data_mut();
52
53    let nearby = data
54        .npcs
55        .nearby(None, ctx.event.wpos.as_(), 24.0)
56        .filter_map(|actor| actor.npc())
57        .collect::<Vec<_>>();
58
59    if !nearby.is_empty() {
60        let report = data.reports.create(Report {
61            kind: ReportKind::Theft {
62                thief: ctx.event.actor,
63                site: ctx.event.site,
64                sprite: ctx.event.sprite,
65            },
66            at_tod: data.time_of_day,
67        });
68
69        for npc_id in nearby {
70            if let Some(npc) = data.npcs.get_mut(npc_id) {
71                npc.inbox.push_back(NpcInput::Report(report));
72            }
73        }
74    }
75}