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.12 by root, Tue Aug 29 05:03:55 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.12 2006/08/29 05:03:55 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 */
2550 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op))) 2394 if (INVOKE_OBJECT (APPLY, tmp, ARG_OBJECT (op)))
2551 return RESULT_INT (0); 2395 return RESULT_INT (0);
2552 2396
2553 switch (tmp->type) { 2397 switch (tmp->type) {
2554 2398
2555 case TRANSPORT:
2556 return apply_transport(op, tmp, aflag);
2557
2558 case CF_HANDLE: 2399 case CF_HANDLE:
2559 new_draw_info(NDI_UNIQUE, 0,op,"You turn the handle."); 2400 new_draw_info(NDI_UNIQUE, 0,op,"You turn the handle.");
2560 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);
2561 tmp->value=tmp->value?0:1; 2402 tmp->value=tmp->value?0:1;
2562 SET_ANIMATION(tmp, tmp->value); 2403 SET_ANIMATION(tmp, tmp->value);
2803 2644
2804void player_apply_below (object *pl) 2645void player_apply_below (object *pl)
2805{ 2646{
2806 object *tmp, *next; 2647 object *tmp, *next;
2807 int floors; 2648 int floors;
2808
2809 if (pl->contr->transport && pl->contr->transport->type == TRANSPORT) {
2810 apply_transport(pl, pl->contr->transport, 0);
2811 return;
2812 }
2813 2649
2814 /* 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
2815 * item in the container. Otherwise, use the map. 2651 * item in the container. Otherwise, use the map.
2816 */ 2652 */
2817 tmp = (pl->container != NULL) ? pl->container->inv : pl->below; 2653 tmp = (pl->container != NULL) ? pl->container->inv : pl->below;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines