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.24 by root, Sun Sep 10 16:00:23 2006 UTC vs.
Revision 1.25 by root, Mon Sep 11 01:16:20 2006 UTC

1 1
2/* 2/*
3 * static char *rcsid_object_c = 3 * static char *rcsid_object_c =
4 * "$Id: object.C,v 1.24 2006/09/10 16:00:23 root Exp $"; 4 * "$Id: object.C,v 1.25 2006/09/11 01:16:20 root Exp $";
5 */ 5 */
6 6
7/* 7/*
8 CrossFire, A Multiplayer game for X-windows 8 CrossFire, A Multiplayer game for X-windows
9 9
507 507
508 op->owner = owner; 508 op->owner = owner;
509 509
510 op->ownercount = owner->count; 510 op->ownercount = owner->count;
511 owner->refcount++; 511 owner->refcount++;
512
513} 512}
514 513
515/* Set the owner to clone's current owner and set the skill and experience 514/* Set the owner to clone's current owner and set the skill and experience
516 * objects to clone's objects (typically those objects that where the owner's 515 * objects to clone's objects (typically those objects that where the owner's
517 * current skill and experience objects at the time when clone's owner was 516 * current skill and experience objects at the time when clone's owner was
535 if (clone->type == PLAYER) 534 if (clone->type == PLAYER)
536 owner = clone; 535 owner = clone;
537 else 536 else
538 return; 537 return;
539 } 538 }
539
540 set_owner (op, owner); 540 set_owner (op, owner);
541
542} 541}
543 542
544/* Zero the key_values on op, decrementing the shared-string 543/* Zero the key_values on op, decrementing the shared-string
545 * refcounts and freeing the links. 544 * refcounts and freeing the links.
546 */ 545 */
561void object::clear () 560void object::clear ()
562{ 561{
563 attachable_base::clear (); 562 attachable_base::clear ();
564 563
565 free_key_values (this); 564 free_key_values (this);
565
566 clear_owner (this);
566 567
567 name = 0; 568 name = 0;
568 name_pl = 0; 569 name_pl = 0;
569 title = 0; 570 title = 0;
570 race = 0; 571 race = 0;
912 913
913 if (op->more != NULL) 914 if (op->more != NULL)
914 update_object (op->more, action); 915 update_object (op->more, action);
915} 916}
916 917
917static 918static unordered_vector<object *> mortals;
918std::vector < object *> 919static std::vector<object *> freed;
919 mortals;
920 920
921void object::free_mortals () 921void object::free_mortals ()
922{ 922{
923 for (std::vector < object *>::iterator i = mortals.begin (); i != mortals.end (); ++i) 923 for (unordered_vector<object *>::iterator i = mortals.begin (); i != mortals.end (); )
924 delete * 924 if (!(*i)->refcount)
925 {
926 freed.push_back (*i);
927 mortals.erase (i);
928 }
929 else
925 i; 930 ++i;
926
927 mortals.clear ();
928} 931}
929 932
930object::object () 933object::object ()
931{ 934{
932 SET_FLAG (this, FLAG_REMOVED); 935 SET_FLAG (this, FLAG_REMOVED);
958{ 961{
959 count = 0; 962 count = 0;
960 963
961 /* Remove this object from the list of used objects */ 964 /* Remove this object from the list of used objects */
962 if (prev) 965 if (prev)
966 {
963 prev->next = next; 967 prev->next = next;
968 prev = 0;
969 }
970
964 if (next) 971 if (next)
972 {
965 next->prev = prev; 973 next->prev = prev;
974 next = 0;
975 }
976
966 if (this == objects) 977 if (this == objects)
967 objects = next; 978 objects = next;
968} 979}
969 980
970object *object::create () 981object *object::create ()
971{ 982{
972 object * 983 object *op;
984
985 if (freed.empty ())
973 op = new object; 986 op = new object;
987 else
988 {
989 // highly annoying, but the only way to get it stable right now
990 op = freed.back (); freed.pop_back ();
991 op->~object ();
992 new ((void *)op) object;
993 }
974 994
975 op->link (); 995 op->link ();
976 return op; 996 return op;
977} 997}
978 998
1061 1081
1062 op = tmp; 1082 op = tmp;
1063 } 1083 }
1064 } 1084 }
1065 } 1085 }
1086
1087 clear_owner (this);
1066 1088
1067 /* Remove object from the active list */ 1089 /* Remove object from the active list */
1068 speed = 0; 1090 speed = 0;
1069 update_ob_speed (this); 1091 update_ob_speed (this);
1070 1092
1375 */ 1397 */
1376 1398
1377object * 1399object *
1378insert_ob_in_map (object *op, mapstruct *m, object *originator, int flag) 1400insert_ob_in_map (object *op, mapstruct *m, object *originator, int flag)
1379{ 1401{
1380 object * 1402 object *tmp, *top, *floor = NULL;
1381 tmp, * 1403 sint16 x, y;
1382 top, *
1383 floor = NULL;
1384 sint16
1385 x,
1386 y;
1387 1404
1388 if (QUERY_FLAG (op, FLAG_FREED)) 1405 if (QUERY_FLAG (op, FLAG_FREED))
1389 { 1406 {
1390 LOG (llevError, "Trying to insert freed object!\n"); 1407 LOG (llevError, "Trying to insert freed object!\n");
1391 return NULL; 1408 return NULL;
1392 } 1409 }
1410
1393 if (m == NULL) 1411 if (m == NULL)
1394 { 1412 {
1395 dump_object (op); 1413 dump_object (op);
1396 LOG (llevError, "Trying to insert in null-map!\n%s\n", errmsg); 1414 LOG (llevError, "Trying to insert in null-map!\n%s\n", errmsg);
1397 return op; 1415 return op;
1398 } 1416 }
1417
1399 if (out_of_map (m, op->x, op->y)) 1418 if (out_of_map (m, op->x, op->y))
1400 { 1419 {
1401 dump_object (op); 1420 dump_object (op);
1402 LOG (llevError, "Trying to insert object outside the map.\n%s\n", errmsg); 1421 LOG (llevError, "Trying to insert object outside the map.\n%s\n", errmsg);
1403#ifdef MANY_CORES 1422#ifdef MANY_CORES
1407 */ 1426 */
1408 abort (); 1427 abort ();
1409#endif 1428#endif
1410 return op; 1429 return op;
1411 } 1430 }
1431
1412 if (!QUERY_FLAG (op, FLAG_REMOVED)) 1432 if (!QUERY_FLAG (op, FLAG_REMOVED))
1413 { 1433 {
1414 dump_object (op); 1434 dump_object (op);
1415 LOG (llevError, "Trying to insert (map) inserted object.\n%s\n", errmsg); 1435 LOG (llevError, "Trying to insert (map) inserted object.\n%s\n", errmsg);
1416 return op; 1436 return op;
1417 } 1437 }
1438
1418 if (op->more != NULL) 1439 if (op->more != NULL)
1419 { 1440 {
1420 /* The part may be on a different map. */ 1441 /* The part may be on a different map. */
1421 1442
1422 object * 1443 object *
1444 if (!op->head) 1465 if (!op->head)
1445 LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n"); 1466 LOG (llevError, "BUG: insert_ob_in_map(): inserting op->more killed op\n");
1446 return NULL; 1467 return NULL;
1447 } 1468 }
1448 } 1469 }
1470
1449 CLEAR_FLAG (op, FLAG_REMOVED); 1471 CLEAR_FLAG (op, FLAG_REMOVED);
1450 1472
1451 /* Ideally, the caller figures this out. However, it complicates a lot 1473 /* Ideally, the caller figures this out. However, it complicates a lot
1452 * of areas of callers (eg, anything that uses find_free_spot would now 1474 * of areas of callers (eg, anything that uses find_free_spot would now
1453 * need extra work 1475 * need extra work
1457 y = op->y; 1479 y = op->y;
1458 1480
1459 /* this has to be done after we translate the coordinates. 1481 /* this has to be done after we translate the coordinates.
1460 */ 1482 */
1461 if (op->nrof && !(flag & INS_NO_MERGE)) 1483 if (op->nrof && !(flag & INS_NO_MERGE))
1462 {
1463 for (tmp = GET_MAP_OB (op->map, x, y); tmp != NULL; tmp = tmp->above) 1484 for (tmp = GET_MAP_OB (op->map, x, y); tmp != NULL; tmp = tmp->above)
1464 if (CAN_MERGE (op, tmp)) 1485 if (CAN_MERGE (op, tmp))
1465 { 1486 {
1466 op->nrof += tmp->nrof; 1487 op->nrof += tmp->nrof;
1467 remove_ob (tmp); 1488 remove_ob (tmp);
1468 free_object (tmp); 1489 free_object (tmp);
1469 } 1490 }
1470 }
1471 1491
1472 CLEAR_FLAG (op, FLAG_APPLIED); /* hack for fixing F_APPLIED in items of dead people */ 1492 CLEAR_FLAG (op, FLAG_APPLIED); /* hack for fixing F_APPLIED in items of dead people */
1473 CLEAR_FLAG (op, FLAG_INV_LOCKED); 1493 CLEAR_FLAG (op, FLAG_INV_LOCKED);
1494
1474 if (!QUERY_FLAG (op, FLAG_ALIVE)) 1495 if (!QUERY_FLAG (op, FLAG_ALIVE))
1475 CLEAR_FLAG (op, FLAG_NO_STEAL); 1496 CLEAR_FLAG (op, FLAG_NO_STEAL);
1476 1497
1477 if (flag & INS_BELOW_ORIGINATOR) 1498 if (flag & INS_BELOW_ORIGINATOR)
1478 { 1499 {
1479 if (originator->map != op->map || originator->x != op->x || originator->y != op->y) 1500 if (originator->map != op->map || originator->x != op->x || originator->y != op->y)
1480 { 1501 {
1481 LOG (llevError, "insert_ob_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n"); 1502 LOG (llevError, "insert_ob_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n");
1482 abort (); 1503 abort ();
1483 } 1504 }
1505
1484 op->above = originator; 1506 op->above = originator;
1485 op->below = originator->below; 1507 op->below = originator->below;
1508
1486 if (op->below) 1509 if (op->below)
1487 op->below->above = op; 1510 op->below->above = op;
1488 else 1511 else
1489 SET_MAP_OB (op->map, op->x, op->y, op); 1512 SET_MAP_OB (op->map, op->x, op->y, op);
1513
1490 /* since *below* originator, no need to update top */ 1514 /* since *below* originator, no need to update top */
1491 originator->below = op; 1515 originator->below = op;
1492 } 1516 }
1493 else 1517 else
1494 { 1518 {
1495 /* If there are other objects, then */ 1519 /* If there are other objects, then */
1496 if ((!(flag & INS_MAP_LOAD)) && ((top = GET_MAP_OB (op->map, op->x, op->y)) != NULL)) 1520 if ((!(flag & INS_MAP_LOAD)) && ((top = GET_MAP_OB (op->map, op->x, op->y)) != NULL))
1497 { 1521 {
1498 object *
1499 last = NULL; 1522 object *last = NULL;
1500 1523
1501 /* 1524 /*
1502 * If there are multiple objects on this space, we do some trickier handling. 1525 * If there are multiple objects on this space, we do some trickier handling.
1503 * We've already dealt with merging if appropriate. 1526 * We've already dealt with merging if appropriate.
1504 * Generally, we want to put the new object on top. But if 1527 * Generally, we want to put the new object on top. But if
1551 */ 1574 */
1552 if (last && last->below && last != floor) 1575 if (last && last->below && last != floor)
1553 top = last->below; 1576 top = last->below;
1554 } 1577 }
1555 } /* If objects on this space */ 1578 } /* If objects on this space */
1579
1556 if (flag & INS_MAP_LOAD) 1580 if (flag & INS_MAP_LOAD)
1557 top = GET_MAP_TOP (op->map, op->x, op->y); 1581 top = GET_MAP_TOP (op->map, op->x, op->y);
1582
1558 if (flag & INS_ABOVE_FLOOR_ONLY) 1583 if (flag & INS_ABOVE_FLOOR_ONLY)
1559 top = floor; 1584 top = floor;
1560 1585
1561 /* Top is the object that our object (op) is going to get inserted above. 1586 /* Top is the object that our object (op) is going to get inserted above.
1562 */ 1587 */
1563 1588
1564 /* First object on this space */ 1589 /* First object on this space */
1565 if (!top) 1590 if (!top)
1566 { 1591 {
1567 op->above = GET_MAP_OB (op->map, op->x, op->y); 1592 op->above = GET_MAP_OB (op->map, op->x, op->y);
1593
1568 if (op->above) 1594 if (op->above)
1569 op->above->below = op; 1595 op->above->below = op;
1596
1570 op->below = NULL; 1597 op->below = NULL;
1571 SET_MAP_OB (op->map, op->x, op->y, op); 1598 SET_MAP_OB (op->map, op->x, op->y, op);
1572 } 1599 }
1573 else 1600 else
1574 { /* get inserted into the stack above top */ 1601 { /* get inserted into the stack above top */
1575 op->above = top->above; 1602 op->above = top->above;
1603
1576 if (op->above) 1604 if (op->above)
1577 op->above->below = op; 1605 op->above->below = op;
1606
1578 op->below = top; 1607 op->below = top;
1579 top->above = op; 1608 top->above = op;
1580 } 1609 }
1610
1581 if (op->above == NULL) 1611 if (op->above == NULL)
1582 SET_MAP_TOP (op->map, op->x, op->y, op); 1612 SET_MAP_TOP (op->map, op->x, op->y, op);
1583 } /* else not INS_BELOW_ORIGINATOR */ 1613 } /* else not INS_BELOW_ORIGINATOR */
1584 1614
1585 if (op->type == PLAYER) 1615 if (op->type == PLAYER)
1588 /* If we have a floor, we know the player, if any, will be above 1618 /* If we have a floor, we know the player, if any, will be above
1589 * it, so save a few ticks and start from there. 1619 * it, so save a few ticks and start from there.
1590 */ 1620 */
1591 if (!(flag & INS_MAP_LOAD)) 1621 if (!(flag & INS_MAP_LOAD))
1592 for (tmp = floor ? floor : GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 1622 for (tmp = floor ? floor : GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
1593 {
1594 if (tmp->type == PLAYER) 1623 if (tmp->type == PLAYER)
1595 tmp->contr->socket.update_look = 1; 1624 tmp->contr->socket.update_look = 1;
1596 }
1597 1625
1598 /* If this object glows, it may affect lighting conditions that are 1626 /* If this object glows, it may affect lighting conditions that are
1599 * visible to others on this map. But update_all_los is really 1627 * visible to others on this map. But update_all_los is really
1600 * an inefficient way to do this, as it means los for all players 1628 * an inefficient way to do this, as it means los for all players
1601 * on the map will get recalculated. The players could very well 1629 * on the map will get recalculated. The players could very well
1620 * blocked() and wall() work properly), and these flags are updated by 1648 * blocked() and wall() work properly), and these flags are updated by
1621 * update_object(). 1649 * update_object().
1622 */ 1650 */
1623 1651
1624 /* if this is not the head or flag has been passed, don't check walk on status */ 1652 /* if this is not the head or flag has been passed, don't check walk on status */
1625
1626 if (!(flag & INS_NO_WALK_ON) && !op->head) 1653 if (!(flag & INS_NO_WALK_ON) && !op->head)
1627 { 1654 {
1628 if (check_move_on (op, originator)) 1655 if (check_move_on (op, originator))
1629 return NULL; 1656 return NULL;
1630 1657
1633 */ 1660 */
1634 for (tmp = op->more; tmp != NULL; tmp = tmp->more) 1661 for (tmp = op->more; tmp != NULL; tmp = tmp->more)
1635 if (check_move_on (tmp, originator)) 1662 if (check_move_on (tmp, originator))
1636 return NULL; 1663 return NULL;
1637 } 1664 }
1665
1638 return op; 1666 return op;
1639} 1667}
1640 1668
1641/* this function inserts an object in the map, but if it 1669/* this function inserts an object in the map, but if it
1642 * finds an object of its own type, it'll remove that one first. 1670 * finds an object of its own type, it'll remove that one first.
1643 * op is the object to insert it under: supplies x and the map. 1671 * op is the object to insert it under: supplies x and the map.
1644 */ 1672 */
1645void 1673void
1646replace_insert_ob_in_map (const char *arch_string, object *op) 1674replace_insert_ob_in_map (const char *arch_string, object *op)
1647{ 1675{
1648 object * 1676 object *tmp;
1649 tmp;
1650 object * 1677 object *tmp1;
1651 tmp1;
1652 1678
1653 /* first search for itself and remove any old instances */ 1679 /* first search for itself and remove any old instances */
1654 1680
1655 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above) 1681 for (tmp = GET_MAP_OB (op->map, op->x, op->y); tmp != NULL; tmp = tmp->above)
1656 { 1682 {
1660 free_object (tmp); 1686 free_object (tmp);
1661 } 1687 }
1662 } 1688 }
1663 1689
1664 tmp1 = arch_to_object (find_archetype (arch_string)); 1690 tmp1 = arch_to_object (find_archetype (arch_string));
1665
1666 1691
1667 tmp1->x = op->x; 1692 tmp1->x = op->x;
1668 tmp1->y = op->y; 1693 tmp1->y = op->y;
1669 insert_ob_in_map (tmp1, op->map, op, 0); 1694 insert_ob_in_map (tmp1, op->map, op, 0);
1670} 1695}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines