· 4 years ago · Mar 06, 2021, 02:18 AM
1void bioex_combine(player_data* p)
2{
3 struct item_data* bioex1 = nullptr;
4 struct item_data* bioex2 = nullptr;
5 struct item_data* stone = nullptr;
6 struct item_data* cls = nullptr;
7
8 std::string text = "";
9
10 int total = 0;
11
12 for (int i = 0; i < MAX_COMBINE; i++) {
13 if (p->combine_item[i] != nullptr) {
14 if (p->combine_item[i]->type == ITEM_BIOEX) {
15 if (bioex1 == nullptr)
16 bioex1 = p->combine_item[i];
17 else
18 bioex2 = p->combine_item[i];
19 }
20 else if (p->combine_item[i]->type == ITEM_ENCHANT) {
21 stone = p->combine_item[i];
22 }
23 else if (p->combine_item[i]->type == ITEM_CLS)
24 {
25 cls = p->combine_item[i];
26 }
27 total += p->combine_quant[i]; // add up items
28 }
29 }
30
31 // warnings of missing items
32 if (bioex1 == nullptr || bioex2 == nullptr)
33 {
34 text = "A minimum of 2 Bio-Ex items must be used, 1 in each slot. Stone and Class are optional";
35
36 if (!p->test_fab) {
37 out_text(p->desc, const_cast<char*>(text.c_str()));
38 clear_players_combine(p);
39 return;
40 }
41 out_combine_string(p->desc, FAB_BIOEX_COMBINE, const_cast<char*>(text.c_str()));
42 return;
43
44 }
45
46 //check levels of Bio-Ex are within 20%
47
48 int bioex1Level = get_max_system_level(bioex1);
49 int bioex2Level = get_max_system_level(bioex2);
50
51 if (bioex1Level < 1)
52 bioex1Level = 1;
53 if (bioex2Level < 1)
54 bioex2Level = 1;
55
56 int maxLevel = 120 * bioex1Level / 100;
57 int minLevel = 80 * bioex1Level / 100;
58
59 if (80 * bioex1Level / 100 == bioex1Level)
60 --minLevel;
61 if (maxLevel == bioex1Level)
62 ++maxLevel;
63
64 int pass = 0;
65
66 if (bioex2Level >= minLevel && bioex2Level <= maxLevel)
67 {
68 pass = 1;
69 }
70 // now check other way
71 if (pass != 1)
72 {
73 pass = 0;
74 maxLevel = 120 * bioex2Level / 100;
75 minLevel = 80 * bioex2Level / 100;
76
77 if (80 * bioex2Level / 100 == bioex2Level)
78 --minLevel;
79 if (maxLevel == bioex2Level)
80 ++maxLevel;
81 if (bioex1Level >= minLevel && bioex1Level <= maxLevel)
82 {
83 pass = 1;
84 }
85 }
86
87 if (pass != 1)
88 {
89 text = "Bio-Ex levels must be within 20% of each other";
90
91 if (!p->test_fab) {
92 out_text(p->desc, const_cast<char*>(text.c_str()));
93 clear_players_combine(p);
94 return;
95 }
96 out_combine_string(p->desc, FAB_BIOEX_COMBINE, const_cast<char*>(text.c_str()));
97 return;
98 }
99
100
101
102 // guess we have 2 valid bioex now
103 //need to check target level
104 bioex1Level *= 1.1F;
105 bioex2Level *= 1.1F;
106
107 // max level
108 int maxBioexLevel = static_cast<int>(bioex1Level);
109 if (bioex2Level > bioex1Level)
110 maxBioexLevel = static_cast<int>(bioex2Level);
111
112 // min level
113 int minBioexLevel = static_cast<int>(bioex1Level);
114 if (bioex2Level < bioex1Level)
115 minBioexLevel = static_cast<int>(bioex2Level);
116
117 if(minBioexLevel > 1)
118 minBioexLevel /= 2;
119
120 //store attributes used, and add a chance of it being in final item
121 int attributes[MAX_SYSTEM_ATTRIBUTES + 1];
122 for (int i = 0; i < MAX_SYSTEM_ATTRIBUTES + 1; ++i)
123 {
124 attributes[i] = 0;
125 }
126
127 //go over bio-ex slots, and give a 50% chance for any matching
128 // can also add up how many slots are being used on each bioex
129
130 int bioex1MaxSlots = 0;
131 int bioex2MaxSlots = 0;
132
133 //bioex 1
134 if (bioex1->num2 != NULL)
135 {
136 attributes[bioex1->num1] += 50;
137 ++bioex1MaxSlots;
138 }
139 if (bioex1->num4 != NULL)
140 {
141 attributes[bioex1->num3] += 50;
142 ++bioex1MaxSlots;
143 }
144 if (bioex1->num6 != NULL)
145 {
146 attributes[bioex1->num5] += 50;
147 ++bioex1MaxSlots;
148 }
149 if (bioex1->num8 != NULL)
150 {
151 attributes[bioex1->num7] += 50;
152 ++bioex1MaxSlots;
153 }
154
155 //bioex 2
156 if (bioex2->num2 != NULL)
157 {
158 attributes[bioex2->num1] += 50;
159 ++bioex2MaxSlots;
160 }
161 if (bioex2->num4 != NULL)
162 {
163 attributes[bioex2->num3] += 50;
164 ++bioex2MaxSlots;
165 }
166 if (bioex2->num6 != NULL)
167 {
168 attributes[bioex2->num5] += 50;
169 ++bioex2MaxSlots;
170 }
171 if (bioex2->num8 != NULL)
172 {
173 attributes[bioex2->num7] += 50;
174 ++bioex2MaxSlots;
175 }
176
177 auto targetMaxSlots = bioex1MaxSlots;
178 if (bioex2MaxSlots > bioex1MaxSlots)
179 targetMaxSlots = bioex2MaxSlots;
180
181 //if a stone is used, set an override on the cpx checks
182 auto forcedStoneAttribute = 0;
183
184 // now we have our top end level, check stone and class items to see if they are suitable.
185 bool extraSlotStone = false;
186 if (stone != nullptr)
187 {
188 forcedStoneAttribute = get_effected_attribute_from_stone(stone->num1);
189
190 // check the stone can be used here (must be systems based
191 if (stone->num1 <= 2 || stone->num1 >= 17)
192 {
193 text = "This stone type cannot be used here\nUse a stone that can only be applied to system attributes.";
194
195 if (!p->test_fab) {
196 out_text(p->desc, const_cast<char*>(text.c_str()));
197 clear_players_combine(p);
198 return;
199 }
200 out_combine_string(p->desc, FAB_BIOEX_COMBINE, const_cast<char*>(text.c_str()));
201 return;
202 }
203 //check level of stone used
204 if (maxBioexLevel > stone->num3 * 75)
205 {
206 hs_sprintf(buf, MAX_BUF, "This stone is too weak to be used here.\nThe max Bio-Ex level is %d.\nThe stone only covers levels %d to %d.", maxBioexLevel, (stone->num3 - 1) * 75, stone->num3 * 75);
207 text = buf;
208
209 if (!p->test_fab) {
210 out_text(p->desc, const_cast<char*>(text.c_str()));
211 clear_players_combine(p);
212 return;
213 }
214 out_combine_string(p->desc, FAB_BIOEX_COMBINE, const_cast<char*>(text.c_str()));
215 return;
216 }
217 if((stone->num3 - 1) * 75 > maxBioexLevel || stone->num3 * 75 < maxBioexLevel)
218 {
219 hs_sprintf(buf, MAX_BUF, "This stone is too strong to be used here.\nThe max Bio-Ex level is %d.\nThe stone only covers levels %d to %d.", maxBioexLevel, (stone->num3 -1) * 75 , stone->num3 * 75);
220 text = buf;
221
222 if (!p->test_fab) {
223 out_text(p->desc, const_cast<char*>(text.c_str()));
224 clear_players_combine(p);
225 return;
226 }
227 out_combine_string(p->desc, FAB_BIOEX_COMBINE, const_cast<char*>(text.c_str()));
228 return;
229 }
230 // see if we not adding to an existing attribute
231 if (attributes[forcedStoneAttribute] == 0)
232 {
233 extraSlotStone = true;
234 if (targetMaxSlots == 4) // we already maxed slots
235 {
236 //since stone will always add that item attribute, it cant be used if we have 4 slots already
237
238 text = "This stone cannot be used here.\nThe final Bio-Ex item already has the maximum allowed attribute slots used (4).";
239
240 if (!p->test_fab) {
241 out_text(p->desc, const_cast<char*>(text.c_str()));
242 clear_players_combine(p);
243 return;
244 }
245 out_combine_string(p->desc, FAB_BIOEX_COMBINE, const_cast<char*>(text.c_str()));
246 return;
247 }
248 }
249
250 //give 100% chance of attribute based on stone type
251 attributes[forcedStoneAttribute] = 100;
252 }
253 if (cls != nullptr)
254 {
255 //check level of class attribute used
256 if (cls->num2 * 90 < maxBioexLevel)
257 {
258 hs_sprintf(buf, MAX_BUF, "This Artifact is too weak to be used here.\nThe max Bio-Ex level is %d.\nThe attribute only covers up to level %d.", maxBioexLevel, cls->num2 * 90);
259 text = buf;
260
261 if (!p->test_fab) {
262 out_text(p->desc, const_cast<char*>(text.c_str()));
263 clear_players_combine(p);
264 return;
265 }
266 out_combine_string(p->desc, FAB_BIOEX_COMBINE, const_cast<char*>(text.c_str()));
267 return;
268 }
269 }
270
271 //let's start rolling shit to make up the item...
272 int minSlots = bioex1MaxSlots;
273 if (bioex2MaxSlots < minSlots)
274 minSlots = bioex2MaxSlots;
275 int maxSlots = bioex1MaxSlots;
276 if (bioex2MaxSlots > maxSlots)
277 maxSlots = bioex2MaxSlots;
278 // roll how many slots we are going to have
279 if (bioex1MaxSlots == bioex2MaxSlots) // same amoutn of slots? set max
280 targetMaxSlots = bioex1MaxSlots;
281 else {
282 if (bioex1MaxSlots < bioex2MaxSlots)
283 {
284 targetMaxSlots = rand_std() % (bioex1MaxSlots + 1) + (bioex2MaxSlots / 2);
285 }
286 else
287 {
288 targetMaxSlots = rand_std() % (bioex2MaxSlots + 1) + (bioex1MaxSlots / 2);
289 }
290 }
291
292
293 // check to see if we adding a stone slot
294 if (extraSlotStone == true)
295 ++targetMaxSlots;
296
297 // roll a 10% chance of a +1
298 if (targetMaxSlots < 4)//
299 {
300 if (1 + rand_std() % 100 <= 10) // 10 % chance of adding another slot
301 {
302 ++targetMaxSlots;
303 }
304 }
305 int finalLevel = minBioexLevel;
306 // random our level
307 if(maxBioexLevel - minBioexLevel != 0)
308 finalLevel = minBioexLevel + rand_std() % (maxBioexLevel - minBioexLevel);
309
310
311
312 // need to build a table of what attributes we have, and the chance, then roll the chances and delete entry, if we still have empty slots, then pick at random
313
314 struct attribute_pair {
315 attribute_pair(int chance, int att) : chance(chance), attribute(att) {}
316 int chance;
317 int attribute;
318 };
319 struct item_slot {
320 item_slot(int attributeType, int attributeValue) : attributeType(attributeType), attributeValue(attributeValue) {}
321 int attributeType;
322 int attributeValue;
323 };
324
325 std::vector<attribute_pair> attributeList;
326 for (int i = 0; i < MAX_SYSTEM_ATTRIBUTES + 1; i++)
327 {
328
329 if (attributes[i] != 0)
330 {
331 attributeList.emplace_back(attribute_pair(attributes[i], i));
332 }
333 }
334
335 std::vector<item_slot> finalItemSlots;
336 int slotsUsed = 0;
337
338 auto it = attributeList.begin();
339
340 while (it != attributeList.end())
341 {
342 if (slotsUsed < targetMaxSlots)
343 {
344 if (it->chance == 100)
345 {
346 finalItemSlots.emplace_back(item_slot(it->attribute, 0));
347 it = attributeList.erase(it);
348 ++slotsUsed;
349 }
350 else
351 ++it;
352 }
353 else // slots used
354 break;
355 }
356
357 //any that are 100% must be used and removed first.
358
359 while (static_cast<int>(finalItemSlots.size()) != targetMaxSlots && static_cast<int>(finalItemSlots.size()) <= 4)
360 {
361 int targetAttribute;
362
363 while (attributeList.empty() == false && static_cast<int>(finalItemSlots.size()) < targetMaxSlots)
364 {
365
366 targetAttribute = rand_std() % attributeList.size();
367
368 if (1 + rand_std() % 100 <= attributeList[targetAttribute].chance)
369 {
370 finalItemSlots.emplace_back(item_slot(attributeList[targetAttribute].attribute, 0));
371 }
372
373 attributeList.erase(attributeList.begin() + targetAttribute);
374 }
375
376
377 if (static_cast<int>(finalItemSlots.size()) != targetMaxSlots && static_cast<int>(finalItemSlots.size()) <= 4)
378 {
379 pass = 0;
380 while (pass == 0) { // this should find a valid attribute
381 targetAttribute = 1 + rand_std() % MAX_SYSTEM_ATTRIBUTES + 1;
382 while (targetAttribute == SYSTEM_CLOAK)
383 {
384 targetAttribute = 1 + rand_std() % MAX_SYSTEM_ATTRIBUTES + 1;
385 }// no cloak stat !
386 pass = 1;
387 for (auto& finalItemSlot : finalItemSlots)
388 if (targetAttribute == finalItemSlot.attributeType)//check stat not used before
389 pass = 0;
390 if (fab_powers[targetAttribute - 1][14] <= 0.0001) // check attribute is allowed in the slot
391 pass = 0;
392 //int cpx = get_system_level_fab(9, targetAttribute, 1);
393 if (get_system_level_fab(9, targetAttribute, 1) > finalLevel + 10) // make sure adding just 1 to value doesn't result in a highewre cpx than allowed
394 pass = 0;
395 }
396
397 finalItemSlots.emplace_back(item_slot(targetAttribute, 0));
398 }
399
400 }
401
402 // attributes now picked..
403 // time to get some values
404
405 bool stoneApplied = false;
406
407
408 for (auto& it : finalItemSlots)
409 {
410 int pass = 0;
411 while (pass == 0)
412 {
413 double baseValue = (fab_powers[it.attributeType - 1][14] * ((static_cast<double>(finalLevel / 8.0)) + 1.0)) /2.0;
414
415 if (baseValue < 1.0)
416 baseValue = 1.0;
417
418 int value = static_cast<int>(baseValue);
419
420 it.attributeValue = (rand_std() % value) + value;
421
422 if (it.attributeValue > 24)
423 {
424 value = it.attributeValue / 5;
425 it.attributeValue = (value + 1) * 5;
426 if (it.attributeValue < 1)
427 it.attributeValue = 1;
428 }
429 //get level
430 int cpx = get_system_level_fab(9, it.attributeType, it.attributeValue);
431
432 // check level is in range or stone is being used, or value == 1( in the case of value == 1, the CPX might be way ovewr the target cpx and will loop)
433 if (cpx <= finalLevel + 10 || forcedStoneAttribute == it.attributeType || it.attributeValue == 1)
434 {
435 pass = 1;
436 if (stone != nullptr && cls != nullptr) {
437
438 // if stone AND class artifact used, max stats to top level
439 int count = 0;
440 // grab a copy of our values
441 int maxedValue = it.attributeValue;
442
443 while (count < 800)
444 {
445 if (static_cast<float>(cpx) < (static_cast<float>(maxBioexLevel) - (static_cast<float>(maxBioexLevel) / 10.0f))
446 || static_cast<float>(cpx) > (static_cast<float>(maxBioexLevel) + (static_cast<float>(maxBioexLevel) / 10.0f)))
447 {
448
449 ++count;
450
451 cpx = get_system_level_fab(9, it.attributeType, maxedValue);
452
453 if (static_cast<float>(cpx) < static_cast<float>(maxBioexLevel) - (static_cast<float>(maxBioexLevel) / 10.0f)) {
454 if (it.attributeType == 1) maxedValue += 5; // shields need a larger increment
455 else maxedValue++;
456 }
457 if (static_cast<float>(cpx) > static_cast<float>(maxBioexLevel) + (static_cast<float>(maxBioexLevel) / 10.0f)) {
458 if (it.attributeType == 1) maxedValue -= 5;
459 else maxedValue--;
460 break; // we've gone over the cpx allowed, break out of loop
461 }
462 }
463
464 else
465 break;
466 }
467 if (count < 800)
468 {
469 it.attributeValue = maxedValue;
470 }
471 }
472 // apply stone
473 if (stone != nullptr)
474 {
475 if (forcedStoneAttribute == it.attributeType)
476 {
477 it.attributeValue += stone->num2 / 3;
478 stoneApplied = true;
479 }
480 }
481 }
482 }
483 }
484
485 // check if stone not applied, make new slot
486 if (stoneApplied == false && stone != nullptr)
487 {
488 auto amount = stone->num2 / 3;
489 if (amount <= 0)
490 amount = 1;
491 finalItemSlots.emplace_back(item_slot(forcedStoneAttribute, static_cast<int>(amount)));
492 }
493
494 //time to deal with class
495
496 auto classSlot = item_slot(0, 0);
497 if (cls != nullptr) // give class no matter what
498 {
499 classSlot.attributeType = cls->num1;
500 classSlot.attributeValue = cls->num2;
501 }
502 else// no class artifact
503 {
504 if (targetMaxSlots == 5) { // only if class is allowed
505 // check if both bioex have same class
506 if (bioex1->num10 == bioex2->num10 && bioex1->num11 != 0 && bioex2->num11 != 0)
507 {
508 classSlot.attributeType = bioex1->num10;
509 classSlot.attributeValue = finalLevel / 90;
510 }
511 else {
512
513 //check existing bioex to see if either has a class
514 auto bioexClass1 = item_slot(0, 0);
515 auto bioexClass2 = item_slot(0, 0);
516 int randType = 0;
517
518 if (bioex1->num11 != 0)
519 {
520 bioexClass1.attributeType = bioex1->num10;
521 bioexClass1.attributeValue = finalLevel / 90;
522 randType = 1;
523
524 }
525 if (bioex2->num11 != 0)
526 {
527 bioexClass2.attributeType = bioex2->num10;
528 bioexClass2.attributeValue = finalLevel / 90;
529 if (randType == 1)
530 randType = 3;
531 else
532 randType = 2;
533 }
534
535 switch (randType)
536 {
537 case 1:
538 // random 50%
539 if (1 + rand_std() % 100 <= 50)
540 {
541 classSlot = bioexClass1;
542 }
543 break;
544 case 2:
545 // random 50%
546 if (1 + rand_std() % 100 <= 50)
547 {
548 classSlot = bioexClass2;
549 }
550 break;
551 case 3:
552 if (rand_std() % 1 == 0) // random first bioex
553 {
554 if (1 + rand_std() % 100 <= 50)
555 {
556 classSlot = bioexClass1;
557 }
558 }
559 else // random 2nd bioex
560 {
561 if (1 + rand_std() % 100 <= 50)
562 {
563 classSlot = bioexClass2;
564 }
565 }
566 break;
567 }
568
569 // if clasSlot is still null
570 if (classSlot.attributeValue == 0)
571 {
572 // give a random skill type
573 classSlot.attributeType = rand_std() % (MAX_SKILLS - 1);
574 classSlot.attributeValue = finalLevel / 90;
575 }
576 }
577 }
578 }
579
580 // make an item??
581 // roll chance first
582 // give skill
583
584 //move our stats into an array that we can initialise with 0 values
585 int savedAttribute[4], savedValue[4];
586
587 for (int i = 0; i < 4; i++)
588 {
589 savedAttribute[i] = 0;
590 savedValue[i] = 0;
591 }
592 int i = 0;
593 // now iterate finalItemSlots moving into the array
594 for (auto& it : finalItemSlots)
595 {
596 savedAttribute[i] = it.attributeType;
597 savedValue[i] = it.attributeValue;
598 ++i;
599 }
600
601
602 auto* itemBioex = static_cast<item_data*>(new item_data());
603
604 itemBioex->type = ITEM_BIOEX;
605 itemBioex->num1 = savedAttribute[0];
606 itemBioex->num2 = savedValue[0];
607 itemBioex->num3 = savedAttribute[1];
608 itemBioex->num4 = savedValue[1];
609 itemBioex->num5 = savedAttribute[2];
610 itemBioex->num6 = savedValue[2];
611 itemBioex->num7 = savedAttribute[3];
612 itemBioex->num8 = savedValue[3];
613 itemBioex->num9 = 9;
614 itemBioex->num10 = classSlot.attributeType; // should be ok to use even if one didn't get picked since it was set to 0 on initialise
615 itemBioex->num11 = classSlot.attributeValue;
616 itemBioex->cost = 100;
617 itemBioex->image_num = 153;
618 itemBioex->image_color = 25;
619 itemBioex->stackdrop = 1;
620 itemBioex->complexity = get_max_system_level(itemBioex);
621
622 if (classSlot.attributeValue * 90 > itemBioex->complexity)
623 itemBioex->complexity = classSlot.attributeValue * 90;
624
625 itemBioex->name = getmem(MAX_ITEM_NAME);
626 strcpy(itemBioex->name, "Bio-Ex");
627
628 auto* find = find_item(itemBioex);
629
630 if (find == nullptr)
631 {
632 magic_item_count++;
633 while (check_id_in_use(20000 + magic_item_count)) {
634 magic_item_count++;
635 }
636 itemBioex->item_id = 20000 + magic_item_count;
637
638 add_item(itemBioex);
639 save_new_item(itemBioex, true);
640 }
641 else
642 {
643 delete itemBioex;
644 itemBioex = find;
645 }
646 int itemLevel = get_max_system_level(itemBioex);
647
648 int skill = SKILL_XENOLOGY; // use systems skill for now
649
650 int chance = 80;
651 chance -= 1 * (itemLevel - (p->mod_skills[skill] / 5 + ((p->mod_skills[STAT_INT] - 10) / 2)));
652 if (itemLevel < 30) chance += 5 * (30 - itemLevel); // bonus for low levels
653
654 if (chance > 100) chance = 100;
655 if (chance < 1) chance = 1;
656
657 //send info to client fab window
658 if (p->test_fab)
659 {
660 // if we not hit combine, then we need to output a load of info
661 // amount of slots range min max
662 // range of cpx
663 // if no stone used, tell them what happens when they do (all stats get maxed to level
664 // inform them of what happens when using a class skill
665 //hs_sprintf(buf, MAX_BUF,"A random Bio-ex will be created based on the following parameters:-\nMinimum level = %d\nMaximum level %d\nBetween %d and %d may be present.\nUsing a stone will guarantee that attribute, and it will also be boosted.\nFor each attribute currently present, a 50%% chance will be added to the chance that attribute exists in the final Bio-Ex.\nArtifacts will also create a class skill on the Bio-Ex.",minBioexLevel,maxBioexLevel, minSlots,maxSlots);
666
667 out_combine_string(p->desc, FAB_BIOEX_COMBINE, "A Random Bio-Ex will be produced.\nVarious factors can be manipulated.");
668 out_combine_chance(p->desc, FAB_BIOEX_COMBINE, chance);
669 //put_in_cargo(p->ship, itemBioex, 1);
670 }
671 else
672 {
673 // give skill
674 if (((p->skills[skill] / 10) - itemBioex->complexity) > 7) {
675 hs_sprintf(buf, MAX_BUF, "You were unable to gain any more skill from making that item.");
676 tell_player(p, buf);
677 }
678 else {
679 for(auto i = 0;i < targetMaxSlots;++i)
680 test_skill(p, skill, 3);
681 if(stone != nullptr)
682 test_skill(p, skill, 3);
683 if(cls != nullptr)
684 test_skill(p, skill, 3);
685 }
686
687 // roll chance
688 if (rand_std() % 100 >= chance)
689 {
690 // FAIL
691
692 hs_sprintf(buf, MAX_BUF, "#21#%s failed to combine [%d] with [%d].", p->ship->cname, bioex1->item_id, bioex2->item_id);
693 tell_ships_colour(p->ship->x, p->ship->y, p->ship->z, buf, nullptr, p->ship->my_instance);
694 }
695 else
696 {
697 hs_sprintf(buf, MAX_BUF, "#5#%s successfully combined [%d] with [%d] creating [%d]", p->ship->cname, bioex1->item_id, bioex2->item_id,itemBioex->item_id);
698 tell_ships_colour(p->ship->x, p->ship->y, p->ship->z, buf, nullptr, p->ship->my_instance);
699
700 // give item
701 put_in_cargo(p->ship, itemBioex, 1);
702 }
703
704 // clear fab
705 for (i = 0; i < MAX_COMBINE; i++) {
706 p->combine_item[i] = nullptr;
707 p->combine_quant[i] = 0;
708 }
709 }
710}