-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnatives.cpp
108 lines (97 loc) · 3.18 KB
/
natives.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/.
*
* The original code is copyright (c) 2022, open.mp team and contributors.
*/
// Required for most of open.mp.
#include <sdk.hpp>
// Include the globally shared definitions for this component.
#include "interface.hpp"
// Contains wrappers for pool lookups from IDs.
#include "natives.hpp"
// `SCRIPT_API` is an enhanced wrapper around the old *pawn-natives* system:
//
// https://github.com/Y-Less/pawn-natives
//
SCRIPT_API(RWW_Create, int(String const& name, String const& location))
{
// Try get a reference to the controlling component.
if (auto rww = WeatherComponent::getInstance())
{
// Call a method on the component.
if (auto ret = rww->createWeatherRegion(name, location))
{
// Pawn wants the ID, not the pointer.
return ret->getID();
}
}
// Natives return `0`/`false` by default if parameter lookups fail.
return 0;
}
SCRIPT_API(RWW_Destroy, bool(IWeatherRegion& region))
{
// Try get a reference to the controlling component.
if (auto rww = WeatherComponent::getInstance())
{
rww->destroyWeatherRegion(®ion);
// Using the region here is use-after-free.
return true;
}
return false;
}
// `IWeatherRegion&` calls the parameter lookup from ID and can auto-fail.
SCRIPT_API(RWW_GetName, bool(IWeatherRegion& region, OutputOnlyString& name))
{
name = region.getName();
// Natives return `0`/`false` by default if parameter lookups fail.
return true;
}
// `OutputOnlyString` translates in pawn to a `string/length` pair.
SCRIPT_API(RWW_GetLocation, bool(IWeatherRegion& region, OutputOnlyString& name))
{
name = region.getLocation();
// Natives return `0`/`false` by default if parameter lookups fail.
return true;
}
// Look up the ID, if it doesn't fail the function will be called.
SCRIPT_API(RWW_IsValid, bool(IWeatherRegion&))
{
// Merely calling this function is enough to validate the region ID exists.
return true;
}
SCRIPT_API(RWW_GetWeather, int(IWeatherRegion& region))
{
return static_cast<int>(region.getWeather());
}
// `IPlayer&` lookup is in-built.
SCRIPT_API(RWW_SetPlayerRegion, bool(IPlayer& player, IWeatherRegion& region))
{
// Get the extension data for this player, created when they connected.
if (auto data = queryExtension<IWeatherExtension>(player))
{
// Player, extension data, and region all exist.
data->setWeatherRegion(®ion);
// In a full implementation we should also update their weather here, but that's done in
// `WeatherComponent::onTick` and in the example script just to demonstrate a greater
// variety of features.
return true;
}
// Extension data doesn't exist, failed to set the region.
return false;
}
// Most SDK functions return pointers/references. Here we convert it to an ID.
SCRIPT_API(RWW_GetPlayerRegion, int(IPlayer& player))
{
// Get the extension data for this player, created when they connected.
if (auto data = queryExtension<IWeatherExtension>(player))
{
// Get their region if they are in one.
if (auto region = data->getWeatherRegion())
{
return region->getID();
}
}
return 0;
}