#! perl # # This file is part of Deliantra, the Roguelike Realtime MMORPG. # # Copyright (©) 2008,2009 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 # =head1 NAME cf::mapscript =head1 DESCRIPTION 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]) } =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 objetc reference is passed), and passes the given state (or C<1>, if missing) to it. =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, $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->set_speed (1); } package cf::mapscript; use common::sense; *{"main::safe::cf::mapscript::eval::"} = \%{"main::cf::mapscript::eval::"}; our %CACHE; sub activate($$$) { package cf::mapscript::eval; ($self, $state, $activator, $originator) = @_; ( $CACHE{$self->msg} ||= cf::safe_eval "package cf::mapscript::eval; sub {\n" . "#line 1 '" . ($self->debug_desc) . "'\n" . $self->msg . "\n}" or sub { } )->(); } =back =head1 EXAMPLE Have a look at F for a nontrivial example. =cut 1;