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

Comparing deliantra/server/common/object.C (file contents):
Revision 1.15 by root, Mon Sep 4 13:55:54 2006 UTC vs.
Revision 1.16 by root, Mon Sep 4 16:46:32 2006 UTC

1/* 1/*
2 * static char *rcsid_object_c = 2 * static char *rcsid_object_c =
3 * "$Id: object.C,v 1.15 2006/09/04 13:55:54 root Exp $"; 3 * "$Id: object.C,v 1.16 2006/09/04 16:46:32 root Exp $";
4 */ 4 */
5 5
6/* 6/*
7 CrossFire, A Multiplayer game for X-windows 7 CrossFire, A Multiplayer game for X-windows
8 8
111 * 111 *
112 * Improvements made with merge: Better checking on potion, and also 112 * Improvements made with merge: Better checking on potion, and also
113 * check weight 113 * check weight
114 */ 114 */
115 115
116int CAN_MERGE(object *ob1, object *ob2) { 116bool
117 117object::can_merge (object *ob1, object *ob2)
118{
118 /* A couple quicksanity checks */ 119 /* A couple quicksanity checks */
119 if ((ob1 == ob2) || (ob1->type != ob2->type)) return 0; 120 if ((ob1 == ob2) || (ob1->type != ob2->type))
120
121 if (ob1->speed != ob2->speed) return 0;
122 /* Note sure why the following is the case - either the object has to
123 * be animated or have a very low speed. Is this an attempted monster
124 * check?
125 */
126 if (!QUERY_FLAG(ob1,FLAG_ANIMATE) && FABS((ob1)->speed) > MIN_ACTIVE_SPEED)
127 return 0; 121 return 0;
128 122
123 if (ob1->speed != ob2->speed)
124 return 0;
125
129 /* Do not merge objects if nrof would overflow. We use 1UL<<31 since that 126 /* Do not merge objects if nrof would overflow. We use 1UL<<31 since that
130 * value could not be stored in a sint32 (which unfortunately sometimes is 127 * value could not be stored in a sint32 (which unfortunately sometimes is
131 * used to store nrof). 128 * used to store nrof).
132 */ 129 */
133 if (ob1->nrof+ob2->nrof >= 1UL<<31) 130 if (ob1->nrof + ob2->nrof >= 1UL << 31)
134 return 0; 131 return 0;
135 132
133 /* If the objects have been identified, set the BEEN_APPLIED flag.
134 * This is to the comparison of the flags below will be OK. We
135 * just can't ignore the been applied or identified flags, as they
136 * are not equal - just if it has been identified, the been_applied
137 * flags lose any meaning.
138 */
139 if (QUERY_FLAG (ob1, FLAG_IDENTIFIED))
140 SET_FLAG (ob1, FLAG_BEEN_APPLIED);
141
142 if (QUERY_FLAG (ob2, FLAG_IDENTIFIED))
143 SET_FLAG (ob2, FLAG_BEEN_APPLIED);
144
145
146 /* the 0x400000 on flags2 is FLAG_INV_LOCK. I don't think something
147 * being locked in inventory should prevent merging.
148 * 0x4 in flags3 is CLIENT_SENT
149 */
150 if ((ob1->arch != ob2->arch) ||
151 (ob1->flags[0] != ob2->flags[0]) ||
152 (ob1->flags[1] != ob2->flags[1]) ||
153 ((ob1->flags[2] & ~0x400000) != (ob2->flags[2] & ~0x400000)) ||
154 ((ob1->flags[3] & ~0x4) != (ob2->flags[3] & ~0x4)) ||
155 (ob1->name != ob2->name) ||
156 (ob1->title != ob2->title) ||
157 (ob1->msg != ob2->msg) ||
158 (ob1->weight != ob2->weight) ||
159 (memcmp (&ob1->resist, &ob2->resist, sizeof (ob1->resist)) != 0) ||
160 (memcmp (&ob1->stats, &ob2->stats, sizeof (ob1->stats)) != 0) ||
161 (ob1->attacktype != ob2->attacktype) ||
162 (ob1->magic != ob2->magic) ||
163 (ob1->slaying != ob2->slaying) ||
164 (ob1->skill != ob2->skill) ||
165 (ob1->value != ob2->value) ||
166 (ob1->animation_id != ob2->animation_id) ||
167 (ob1->client_type != ob2->client_type) ||
168 (ob1->materialname != ob2->materialname) ||
169 (ob1->lore != ob2->lore) ||
170 (ob1->subtype != ob2->subtype) ||
171 (ob1->move_type != ob2->move_type) ||
172 (ob1->move_block != ob2->move_block) ||
173 (ob1->move_allow != ob2->move_allow) ||
174 (ob1->move_on != ob2->move_on) ||
175 (ob1->move_off != ob2->move_off) ||
176 (ob1->move_slow != ob2->move_slow) ||
177 (ob1->move_slow_penalty != ob2->move_slow_penalty))
178 return 0;
179
136 /* This is really a spellbook check - really, we should 180 /* This is really a spellbook check - really, we should
137 * check all objects in the inventory. 181 * check all objects in the inventory.
138 */ 182 */
139 if (ob1->inv || ob2->inv) { 183 if (ob1->inv || ob2->inv)
184 {
140 /* if one object has inventory but the other doesn't, not equiv */ 185 /* if one object has inventory but the other doesn't, not equiv */
141 if ((ob1->inv && !ob2->inv) || (ob2->inv && !ob1->inv)) return 0; 186 if ((ob1->inv && !ob2->inv) || (ob2->inv && !ob1->inv))
187 return 0;
142 188
143 /* Now check to see if the two inventory objects could merge */ 189 /* Now check to see if the two inventory objects could merge */
144 if (!CAN_MERGE(ob1->inv, ob2->inv)) return 0; 190 if (!CAN_MERGE (ob1->inv, ob2->inv))
191 return 0;
145 192
146 /* inventory ok - still need to check rest of this object to see 193 /* inventory ok - still need to check rest of this object to see
147 * if it is valid. 194 * if it is valid.
148 */ 195 */
149 } 196 }
150 197
151 /* If the objects have been identified, set the BEEN_APPLIED flag.
152 * This is to the comparison of the flags below will be OK. We
153 * just can't ignore the been applied or identified flags, as they
154 * are not equal - just if it has been identified, the been_applied
155 * flags lose any meaning.
156 */
157 if (QUERY_FLAG(ob1, FLAG_IDENTIFIED))
158 SET_FLAG(ob1, FLAG_BEEN_APPLIED);
159
160 if (QUERY_FLAG(ob2, FLAG_IDENTIFIED))
161 SET_FLAG(ob2, FLAG_BEEN_APPLIED);
162
163
164 /* the 0x400000 on flags2 is FLAG_INV_LOCK. I don't think something
165 * being locked in inventory should prevent merging.
166 * 0x4 in flags3 is CLIENT_SENT
167 */
168 if ((ob1->arch != ob2->arch) ||
169 (ob1->flags[0] != ob2->flags[0]) ||
170 (ob1->flags[1] != ob2->flags[1]) ||
171 ((ob1->flags[2] & ~0x400000) != (ob2->flags[2] & ~ 0x400000)) ||
172 ((ob1->flags[3] & ~0x4) != (ob2->flags[3] & ~0x4)) ||
173 (ob1->name != ob2->name) ||
174 (ob1->title != ob2->title) ||
175 (ob1->msg != ob2->msg) ||
176 (ob1->weight != ob2->weight) ||
177 (memcmp(&ob1->resist, &ob2->resist, sizeof(ob1->resist))!=0) ||
178 (memcmp(&ob1->stats, &ob2->stats, sizeof(ob1->stats))!=0) ||
179 (ob1->attacktype != ob2->attacktype) ||
180 (ob1->magic != ob2->magic) ||
181 (ob1->slaying != ob2->slaying) ||
182 (ob1->skill != ob2->skill) ||
183 (ob1->value != ob2->value) ||
184 (ob1->animation_id != ob2->animation_id) ||
185 (ob1->client_type != ob2->client_type) ||
186 (ob1->materialname != ob2->materialname) ||
187 (ob1->lore != ob2->lore) ||
188 (ob1->subtype != ob2->subtype) ||
189 (ob1->move_type != ob2->move_type) ||
190 (ob1->move_block != ob2->move_block) ||
191 (ob1->move_allow != ob2->move_allow) ||
192 (ob1->move_on != ob2->move_on) ||
193 (ob1->move_off != ob2->move_off) ||
194 (ob1->move_slow != ob2->move_slow) ||
195 (ob1->move_slow_penalty != ob2->move_slow_penalty)
196 )
197 return 0;
198
199 /* Don't merge objects that are applied. With the new 'body' code, 198 /* Don't merge objects that are applied. With the new 'body' code,
200 * it is possible for most any character to have more than one of 199 * it is possible for most any character to have more than one of
201 * some items equipped, and we don't want those to merge. 200 * some items equipped, and we don't want those to merge.
202 */ 201 */
203 if (QUERY_FLAG(ob1, FLAG_APPLIED) || QUERY_FLAG(ob2, FLAG_APPLIED)) 202 if (QUERY_FLAG (ob1, FLAG_APPLIED) || QUERY_FLAG (ob2, FLAG_APPLIED))
204 return 0; 203 return 0;
205 204
205 /* Note sure why the following is the case - either the object has to
206 * be animated or have a very low speed. Is this an attempted monster
207 * check?
208 */
209 if (!QUERY_FLAG (ob1, FLAG_ANIMATE)
210 && FABS ((ob1)->speed) > MIN_ACTIVE_SPEED)
211 return 0;
212
206 switch (ob1->type) { 213 switch (ob1->type)
214 {
207 case SCROLL: 215 case SCROLL:
208 if (ob1->level != ob2->level) return 0; 216 if (ob1->level != ob2->level)
217 return 0;
209 break; 218 break;
210
211 } 219 }
220
212 if (ob1->key_values != NULL || ob2->key_values != NULL) { 221 if (ob1->key_values != NULL || ob2->key_values != NULL)
222 {
213 /* At least one of these has key_values. */ 223 /* At least one of these has key_values. */
214 if ((ob1->key_values == NULL) != (ob2->key_values == NULL)) { 224 if ((ob1->key_values == NULL) != (ob2->key_values == NULL))
215 /* One has fields, but the other one doesn't. */ 225 /* One has fields, but the other one doesn't. */
216 return 0; 226 return 0;
217 } else if (!compare_ob_value_lists(ob1, ob2)) { 227 else if (!compare_ob_value_lists (ob1, ob2))
218 return 0; 228 return 0;
219 } 229 }
230
231 //TODO: generate an event or call into perl for additional checks
232 if (ob1->self || ob2->self)
220 } 233 {
234 ob1->optimise ();
235 ob2->optimise ();
221 236
237 if (ob1->self || ob2->self)
238 return 0;
239 }
240
222 /* Everything passes, must be OK. */ 241 /* Everything passes, must be OK. */
223 return 1; 242 return 1;
224} 243}
225
226/* 244/*
227 * sum_weight() is a recursive function which calculates the weight 245 * sum_weight() is a recursive function which calculates the weight
228 * an object is carrying. It goes through in figures out how much 246 * an object is carrying. It goes through in figures out how much
229 * containers are carrying, and sums it up. 247 * containers are carrying, and sums it up.
230 */ 248 */

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines