--- deliantra/server/lib/cf/mapscript.pm 2009/01/08 04:35:04 1.2 +++ deliantra/server/lib/cf/mapscript.pm 2012/11/06 21:52:55 1.12 @@ -1,44 +1,125 @@ -#! perl +# +# This file is part of Deliantra, the Roguelike Realtime MMORPG. +# +# Copyright (©) 2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team +# +# Deliantra is free software: you can redistribute it and/or modify it under +# the terms of the Affero GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the Affero GNU General Public License +# and the GNU General Public License along with this program. If not, see +# . +# +# The authors can be reached via e-mail to +# -# this implements the mapscript connectable +=head1 NAME -package safe::mapscript; +cf::mapscript -use strict qw(subs vars); +=head1 DESCRIPTION -our ($self, $state, $activator, $originator); +This module implements the mapscript object. + +Map scripts are perl snippets that get executed whenever any connected +element is triggered (e.g. a check inv, a lever etc.) + +=head1 ENVIRONMENT + +The map scripts are compiled and executed into a namespace with the +following symbols available: + +=over 4 + +=cut + +package cf::mapscript::eval; + +use common::sense; + +=item $self + +The mapscript object itself. + +=item $state + +The state value (0 means release, <>0 means push/trigger/enable) that +triggered the map script. + +=item $activator + +The object that was triggered (the lever, check inv element, npc etc.). + +=item $originator + +The object that triggered the activator, usually (but not always) the +player who stepped on a check inv, pulled a lever etc. Can be C. + +=cut + +use vars qw($self $state $activator $originator); + +=item @obs = find $id_or_object + +Finds all objects with the given I C<$id>. If an object +reference is passed, it will be returned unchanged. + +=cut sub find($) { ref $_[0] ? $_[0] : $self->map->find_link ($_[0]) } -sub get($) { - (&find)[0]->value -} +=item trigger $id_or_object[, $state] + +Triggers the linked chain with the given I id, or the connected +chain associated with the given object (if an object reference is passed), +and passes the given state (or C<1>, if missing) to it. -sub set($;$) { +=cut + +sub trigger($;$) { $self->map->trigger ($_[0], $#_ ? $_[1] : 1, $self); } +=item timer $id_or_object, $seconds + +Starts the timer on the given mapscript object (usually, C<$id_or_object> is +C<$self>). When the timer expires on the mapscript object, it will trigger +the script with C<$activator == $self> and C<$originator == undef>. + +=cut + sub timer($$) { my $ob = (&find)[0]; - $ob->speed_left ($_[1] / -cf::TICK); + $ob->speed_left (-$_[1] / cf::TICK); $ob->set_speed (1); } package cf::mapscript; -use strict qw(subs vars); +use common::sense; + +*{"main::safe::cf::mapscript::eval::"} = \%{"main::cf::mapscript::eval::"}; + +our %CACHE; sub activate($$$) { - ($self, $state, $activator, $originator) = @_; + package cf::mapscript::eval; - warn "$self->{msg} $self->{on_activate}\n";#d# + ($self, $state, $activator, $originator) = @_; ( - $self->{on_activate} ||= cf::safe_eval - "package mapscript; sub {\n" + $CACHE{$self->msg} ||= cf::safe_eval + "package cf::mapscript::eval; sub {\n" . "#line 1 '" . ($self->debug_desc) . "'\n" . $self->msg . "\n}" @@ -46,4 +127,12 @@ )->(); } +=back + +=head1 EXAMPLE + +Have a look at F for a nontrivial example. + +=cut + 1;