--- deliantra/server/common/button.C 2009/01/08 03:03:23 1.51
+++ deliantra/server/common/button.C 2009/11/06 13:03:34 1.61
@@ -1,22 +1,23 @@
/*
* This file is part of Deliantra, the Roguelike Realtime MMORPG.
*
- * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
+ * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
* Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
* Copyright (©) 1992,2007 Frank Tore Johansen
*
- * Deliantra is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * 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 GNU General Public License
- * along with this program. If not, see .
+ * 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
*/
@@ -31,10 +32,11 @@
* elmex:
* This function takes a objectlink list with all the objects are going to be activated.
* state is a true/false flag that will actiavte objects that have FLAG_ACTIVATE_ON_PUSH/RELEASE set.
- * The source argument can be 0 or the source object for this activation.
+ * The activator argument can be 0 or the source object for this activation.
+ * the originator is the player or monster who did something.
*/
-void
-activate_connection_link (objectlink *ol, bool state, object *source = 0)
+static void
+activate_connection_link (objectlink *ol, int state, object *activator, object *originator)
{
for (; ol; ol = ol->next)
{
@@ -76,7 +78,7 @@
tmp->set_speed (0.5);
break;
- case CF_HANDLE:
+ case T_HANDLE:
SET_ANIMATION (tmp, (tmp->value = tmp->stats.maxsp ? !state : state));
update_object (tmp, UP_OBJ_FACE);
break;
@@ -84,8 +86,13 @@
case SIGN:
if (!tmp->stats.food || tmp->last_eat < tmp->stats.food)
{
- tmp->play_sound (tmp->sound ? tmp->sound : sound_find ("trigger_sign"));
- new_info_map (NDI_UNIQUE | NDI_NAVY, tmp->map, tmp->msg);
+ tmp->play_sound (tmp->sound ? tmp->sound : sound_find ("msg_voice"));
+
+ if (originator && originator->contr)
+ originator->contr->infobox (MSG_CHANNEL ("examine"), format ("T<%s>\n\n%s", &tmp->name, &tmp->msg));
+
+ new_info_map_except (NDI_UNIQUE | NDI_NAVY, tmp->map, originator, tmp->msg);
+
if (tmp->stats.food)
tmp->last_eat++;
}
@@ -107,7 +114,7 @@
break;
case MOOD_FLOOR:
- do_mood_floor (tmp, source);
+ do_mood_floor (tmp, activator);
break;
case TIMED_GATE:
@@ -136,9 +143,7 @@
move_firewall (tmp);
else
{
- if ((tmp->stats.sp += tmp->stats.maxsp) > 8) /* next direction */
- tmp->stats.sp = ((tmp->stats.sp - 1) % 8) + 1;
-
+ tmp->stats.sp = absdir (tmp->stats.sp + tmp->stats.maxsp); /* next direction */
animate_turning (tmp);
}
break;
@@ -161,7 +166,7 @@
break;
case MAPSCRIPT:
- cfperl_mapscript_activate (tmp, source, state);
+ cfperl_mapscript_activate (tmp, state, activator, originator);
break;
}
}
@@ -180,14 +185,14 @@
*
*/
void
-push_button (object *op)
+push_button (object *op, object *originator)
{
if (oblinkpt *obp = op->find_link ())
{
- if (INVOKE_MAP (TRIGGER, op->map, ARG_STRING (&obp->id), ARG_INT (op->value)))
+ if (INVOKE_MAP (TRIGGER, op->map, ARG_STRING (&obp->id), ARG_INT (op->value), ARG_OBJECT (op), ARG_OBJECT (originator)))
return;
- activate_connection_link (obp->link, op->value, op);
+ activate_connection_link (obp->link, op->value, op, originator);
}
}
@@ -200,13 +205,13 @@
*
*/
void
-maptile::trigger (shstr_tmp id, bool state, object *originator)
+maptile::trigger (shstr_tmp id, int state, object *activator, object *originator)
{
if (INVOKE_MAP (TRIGGER, this, ARG_STRING (&id), ARG_INT (state), ARG_OBJECT (originator)))
return;
if (oblinkpt *obp = find_link (id))
- activate_connection_link (obp->link, state, originator);
+ activate_connection_link (obp->link, state, activator, originator);
}
/*
@@ -216,7 +221,7 @@
* button reacts to the (eventual) change of state.
*/
void
-update_button (object *op)
+update_button (object *op, object *originator)
{
int any_down = 0, old_value = op->value;
@@ -251,6 +256,7 @@
}
else if (tmp->type == PEDESTAL)
{
+ bool is_match = is_match_expr (tmp->slaying);
tmp->value = 0;
for (object *ab = tmp->above; ab; ab = ab->above)
@@ -258,11 +264,35 @@
object *head = ab->head_ ();
/* Same note regarding move_type for buttons above apply here. */
- if (((ab->move_type & tmp->move_on) || ab->move_type == 0)
- && (head->race == tmp->slaying
- || (head->type == SPECIAL_KEY && head->slaying == tmp->slaying)
- || (tmp->slaying == shstr_player && head->type == PLAYER)))
- tmp->value = 1;
+ if (((ab->move_type & tmp->move_on) || ab->move_type == 0))
+ if (is_match
+ ? match (tmp->slaying, head, tmp, originator)
+ : (head->race == tmp->slaying
+ || (head->type == SPECIAL_KEY && head->slaying == tmp->slaying)
+ || (tmp->slaying == shstr_player && head->type == PLAYER)))
+ {
+ tmp->value = 1;
+ break;
+ }
+ }
+
+ any_down = any_down || tmp->value;
+ }
+ else if (tmp->type == T_MATCH)
+ {
+ tmp->value = 0;
+
+ for (object *ab = tmp->above; ab; ab = ab->above)
+ {
+ object *head = ab->head_ ();
+
+ /* Same note regarding move_type for buttons above apply here. */
+ if (((ab->move_type & tmp->move_on) || ab->move_type == 0))
+ if (match (tmp->slaying, head, tmp, originator))
+ {
+ tmp->value = 1;
+ break;
+ }
}
any_down = any_down || tmp->value;
@@ -279,16 +309,17 @@
{
SET_ANIMATION (op, op->value);
update_object (op, UP_OBJ_FACE);
- push_button (op); /* Make all other buttons the same */
+ push_button (op, originator); /* Make all other buttons the same */
}
}
void
-use_trigger (object *op)
+use_trigger (object *op, object *originator)
{
/* Toggle value */
op->value = !op->value;
- push_button (op);
+
+ push_button (op, originator);
}
/*
@@ -319,8 +350,14 @@
*/
int
-check_altar_sacrifice (const object *altar, const object *sacrifice)
+check_altar_sacrifice (object *altar, object *sacrifice, object *originator)
{
+ if (sacrifice->flag [FLAG_UNPAID])
+ return 0;
+
+ if (is_match_expr (ARCH_SACRIFICE (altar)))
+ return match (ARCH_SACRIFICE (altar), altar, originator);
+
if (!QUERY_FLAG (sacrifice, FLAG_ALIVE)
&& !QUERY_FLAG (sacrifice, FLAG_IS_LINKED)
&& sacrifice->type != PLAYER)
@@ -351,7 +388,7 @@
* remaining sacrifice, or is set to NULL if the sacrifice was used up.
*/
int
-operate_altar (object *altar, object **sacrifice)
+operate_altar (object *altar, object **sacrifice, object *originator)
{
if (!altar->map)
{
@@ -362,7 +399,7 @@
if (!altar->slaying || altar->value)
return 0;
- if (!check_altar_sacrifice (altar, *sacrifice))
+ if (!check_altar_sacrifice (altar, *sacrifice, originator))
return 0;
/* check_altar_sacrifice should have already verified that enough money
@@ -389,19 +426,20 @@
return 1;
}
-void
-trigger_move (object *op, int state) /* 1 down and 0 up */
+static void
+trigger_move (object *op, int state, object *originator) /* 1 down and 0 up */
{
op->stats.wc = state;
+
if (state)
{
- use_trigger (op);
+ use_trigger (op, originator);
op->set_speed (op->stats.exp > 0 ? 1. / op->stats.exp : 1.);
op->speed_left = -1;
}
else
{
- use_trigger (op);
+ use_trigger (op, originator);
op->set_speed (0);
}
}
@@ -420,7 +458,7 @@
* TRIGGER_BUTTON, TRIGGER_PEDESTAL: Returns 0.
*/
int
-check_trigger (object *op, object *cause)
+check_trigger (object *op, object *cause, object *originator)
{
object *tmp;
int push = 0, tot = 0;
@@ -460,7 +498,8 @@
if (in_movement || !push)
return 0;
}
- trigger_move (op, push);
+
+ trigger_move (op, push, cause);
}
return 0;
@@ -498,7 +537,7 @@
return 0;
}
- trigger_move (op, push);
+ trigger_move (op, push, cause);
return 0;
case TRIGGER_ALTAR:
@@ -507,7 +546,7 @@
if (in_movement)
return 0;
- if (operate_altar (op, &cause))
+ if (operate_altar (op, &cause)) /* TODO: originator? */
{
if (NUM_ANIMATIONS (op) > 1)
{
@@ -517,7 +556,8 @@
if (op->last_sp >= 0)
{
- trigger_move (op, 1);
+ trigger_move (op, 1, cause);
+
if (op->last_sp > 0)
op->last_sp = -op->last_sp;
}
@@ -527,7 +567,7 @@
* status (-> +/- value) is "simulated":
*/
op->value = !op->value;
- trigger_move (op, 1);
+ trigger_move (op, 1, cause);
op->last_sp = -op->last_sp;
op->value = !op->value;
}
@@ -551,7 +591,7 @@
* pushed twice: First by sacrifice, second by reset! -AV
*/
if (!op->last_sp)
- trigger_move (op, 0);
+ trigger_move (op, 0, cause);
else
{
op->stats.wc = 0;
@@ -576,7 +616,7 @@
update_object (op, UP_OBJ_FACE);
}
- trigger_move (op, push);
+ trigger_move (op, push, cause);
return 1;
default:
@@ -667,7 +707,7 @@
if (ol->ob->type == BUTTON || ol->ob->type == PEDESTAL)
{
- update_button (ol->ob);
+ update_button (ol->ob, 0);
break;
}
}
@@ -882,12 +922,12 @@
match->decrease ();
trig->value = (pl == op ? 1 : 0); // 1 if matching player entered, and 0 if he left
- push_button (trig);
+ push_button (trig, op);
}
else if (!match && !trig->last_sp) // match == not having
{
trig->value = (pl == op ? 1 : 0); // 1 if matching player entered, and 0 if he left
- push_button (trig);
+ push_button (trig, op);
}
}