ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/apply.C
(Generate patch)

Comparing deliantra/server/server/apply.C (file contents):
Revision 1.9 by root, Fri Aug 25 17:11:53 2006 UTC vs.
Revision 1.13 by root, Tue Aug 29 07:34:00 2006 UTC

1/* 1/*
2 * static char *rcsid_apply_c = 2 * static char *rcsid_apply_c =
3 * "$Id: apply.C,v 1.9 2006/08/25 17:11:53 root Exp $"; 3 * "$Id: apply.C,v 1.13 2006/08/29 07:34:00 root Exp $";
4 */ 4 */
5/* 5/*
6 CrossFire, A Multiplayer game for X-windows 6 CrossFire, A Multiplayer game for X-windows
7 7
8 Copyright (C) 2001 Mark Wedel & Crossfire Development Team 8 Copyright (C) 2001 Mark Wedel & Crossfire Development Team
38/* Want this regardless of rplay. */ 38/* Want this regardless of rplay. */
39#include <sounds.h> 39#include <sounds.h>
40 40
41/* need math lib for double-precision and pow() in dragon_eat_flesh() */ 41/* need math lib for double-precision and pow() in dragon_eat_flesh() */
42#include <math.h> 42#include <math.h>
43
44/* Can transport hold object op?
45 * This is a pretty trivial function,
46 * but in the future, possible transport may have more restrictions
47 * or weight reduction like containers
48 */
49int transport_can_hold(const object *transport, const object *op, int nrof)
50{
51 if ((op->weight *nrof + transport->carrying) > transport->weight_limit)
52 return 0;
53 else
54 return 1;
55}
56
57
58/*
59 * Player is trying to use a transport. This returns same values as
60 * manual_apply() does. This function basically checks to see if
61 * the player can use the transport, and if so, sets up the appropriate
62 * pointers.
63 */
64int apply_transport(object *pl, object *transport, int aflag) {
65
66 /* Only players can use transports right now */
67 if (pl->type != PLAYER) return 0;
68
69 // due to brokenness of transports disable them until a working alternative
70 // has been found... :(
71 // - elmex
72 new_draw_info (NDI_UNIQUE, 0, pl, "This transport is out of order!");
73 return 1;
74
75 /* If player is currently on a transport but not this transport, they need
76 * to exit first. Perhaps transport to transport transfers should be
77 * allowed.
78 */
79 if (pl->contr->transport && pl->contr->transport != transport) {
80 new_draw_info_format(NDI_UNIQUE, 0, pl,
81 "You must exit %s before you can board %s.",
82 query_name(pl->contr->transport),
83 query_name(transport));
84 return 1;
85 }
86
87 /* player is currently on a transport. This must mean he
88 * wants to exit.
89 */
90 if (pl->contr->transport) {
91 object *old_transport = pl->contr->transport, *inv;
92
93 /* Should we print a message if the player only wants to
94 * apply?
95 */
96 if (aflag & AP_APPLY) return 1;
97 new_draw_info_format(NDI_UNIQUE, 0, pl,
98 "You disembark from %s.",
99 query_name(old_transport));
100 remove_ob(pl);
101 pl->map = old_transport->map;
102 pl->x = old_transport->x;
103 pl->y = old_transport->y;
104 if (pl->contr == old_transport->contr)
105 old_transport->contr = NULL;
106
107 pl->contr->transport = NULL;
108 insert_ob_in_map(pl, pl->map, pl, 0);
109 sum_weight(old_transport);
110
111 /* Possible for more than one player to be using a transport.
112 * if that is the case, we don't want to reset the face, as the
113 * transport is still occupied.
114 */
115 for (inv=old_transport->inv; inv; inv=inv->below)
116 if (inv->type == PLAYER) break;
117 if (!inv) {
118 old_transport->face = old_transport->arch->clone.face;
119 old_transport->animation_id = old_transport->arch->clone.animation_id;
120 }
121 return 1;
122 }
123 else {
124 /* player is trying to board a transport */
125 int pc=0, p_limit;
126 object *inv;
127 const char *kv;
128
129 if (aflag & AP_UNAPPLY) return 1;
130
131 /* Can this transport hold the weight of this player? */
132 if (!transport_can_hold(transport, pl, 1)) {
133 new_draw_info_format(NDI_UNIQUE, 0, pl,
134 "The %s is unable to hold your weight!",
135 query_name(transport));
136 return 1;
137 }
138
139 /* Does this transport have space for more players? */
140 for (inv=transport->inv; inv; inv=inv->below) {
141 if (inv->type == PLAYER) pc++;
142 }
143 kv = get_ob_key_value(transport, "passenger_limit");
144 if (!kv) p_limit=1;
145 else p_limit = atoi(kv);
146 if (pc >= p_limit) {
147 new_draw_info_format(NDI_UNIQUE, 0, pl,
148 "The %s does not have space for any more people",
149 query_name(transport));
150 return 1;
151 }
152
153 /* Everything checks out OK - player can get on the transport */
154 pl->contr->transport = transport;
155 if (!transport->contr) transport->contr = pl->contr;
156 remove_ob(pl);
157 insert_ob_in_ob(pl, transport);
158 sum_weight(transport);
159 pl->map = transport->map;
160 pl->x = transport->x;
161 pl->y = transport->y;
162
163 /* Might need to update face, animation info */
164 if (!pc) {
165 const char *str;
166
167 str = get_ob_key_value(transport, "face_full");
168 if (str)
169 transport->face = &new_faces[FindFace(str,
170 transport->face->number)];
171 str = get_ob_key_value(transport, "anim_full");
172 if (str)
173 transport->animation_id = find_animation(str);
174 }
175
176 /* Does speed of this object change based on weight? */
177 kv = get_ob_key_value(transport, "weight_speed_ratio");
178 if (kv) {
179 int wsr = atoi(kv);
180 float base_speed;
181
182 kv = get_ob_key_value(transport, "base_speed");
183 if (kv) base_speed = atof(kv);
184 else base_speed = transport->arch->clone.speed;
185
186 transport->speed = base_speed - (base_speed * transport->carrying *
187 wsr) / (transport->weight_limit * 100);
188
189 /* Put some limits on min/max speeds */
190 if (transport->speed < 0.10) transport->speed = 0.10;
191 if (transport->speed > 1.0) transport->speed = 1.0;
192 }
193 } /* else if player is boarding the transport */
194
195 return 1;
196}
197
198
199 43
200/** 44/**
201 * Check if op should abort moving victim because of it's race or slaying. 45 * Check if op should abort moving victim because of it's race or slaying.
202 * Returns 1 if it should abort, returns 0 if it should continue. 46 * Returns 1 if it should abort, returns 0 if it should continue.
203 */ 47 */
1291 1135
1292 if (op->container && QUERY_FLAG(sack, FLAG_APPLIED)) { 1136 if (op->container && QUERY_FLAG(sack, FLAG_APPLIED)) {
1293 if (op->container->env != op) { /* if container is on the ground */ 1137 if (op->container->env != op) { /* if container is on the ground */
1294 op->container->move_off = 0; 1138 op->container->move_off = 0;
1295 } 1139 }
1296 /* Lauwenmark: Handle for plugin close event */ 1140
1297 if (execute_event(tmp, EVENT_CLOSE,op,NULL,NULL,SCRIPT_FIX_ALL)!=0) 1141 if (INVOKE_OBJECT (CLOSE, op))
1298 return 1; 1142 return 1;
1299 1143
1300 new_draw_info_format(NDI_UNIQUE, 0, op, "You close %s.", 1144 new_draw_info_format(NDI_UNIQUE, 0, op, "You close %s.",
1301 query_name(op->container)); 1145 query_name(op->container));
1302 CLEAR_FLAG(op->container, FLAG_APPLIED); 1146 CLEAR_FLAG(op->container, FLAG_APPLIED);
1303 op->container=NULL; 1147 op->container=NULL;
1576 return; 1420 return;
1577 } 1421 }
1578 recursion_depth++; 1422 recursion_depth++;
1579 if (trap->head) trap=trap->head; 1423 if (trap->head) trap=trap->head;
1580 1424
1581 /* Lauwenmark: Handle for plugin trigger event */ 1425 if (INVOKE_OBJECT (MOVE_TRIGGER, trap, ARG_OBJECT (victim), ARG_OBJECT (originator)))
1582 if (execute_event(trap, EVENT_TRIGGER,originator,victim,NULL,SCRIPT_FIX_ALL)!=0)
1583 goto leave; 1426 goto leave;
1584 1427
1585 switch (trap->type) { 1428 switch (trap->type) {
1586 case PLAYERMOVER: 1429 case PLAYERMOVER:
1587 if (trap->attacktype && (trap->level || victim->type!=PLAYER) && 1430 if (trap->attacktype && (trap->level || victim->type!=PLAYER) &&
2546 } else { 2389 } else {
2547 return 0; /* monsters just skip unpaid items */ 2390 return 0; /* monsters just skip unpaid items */
2548 } 2391 }
2549 } 2392 }
2550 2393
2551
2552 /* Lauwenmark: Handle for plugin apply event */
2553 //TODO: remove
2554 if (execute_event(tmp, EVENT_APPLY,op,NULL,NULL,SCRIPT_FIX_ALL)!=0)
2555 return 1;
2556
2557 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op))) 2394 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op)))
2558 return 1; 2395 return RESULT_INT (0);
2559 2396
2560 switch (tmp->type) { 2397 switch (tmp->type) {
2561
2562 case TRANSPORT:
2563 return apply_transport(op, tmp, aflag);
2564 2398
2565 case CF_HANDLE: 2399 case CF_HANDLE:
2566 new_draw_info(NDI_UNIQUE, 0,op,"You turn the handle."); 2400 new_draw_info(NDI_UNIQUE, 0,op,"You turn the handle.");
2567 play_sound_map(op->map, op->x, op->y, SOUND_TURN_HANDLE); 2401 play_sound_map(op->map, op->x, op->y, SOUND_TURN_HANDLE);
2568 tmp->value=tmp->value?0:1; 2402 tmp->value=tmp->value?0:1;
2811void player_apply_below (object *pl) 2645void player_apply_below (object *pl)
2812{ 2646{
2813 object *tmp, *next; 2647 object *tmp, *next;
2814 int floors; 2648 int floors;
2815 2649
2816 if (pl->contr->transport && pl->contr->transport->type == TRANSPORT) {
2817 apply_transport(pl, pl->contr->transport, 0);
2818 return;
2819 }
2820
2821 /* If using a container, set the starting item to be the top 2650 /* If using a container, set the starting item to be the top
2822 * item in the container. Otherwise, use the map. 2651 * item in the container. Otherwise, use the map.
2823 */ 2652 */
2824 tmp = (pl->container != NULL) ? pl->container->inv : pl->below; 2653 tmp = (pl->container != NULL) ? pl->container->inv : pl->below;
2825 2654
2856 * Break this out of apply_special - this is just done 2685 * Break this out of apply_special - this is just done
2857 * to keep the size of apply_special to a more managable size. 2686 * to keep the size of apply_special to a more managable size.
2858 */ 2687 */
2859static int unapply_special (object *who, object *op, int aflags) 2688static int unapply_special (object *who, object *op, int aflags)
2860{ 2689{
2690 if (INVOKE_OBJECT (BE_UNREADY, op, ARG_OBJECT (who), ARG_INT (aflags))
2691 || INVOKE_OBJECT (UNREADY, who, ARG_OBJECT (op), ARG_INT (aflags)))
2692 return RESULT_INT (0);
2693
2861 object *tmp2; 2694 object *tmp2;
2862 2695
2863 CLEAR_FLAG(op, FLAG_APPLIED); 2696 CLEAR_FLAG(op, FLAG_APPLIED);
2864 switch(op->type) { 2697 switch(op->type) {
2865 case WEAPON: 2698 case WEAPON:
2866 new_draw_info_format(NDI_UNIQUE, 0, who, "You unwield %s.",query_name(op)); 2699 new_draw_info_format(NDI_UNIQUE, 0, who, "You unwield %s.",query_name(op));
2867 2700
2868 (void) change_abil (who,op); 2701 (void) change_abil (who,op);
2869 if(QUERY_FLAG(who,FLAG_READY_WEAPON)) 2702 if(QUERY_FLAG(who,FLAG_READY_WEAPON))
2870 CLEAR_FLAG(who,FLAG_READY_WEAPON); 2703 CLEAR_FLAG(who,FLAG_READY_WEAPON);
2871 /* GROS: update the current_weapon_script field (used with script_attack for weapons) */
2872 who->current_weapon_script = NULL;
2873 who->current_weapon = NULL;
2874 clear_skill(who); 2704 clear_skill(who);
2875 break; 2705 break;
2876 2706
2877 case SKILL: /* allows objects to impart skills */ 2707 case SKILL: /* allows objects to impart skills */
2878 case SKILL_TOOL: 2708 case SKILL_TOOL:
3113 * See include/define.h for detailed description of the meaning of 2943 * See include/define.h for detailed description of the meaning of
3114 * these return values. 2944 * these return values.
3115 */ 2945 */
3116int can_apply_object(object *who, object *op) 2946int can_apply_object(object *who, object *op)
3117{ 2947{
2948 if (INVOKE_OBJECT (CAN_BE_APPLIED, op, ARG_OBJECT (who))
2949 || INVOKE_OBJECT (CAN_APPLY, who, ARG_OBJECT (op)))
2950 return RESULT_INT (0);
2951
3118 int i, retval=0; 2952 int i, retval=0;
3119 object *tmp=NULL, *ws=NULL; 2953 object *tmp=NULL, *ws=NULL;
3120 2954
3121 /* Players have 2 'arm's, so they could in theory equip 2 shields or 2955 /* Players have 2 'arm's, so they could in theory equip 2 shields or
3122 * 2 weapons, but we don't want to let them do that. So if they are 2956 * 2 weapons, but we don't want to let them do that. So if they are
3340 if(op->nrof > 1) 3174 if(op->nrof > 1)
3341 tmp = get_split_ob(op,op->nrof - 1); 3175 tmp = get_split_ob(op,op->nrof - 1);
3342 else 3176 else
3343 tmp = NULL; 3177 tmp = NULL;
3344 3178
3179 if (INVOKE_OBJECT (BE_READY, op, ARG_OBJECT (who))
3180 || INVOKE_OBJECT (READY, who, ARG_OBJECT (op)))
3181 return RESULT_INT (0);
3182
3345 switch(op->type) { 3183 switch(op->type) {
3346 case WEAPON: 3184 case WEAPON:
3347 if (!check_weapon_power(who, op->last_eat)) { 3185 if (!check_weapon_power(who, op->last_eat)) {
3348 new_draw_info(NDI_UNIQUE, 0,who, 3186 new_draw_info(NDI_UNIQUE, 0,who,
3349 "That weapon is too powerful for you to use."); 3187 "That weapon is too powerful for you to use.");
3367 SET_FLAG(who, FLAG_READY_WEAPON); 3205 SET_FLAG(who, FLAG_READY_WEAPON);
3368 3206
3369 new_draw_info_format(NDI_UNIQUE, 0, who, "You wield %s.",query_name(op)); 3207 new_draw_info_format(NDI_UNIQUE, 0, who, "You wield %s.",query_name(op));
3370 3208
3371 (void) change_abil (who,op); 3209 (void) change_abil (who,op);
3372 /* GROS: update the current_weapon_script field (used with EVENT_ATTACK for weapons) */
3373 /*if ((evt = find_event(op, EVENT_ATTACK)) != NULL) {
3374 LOG(llevDebug, "Scripting Weapon wielded\n");
3375 if (who->current_weapon_script) free_string(who->current_weapon_script);
3376 who->current_weapon_script=add_string(query_name(op));
3377 }
3378 who->current_weapon = op;*/
3379 break; 3210 break;
3380 3211
3381 case ARMOUR: 3212 case ARMOUR:
3382 case HELMET: 3213 case HELMET:
3383 case SHIELD: 3214 case SHIELD:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines