ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/pod/extensions.pod
Revision: 1.4
Committed: Thu Jan 8 03:03:24 2009 UTC (15 years, 4 months ago) by root
Branch: MAIN
CVS Tags: rel-2_82, rel-2_81, rel-2_80, rel-3_0, rel-2_76, rel-2_77, rel-2_75, rel-2_79, rel-2_90, rel-2_92, rel-2_93, rel-2_78
Changes since 1.3: +1 -1 lines
Log Message:
connected => shstr, beginning of mapscript

File Contents

# User Rev Content
1 root 1.3 =head1 DELIANTRA EXTENSION INTRODUCTION
2 elmex 1.1
3 root 1.3 In Deliantra, the plugin/extension and event API was completly rewritten
4     in Perl and C++. Here is a small guide or introduction on how to use it.
5 elmex 1.1
6     If you have any questions don't hesitate to contact the developers,
7     see: http://cf.schmorp.de/contact.shtml
8    
9    
10     =head2 Extension to <thing> attachments
11    
12     You can "attach" extensions to global events, to type/subtypes,
13     to specifix objects, to players and to maps.
14 elmex 1.2 On top of that an extension can implement new user commands.
15 elmex 1.1
16 elmex 1.2 If an extension for example wants to attach itself to all jeweler
17 elmex 1.1 skills it has to attach itself like this:
18    
19     cf::attach_to_type cf::SKILL, cf::SK_JEWELER,
20     on_use_skill => sub {
21     ... handling code here ...
22     };
23    
24     This function attaches itself to the type SKILL with the subtype
25     SK_JEWELER. And everytime someone uses the skill the callback
26     registered as 'on_use_skill' is called.
27     Multiple extensions can attach themself to this type, and they
28     can specify a priority with 'prio => -100' to be executed earlier.
29    
30     You can also attach a Perl package to the skill like this:
31    
32     cf::attach_to_type cf::SKILL, cf::SK_JEWELER,
33 root 1.3 package => 'ext::JewelerSkill';
34 elmex 1.1
35     cf::attach_to_objects will attach handlers for events on _all_ objects
36     in the game, this is mainly for debugging purposes, as it will produce a
37     high load.
38    
39     The map attachments work like this:
40    
41 elmex 1.2 If an extension wants to attach itself to the 'trigger' event (this is
42 elmex 1.1 the event that is generated when a connection is activated (pushed or
43     released)), it has to do this:
44    
45     cf::attach_to_maps
46     on_trigger => sub {
47     my ($map, $connection, $state) = @_;
48    
49     print "CONNECITON TRIGGERED: $connection : $state\n";
50    
51 root 1.4 for ($map->find_link ($connection)) {
52 elmex 1.1 print "connected obj: " . $_->name . "\n";
53     }
54     };
55    
56     This small attachment dumps all connection activations and the connected
57     objects. If this attachment now decides to overwrite connection 10, so that
58     nothing happens if it is triggered, it has to do this:
59    
60     cf::attach_to_maps
61     on_trigger => sub {
62     my ($map, $connection, $state) = @_;
63    
64     if ($connection == 10) {
65     cf::override;
66     return; # the idiom 'return cf::override;' is quite common in our code
67     # but i want to empasize that cf::override is just a functioncall
68     }
69     };
70    
71     The call of cf::override sets a flag in the event system that will prevent any execution
72     of further code that handles this event. This way all attachments with 'lower' priority
73     and the C/C++ code is inhibited/overridden.
74    
75     =head2 <thing> to extension attachments
76    
77     The attachments are not limited to 'an extension attaches itself to <...>', a map or an
78     objects itself can attach to a 'registered' attachment. For example our nice cat which runs
79     around in scorn and heals people at random has following line in it's archetype:
80    
81     Object nekosan
82     ...
83     attach [["Nekosan"]]
84     end
85    
86     The value of the attach field is a 2 dimensional array in JSON (JavaScript Object Notation)
87     is a array of arrays which contain following fields:
88     [ <attachment name/key>, { <key value pairs of arguments for the attachment> }]
89    
90     The code side of this looks like this:
91    
92     cf::register_attachment "Nekosan", package => __PACKAGE__;
93    
94     This registeres an attachment under the name/key 'Nekosan' so that objects like our
95     cat can attach itself.
96    
97     Where the package defines for example this function:
98     sub on_monster_move {
99     my ($self, $enemy) = @_;
100     ...
101     }
102    
103     $self is a mostly empty object, the attachment object, which is initalized
104     with the arguments that are given in the 'attach' value, if nekosan would have an
105     attach field like this:
106    
107     attach [["Nekosan", {"foo":"bar"}]]
108    
109     The attached function can access the value of the key "foo" like this:
110    
111     $self->{Nekosan}->{foo}
112    
113     This way multiple different attachments have a seperate field for storing
114     their arguments.
115    
116     =head2 Defining new user commands
117    
118 elmex 1.2 If an extension wants to redefine a user command it does it like this:
119 elmex 1.1
120     cf::register_command invite => 10, sub {
121     my ($who, $args) = @_;
122     ...
123     }
124    
125     This registers the 'invite' command with the execution time of 10. The
126     arguments to the function are ($who, $args), where $who is the player
127     and $args the argument string to the command.
128    
129     =head2 Adding event invocations to the C++ code
130    
131     There are already a lot of events implemented, look in the L<events.pod> for
132     a reference of existing events. But when you need a new event, here
133     is how to do add it:
134    
135     Here an example for move_trigger in move_apply ():
136    
137     Add a line to doc/events.pod with documentation looking like this:
138    
139     =head3 move_trigger (object victim originator -- )
140    
141     Invoked whenever a trap-like B<object> has been activated, usually by
142     moving onto it. This includes not just traps, but also buttons, holes,
143     signs and similar stuff.
144    
145     And put some lines like this to move_apply:
146    
147     if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator)))
148     goto leave;
149    
150     This invokes all attachments that are interested in the object event MOVE_TRIGGER, with
151     the object being 'trap' and the arguments victim and originator. This is all C++ code
152     that has to be added when one wants to add an event. 'make' will update include/eventinc.h
153     from the events.pod automatically when building.
154    
155     =head2 Resources / See also
156    
157     Here is the documentation for all this, which is maybe partly unfinished. But there
158     are also a lot of examples:
159    
160     =over 4
161    
162     =item lib/cf.pm
163    
164     Has some documentation of the attachment API
165    
166     =item pod/events.pod
167    
168     A reference for all existing events
169    
170     =item Examples
171    
172     Examples can be found in http://cvs.schmorp.de/cf.schmorp.de/maps/perl/
173    
174     =item NPC_Dialogue.pod in maps/perl/
175    
176     The NPC dialogue system might also be interesting: http://cf.schmorp.de/doc/development/NPC_Dialogue.html