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

Comparing deliantra/server/server/skill_util.C (file contents):
Revision 1.49 by root, Mon May 14 21:32:27 2007 UTC vs.
Revision 1.50 by root, Mon May 14 21:52:32 2007 UTC

105 op->contr->ns->last_skill_exp[tmp->subtype] = -1; //TODO: this should go 105 op->contr->ns->last_skill_exp[tmp->subtype] = -1; //TODO: this should go
106 } 106 }
107 } 107 }
108} 108}
109 109
110static object *
111find_skill (object *who, const shstr &sh)
112{
113 for (object *tmp = who->inv; tmp; tmp = tmp->below)
114 if (tmp->skill == sh && tmp->type == SKILL)
115 return tmp;
116
117 return 0;
118}
119
110/* This returns the skill pointer of the given name (the 120/* This returns the skill pointer of the given name (the
111 * one that accumlates exp, has the level, etc). 121 * one that accumulates exp, has the level, etc).
112 * 122 *
113 * It is presumed that the player will be needing to actually 123 * It is presumed that the player will be needing to actually
114 * use the skill, so thus if use of the skill requires a skill 124 * use the skill, so thus if use of the skill requires a skill
115 * tool, this code will equip it. 125 * tool, this code will equip it.
116 */ 126 */
117object *
118find_skill_by_name (object *who, const char *name)
119{
120 if (!name)
121 return 0;
122
123 object *skill = 0, *skill_tool = 0;
124
125 /* We make sure the length of the string in the object is greater
126 * in length than the passed string. Eg, if we have a skill called
127 * 'hi', we don't want to match if the user passed 'high'
128 */
129 for (object *tmp = who->inv; tmp; tmp = tmp->below)
130 {
131 if (tmp->type == SKILL && !strncasecmp (name, tmp->skill, strlen (name)) && strlen (tmp->skill) >= strlen (name))
132 skill = tmp;
133
134 /* Try to find appropriate skilltool. If the player has one already
135 * applied, we try to keep using that one.
136 */
137 else if (tmp->type == SKILL_TOOL && !strncasecmp (name, tmp->skill, strlen (name)) && strlen (tmp->skill) >= strlen (name))
138 {
139 if (QUERY_FLAG (tmp, FLAG_APPLIED))
140 skill_tool = tmp;
141 else if (!skill_tool || !QUERY_FLAG (skill_tool, FLAG_APPLIED))
142 skill_tool = tmp;
143 }
144 }
145
146 /* If this is a skill that can be used without a tool, return it */
147 if (skill && QUERY_FLAG (skill, FLAG_CAN_USE_SKILL))
148 return skill;
149
150 /* Player has a tool to use the skill. If not applied, apply it -
151 * if not successful, return null. If they do have the skill tool
152 * but not the skill itself, give it to them.
153 */
154 if (skill_tool)
155 {
156 if (!skill)
157 {
158 skill = give_skill_by_name (who, skill_tool->skill);
159 link_player_skills (who);
160 }
161
162 if (!QUERY_FLAG (skill_tool, FLAG_APPLIED))
163 if (apply_special (who, skill_tool, 0))
164 return 0;
165
166 return skill;
167 }
168
169 return 0;
170}
171
172static object *
173find_skill (object *who, const shstr &sh)
174{
175 for (object *tmp = who->inv; tmp; tmp = tmp->below)
176 if (tmp->skill == sh && tmp->type == SKILL)
177 return tmp;
178
179 return 0;
180}
181
182// like the other function above, but for exact matches using a shstr
183// which is very common inside the server. unlike the above function,
184// we always return the skill.
185object * 127object *
186find_skill_by_name (object *who, const shstr &sh) 128find_skill_by_name (object *who, const shstr &sh)
187{ 129{
188 object *skill_tool = 0; 130 object *skill_tool = 0;
189 131
222 return 0; 164 return 0;
223 165
224 return skill; 166 return skill;
225} 167}
226 168
169object *
170find_skill_by_name (object *who, const char *name)
171{
172 if (!name)
173 return 0;
174
175 for (object *tmp = who->inv; tmp; tmp = tmp->below)
176 if ((tmp->type == SKILL || tmp->type == SKILL_TOOL)
177 && tmp->skill.begins_with (name))
178 if (object *skop = find_skill_by_name (who, tmp->skill))
179 return skop;
180
181 return 0;
182}
183
227/* This returns the skill pointer of the given name (the 184/* This returns the skill pointer of the given name (the
228 * one that accumulates exp, has the level, etc). 185 * one that accumulates exp, has the level, etc).
229 * 186 *
230 * It is presumed that the player will be needing to actually 187 * It is presumed that the player will be needing to actually
231 * use the skill, so thus if use of the skill requires a skill 188 * use the skill, so thus if use of the skill requires a skill
236 * this replaces find_skill. 193 * this replaces find_skill.
237 */ 194 */
238object * 195object *
239find_skill_by_number (object *who, int skillno) 196find_skill_by_number (object *who, int skillno)
240{ 197{
241 if (!IN_RANGE_EXC (skillno, 1, NUM_SKILLS))
242 return 0;
243
244 object *skill = NULL, *skill_tool = NULL;
245
246 for (object *tmp = who->inv; tmp; tmp = tmp->below) 198 for (object *tmp = who->inv; tmp; tmp = tmp->below)
247 {
248 if (tmp->type == SKILL && tmp->subtype == skillno) 199 if (tmp->type == SKILL && tmp->subtype == skillno)
249 skill = tmp; 200 if (object *skop = find_skill_by_name (who, tmp->skill))
250
251 /* Try to find appropriate skilltool. If the player has one already
252 * applied, we try to keep using that one.
253 */
254 //TODO: afaics, skill tools have subtype 0 always
255 else if (tmp->type == SKILL_TOOL && tmp->subtype == skillno)
256 {
257 if (QUERY_FLAG (tmp, FLAG_APPLIED))
258 skill_tool = tmp;
259 else if (!skill_tool || !QUERY_FLAG (skill_tool, FLAG_APPLIED))
260 skill_tool = tmp;
261 }
262 }
263
264 /* If this is a skill that can be used without a tool, return it */
265 if (skill && QUERY_FLAG (skill, FLAG_CAN_USE_SKILL))
266 return skill;
267
268 /* Player has a tool to use the skill. If not applied, apply it -
269 * if not successful, return null. If they do have the skill tool
270 * but not the skill itself, give it to them.
271 */
272 if (skill_tool)
273 {
274 if (!QUERY_FLAG (skill_tool, FLAG_APPLIED))
275 {
276 if (apply_special (who, skill_tool, 0))
277 return NULL;
278 }
279
280 if (!skill)
281 {
282 skill = give_skill_by_name (who, skill_tool->skill);
283 link_player_skills (who);
284 }
285
286 return skill; 201 return skop;
287 }
288 202
289 return NULL; 203 return 0;
290} 204}
291 205
292/* This changes the objects skill to new_skill. 206/* This changes the objects skill to new_skill.
293 * note that this function doesn't always need to get used - 207 * note that this function doesn't always need to get used -
294 * you can now add skill exp to the player without the chosen_skill being 208 * you can now add skill exp to the player without the chosen_skill being
696 * player learns the skill, 2 otherwise. 610 * player learns the skill, 2 otherwise.
697 */ 611 */
698int 612int
699learn_skill (object *pl, object *scroll) 613learn_skill (object *pl, object *scroll)
700{ 614{
701 object *tmp;
702
703 if (!scroll->skill) 615 if (!scroll->skill)
704 { 616 {
705 LOG (llevError, "skill scroll %s does not have skill pointer set.\n", &scroll->name); 617 LOG (llevError, "skill scroll %s does not have skill pointer set.\n", &scroll->name);
706 return 2; 618 return 2;
707 } 619 }
708 620
709 /* can't use find_skill_by_name because we want skills the player knows 621 object *tmp = find_skill (pl, scroll->skill);
710 * but can't use natively.
711 */
712
713 for (tmp = pl->inv; tmp != NULL; tmp = tmp->below)
714 if (tmp->type == SKILL && !strncasecmp (scroll->skill, tmp->skill, strlen (scroll->skill)))
715 break;
716 622
717 /* player already knows it */ 623 /* player already knows it */
718 if (tmp && QUERY_FLAG (tmp, FLAG_CAN_USE_SKILL)) 624 if (tmp && QUERY_FLAG (tmp, FLAG_CAN_USE_SKILL))
719 return 0; 625 return 0;
720 626
849 size_t len; 755 size_t len;
850 756
851 if (!string) 757 if (!string)
852 return 0; 758 return 0;
853 759
854 for (skop = op->inv; skop != NULL; skop = skop->below) 760 for (skop = op->inv; skop; skop = skop->below)
855 { 761 {
762 if (skop->type == SKILL
856 if (skop->type == SKILL && QUERY_FLAG (skop, FLAG_CAN_USE_SKILL) && 763 && QUERY_FLAG (skop, FLAG_CAN_USE_SKILL)
857 !strncasecmp (string, skop->skill, MIN (strlen (string), (size_t) strlen (skop->skill)))) 764 && !strncasecmp (string, skop->skill, MIN (strlen (string), (size_t) strlen (skop->skill))))
858 break; 765 break;
766 else if (skop->type == SKILL_TOOL
859 else if (skop->type == SKILL_TOOL && !strncasecmp (string, skop->skill, MIN (strlen (string), (size_t) strlen (skop->skill)))) 767 && !strncasecmp (string, skop->skill, MIN (strlen (string), (size_t) strlen (skop->skill))))
860 break; 768 break;
861 } 769 }
770
862 if (!skop) 771 if (!skop)
863 { 772 {
864 new_draw_info_format (NDI_UNIQUE, 0, op, "Unable to find skill %s", string); 773 new_draw_info_format (NDI_UNIQUE, 0, op, "Unable to find skill %s", string);
865 return 0; 774 return 0;
866 } 775 }
871 * options given to the skill. Its pretty simple - if there 780 * options given to the skill. Its pretty simple - if there
872 * are extra parameters (as deteremined by string length), we 781 * are extra parameters (as deteremined by string length), we
873 * want to skip over any leading spaces. 782 * want to skip over any leading spaces.
874 */ 783 */
875 if (len >= strlen (string)) 784 if (len >= strlen (string))
876 {
877 string = NULL; 785 string = NULL;
878 }
879 else 786 else
880 { 787 {
881 string += len; 788 string += len;
882 while (*string == 0x20) 789 while (*string == 0x20)
883 string++; 790 string++;
791
884 if (strlen (string) == 0) 792 if (strlen (string) == 0)
885 string = NULL; 793 string = NULL;
886 } 794 }
887 795
888#ifdef SKILL_UTIL_DEBUG 796#ifdef SKILL_UTIL_DEBUG
889 LOG (llevDebug, "use_skill() got skill: %s\n", sknum > -1 ? skills[sknum].name : "none"); 797 LOG (llevDebug, "use_skill() got skill: %s\n", sknum > -1 ? skills[sknum].name : "none");
890#endif 798#endif
891 799
892 /* Change to the new skill, then execute it. */
893 if (do_skill (op, op, skop, op->facing, string)) 800 if (do_skill (op, op, skop, op->facing, string))
894 return 1; 801 return 1;
895 802
896 return 0; 803 return 0;
897} 804}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines