… | |
… | |
625 | control_golem (object *op, int dir) |
625 | control_golem (object *op, int dir) |
626 | { |
626 | { |
627 | op->direction = dir; |
627 | op->direction = dir; |
628 | } |
628 | } |
629 | |
629 | |
630 | /* summon golem: summons a monster for 'op'. caster is the object |
630 | /* summon golem: summons a monster for 'op'. caster is the object |
631 | * casting the spell, dir is the direction to place the monster, |
631 | * casting the spell, dir is the direction to place the monster, |
632 | * at is the archetype of the monster, and spob is the spell |
632 | * at is the archetype of the monster, and spob is the spell |
633 | * object. At this stage, all spob is really used for is to |
633 | * object. At this stage, all spob is really used for is to |
634 | * adjust some values in the monster. |
634 | * adjust some values in the monster. |
635 | */ |
635 | */ |
… | |
… | |
755 | if (!(tmp->attacktype & AT_PHYSICAL)) |
755 | if (!(tmp->attacktype & AT_PHYSICAL)) |
756 | tmp->attacktype |= AT_PHYSICAL; |
756 | tmp->attacktype |= AT_PHYSICAL; |
757 | } |
757 | } |
758 | |
758 | |
759 | insert_ob_in_map (tmp, tmp->map, op, 0); |
759 | insert_ob_in_map (tmp, tmp->map, op, 0); |
|
|
760 | |
760 | return 1; |
761 | return 1; |
761 | } |
762 | } |
762 | |
763 | |
763 | |
764 | |
764 | /*************************************************************************** |
765 | /*************************************************************************** |
… | |
… | |
770 | /* Returns a monster (chosen at random) that this particular player (and his |
771 | /* Returns a monster (chosen at random) that this particular player (and his |
771 | * god) find acceptable. This checks level, races allowed by god, etc |
772 | * god) find acceptable. This checks level, races allowed by god, etc |
772 | * to determine what is acceptable. |
773 | * to determine what is acceptable. |
773 | * This returns NULL if no match was found. |
774 | * This returns NULL if no match was found. |
774 | */ |
775 | */ |
775 | |
|
|
776 | object * |
776 | object * |
777 | choose_cult_monster (object *pl, object *god, int summon_level) |
777 | choose_cult_monster (object *pl, object *god, int summon_level) |
778 | { |
778 | { |
779 | char buf[MAX_BUF]; |
779 | char buf[MAX_BUF]; |
780 | const char *race; |
780 | const char *race; |
… | |
… | |
835 | * a valid entry, assuming nothing is available and quit. |
835 | * a valid entry, assuming nothing is available and quit. |
836 | */ |
836 | */ |
837 | if (!mon_nr) |
837 | if (!mon_nr) |
838 | return NULL; |
838 | return NULL; |
839 | |
839 | |
840 | mon_nr = rndm (0, mon_nr - 1); |
840 | mon_nr = rndm (mon_nr - 1); |
841 | for (tobl = list->member; tobl; tobl = tobl->next) |
841 | for (tobl = list->member; tobl; tobl = tobl->next) |
842 | { |
842 | { |
843 | otmp = tobl->ob; |
843 | otmp = tobl->ob; |
844 | if (!otmp || !QUERY_FLAG (otmp, FLAG_MONSTER)) |
844 | if (!otmp || !QUERY_FLAG (otmp, FLAG_MONSTER)) |
845 | continue; |
845 | continue; |
|
|
846 | |
846 | if (otmp->level <= summon_level && !mon_nr--) |
847 | if (otmp->level <= summon_level && !mon_nr--) |
847 | return otmp; |
848 | return otmp; |
848 | } |
849 | } |
|
|
850 | |
849 | /* This should not happen */ |
851 | /* This should not happen */ |
850 | LOG (llevDebug, "choose_cult_monster() mon_nr was set, but did not find a monster\n"); |
852 | LOG (llevDebug, "choose_cult_monster() mon_nr was set, but did not find a monster\n"); |
851 | return NULL; |
853 | return NULL; |
852 | } |
854 | } |
853 | |
855 | |
… | |
… | |
1053 | } /* for i < nrof */ |
1055 | } /* for i < nrof */ |
1054 | |
1056 | |
1055 | return 1; |
1057 | return 1; |
1056 | } |
1058 | } |
1057 | |
1059 | |
1058 | /* recursively look through the owner property of objects until the real owner |
|
|
1059 | is found */ |
|
|
1060 | object * |
|
|
1061 | get_real_owner (object *ob) |
|
|
1062 | { |
|
|
1063 | object *realowner = ob; |
|
|
1064 | |
|
|
1065 | if (realowner == NULL) |
|
|
1066 | return NULL; |
|
|
1067 | |
|
|
1068 | while (realowner->owner != NULL) |
|
|
1069 | { |
|
|
1070 | realowner = realowner->owner; |
|
|
1071 | } |
|
|
1072 | return realowner; |
|
|
1073 | } |
|
|
1074 | |
|
|
1075 | /* determines if checks so pets don't attack players or other pets should be |
1060 | /* determines if checks so pets don't attack players or other pets should be |
1076 | overruled by the arena petmode */ |
1061 | overruled by the arena petmode */ |
1077 | int |
1062 | int |
1078 | should_arena_attack (object *pet, object *owner, object *target) |
1063 | should_arena_attack (object *pet, object *owner, object *target) |
1079 | { |
1064 | { |
… | |
… | |
1083 | if ((target == NULL) || (pet == NULL) || (owner == NULL)) |
1068 | if ((target == NULL) || (pet == NULL) || (owner == NULL)) |
1084 | return 0; |
1069 | return 0; |
1085 | |
1070 | |
1086 | /* get the owners of itself and the target, this is to deal with pets of |
1071 | /* get the owners of itself and the target, this is to deal with pets of |
1087 | pets */ |
1072 | pets */ |
1088 | rowner = get_real_owner (owner); |
1073 | rowner = owner->outer_owner (); |
1089 | towner = target->type == PLAYER ? 0 : get_real_owner (target); |
1074 | towner = target->is_player () ? 0 : target->outer_owner (); |
1090 | |
1075 | |
1091 | /* if the pet has now owner, exit with error */ |
1076 | /* if the pet has now owner, exit with error */ |
1092 | if (!rowner) |
1077 | if (!rowner) |
1093 | { |
1078 | { |
1094 | LOG (llevError, "Pet has no owner.\n"); |
1079 | LOG (llevError, "Pet has no owner.\n"); |
1095 | return 0; |
1080 | return 0; |
1096 | } |
1081 | } |
1097 | |
1082 | |
1098 | /* if the target is not a player, and has no owner, we shouldn't be here |
1083 | /* if the target is not a player, and has no owner, we shouldn't be here |
1099 | */ |
1084 | */ |
1100 | if ((towner == NULL) && (target->type != PLAYER)) |
1085 | if (!towner && !target->is_player ()) |
1101 | { |
1086 | { |
1102 | LOG (llevError, "Target is not a player but has no owner. We should not be here.\n"); |
1087 | LOG (llevError, "Target is not a player but has no owner. We should not be here.\n"); |
1103 | return 0; |
1088 | return 0; |
1104 | } |
1089 | } |
1105 | |
1090 | |
1106 | /* make sure that the owner is a player */ |
1091 | /* make sure that the owner is a player */ |
1107 | if (rowner->type != PLAYER) |
1092 | if (!rowner->is_player ()) |
1108 | return 0; |
1093 | return 0; |
1109 | |
1094 | |
1110 | /* abort if the petmode is not arena */ |
1095 | /* abort if the petmode is not arena */ |
1111 | if (rowner->contr->petmode != pet_arena) |
1096 | if (rowner->contr->petmode != pet_arena) |
1112 | return 0; |
1097 | return 0; |
… | |
… | |
1114 | /* abort if the pet, it's owner, or the target is not on battleground */ |
1099 | /* abort if the pet, it's owner, or the target is not on battleground */ |
1115 | if (!(op_on_battleground (pet, NULL, NULL) && op_on_battleground (owner, NULL, NULL) && op_on_battleground (target, NULL, NULL))) |
1100 | if (!(op_on_battleground (pet, NULL, NULL) && op_on_battleground (owner, NULL, NULL) && op_on_battleground (target, NULL, NULL))) |
1116 | return 0; |
1101 | return 0; |
1117 | |
1102 | |
1118 | /* if the target is a monster, make sure it's owner is not the same */ |
1103 | /* if the target is a monster, make sure it's owner is not the same */ |
1119 | if ((target->type != PLAYER) && (rowner == towner)) |
1104 | if (!target->is_player () && rowner == towner) |
1120 | return 0; |
1105 | return 0; |
1121 | |
1106 | |
1122 | /* check if the target is a player which affects how it will handle |
1107 | /* check if the target is a player which affects how it will handle |
1123 | parties */ |
1108 | parties */ |
1124 | if (target->type != PLAYER) |
1109 | if (!target->is_player ()) |
1125 | { |
1110 | { |
1126 | /* if the target is owned by a player make sure than make sure |
1111 | /* if the target is owned by a player make sure than make sure |
1127 | it's not in the same party */ |
1112 | it's not in the same party */ |
1128 | if ((towner->type == PLAYER) && (rowner->contr->party != NULL)) |
1113 | if (towner->is_player () && rowner->contr->party) |
1129 | { |
|
|
1130 | if (rowner->contr->party == towner->contr->party) |
1114 | if (rowner->contr->party == towner->contr->party) |
1131 | return 0; |
1115 | return 0; |
1132 | } |
|
|
1133 | } |
1116 | } |
1134 | else |
1117 | else |
1135 | { |
1118 | { |
1136 | /* if the target is a player make sure than make sure it's not |
1119 | /* if the target is a player make sure than make sure it's not |
1137 | in the same party */ |
1120 | in the same party */ |
1138 | if (rowner->contr->party != NULL) |
1121 | if (rowner->contr->party) |
1139 | { |
|
|
1140 | if (rowner->contr->party == target->contr->party) |
1122 | if (rowner->contr->party == target->contr->party) |
1141 | return 0; |
1123 | return 0; |
1142 | } |
|
|
1143 | } |
1124 | } |
1144 | |
1125 | |
1145 | return 1; |
1126 | return 1; |
1146 | } |
1127 | } |
|
|
1128 | |