1 #include <strings.h>
2 
3 #include "handwave.h"
4 #include "internal.h"
5 
6 /* the following are purely for readability */
7 #define P Gesture_PALM
8 #define D Gesture_DIGIT
9 #define F Gesture_FINGERS
10 #define W Gesture_WAVE
11 #define C Gesture_CLAPHALF
12 #define S Gesture_SNAP
13 #define P2 (Gesture_PALM | Gesture_DOUBLE)
14 #define D2 (Gesture_DIGIT | Gesture_DOUBLE)
15 #define F2 (Gesture_FINGERS | Gesture_DOUBLE)
16 #define W2 (Gesture_WAVE | Gesture_DOUBLE)
17 #define C2 (Gesture_CLAPHALF | Gesture_DOUBLE)
18 #define S2 (Gesture_SNAP | Gesture_DOUBLE)
19 
20 struct spelldef spelllist[NUMSPELLS] = {
21     {4, {C2, D,  P,  W},	0, 1, "Dispel Magic"},
22     {5, {C2, S,  W,  W,  S},	0, 1, "Summon Elemental"},
23     {2, {C2, W2},		0, 1, "Magic Mirror"},
24     {5, {D,  F,  F,  D,  D},	0, 0, "Lightning Bolt"},
25     {4, {D,  F,  P,  W},	0, 1, "Cure Heavy Wounds"},
26     {3, {D,  F,  W},		0, 1, "Cure Light Wounds"},
27     {3, {D,  P,  P},		1, 0, "Amnesia"},
28     {3, {D,  S,  F},		1, 0, "Confusion"},
29     {6, {D,  S,  F,  F,  F,  C2},0, 0,"Disease"},
30     {5, {D,  W,  F,  F,  D2},	1, 0, "Blindness"},
31     {6, {D,  W,  S,  S,  S,  P},0, 1, "Delayed Effect"},
32     {6, {D,  W,  W,  F,  W,  C2},0, 1,"Raise Dead"},
33     {6, {D,  W,  W,  F,  W,  D},0, 0, "Poison"},
34     {3, {F,  F,  F},		1, 0, "Paralysis"},
35     {5, {F,  P,  S,  F,  W},	0, 1, "Summon Troll"},
36     {5, {F,  S,  S,  D,  D},	0, 0, "Fireball"},
37     {1, {P},			0, 1, "Shield"},
38     {1, {P2},			0, 0, "SURRENDER"},
39     {4, {P,  D,  W,  P},	0, 1, "Remove Enchantment"},
40     {4, {P,  P,  W2, S2},	1, 1, "Invisibility"},
41     {4, {P,  S,  D,  D},	1, 0, "Charm Monster"},
42     {4, {P,  S,  D,  F},	1, 0, "Charm Person"},
43     {4, {P,  S,  F,  W},	0, 1, "Summon Ogre"},
44     {8, {P,  W,  P,  F,  S,  S,  S,  D},0,0,"Finger of Death"},
45     {6, {P,  W,  P,  W,  W,  C2},1, 1,"Haste"},
46     {2, {S,  D},		0, 0, "Missile"},
47     {3, {S,  F,  W},		0, 1, "Summon Goblin"},
48     {3, {S,  P,  F},		0, 0, "Anti-Spell"},
49     {7, {S,  P,  F,  P,  S,  D,  W},0,1,"Permanency"},
50     {4, {S,  P,  P,  C2},	0, 1, "Time Stop"},
51     {4, {S,  S,  F,  P},	1, 1, "Resist Cold"},
52     {3, {S,  W,  D},		1, 0, "Fear"},
53     {4, {S,  W,  W,  C2},	0, 0, "Fire Storm"},
54     {4, {W,  D,  D,  C2},	0, 0, "Lightning Bolt"},
55     {3, {W,  F,  P},		0, 0, "Cause Light Wounds"},
56     {6, {W,  F,  P,  S,  F,  W},0, 1, "Summon Giant"},
57     {4, {W,  P,  F,  D},	0, 0, "Cause Heavy Wounds"},
58     {3, {W,  P,  P},		0, 0, "Counter-Spell"},
59     {4, {W,  S,  S,  C2},	0, 0, "Ice Storm"},
60     {4, {W,  W,  F,  P},	1, 1, "Resist Heat"},
61     {3, {W,  W,  P},		1, 1, "Protection From Evil"},
62     {3, {W,  W,  S},		0, 0, "Counter-Spell"},
63     {1,	{Gesture_KNIFE},	0, 0, "stab"}
64 };
65 
66 #undef P
67 #undef D
68 #undef F
69 #undef W
70 #undef C
71 #undef S
72 #undef P2
73 #undef D2
74 #undef F2
75 #undef W2
76 #undef C2
77 #undef S2
78 
79 int reverse_sort_list[NUMSPELLS] = {
80     SP__LIGHTNING_BOLT2, SP__DISEASE, SP__TIME_STOP, SP__ICE_STORM, SP__RAISE_DEAD,
81     SP__HASTE, SP__FIRE_STORM, SP__LIGHTNING_BOLT, SP__CHARM_MONSTER, SP__FIREBALL,
82     SP__BLINDNESS, SP__CAUSE_HEAVY_WOUNDS, SP__MISSILE, SP__FINGER_OF_DEATH,
83     SP__POISON, SP__FEAR, SP__CHARM_PERSON, SP__PARALYSIS, SP__ANTI_SPELL,
84     SP__CONFUSION, SP__SHIELD, SP__SURRENDER, SP__RESIST_COLD, SP__CAUSE_LIGHT_WOUNDS,
85     SP__RESIST_HEAT, SP__AMNESIA, SP__COUNTER_SPELL, SP__DELAYED_EFFECT,
86     SP__REMOVE_ENCHANTMENT, SP__PROTECTION_FROM_EVIL, SP__INVISIBILITY,
87     SP__COUNTER_SPELL2, SP__SUMMON_ELEMENTAL, SP__MAGIC_MIRROR, SP__PERMANENCY,
88     SP__CURE_LIGHT_WOUNDS, SP__SUMMON_GOBLIN, SP__SUMMON_OGRE, SP__SUMMON_TROLL,
89     SP__SUMMON_GIANT, SP__DISPEL_MAGIC, SP__CURE_HEAVY_WOUNDS, SP__STAB
90 };
91 int alphabet_sort_list[NUMSPELLS] = {
92     SP__AMNESIA, SP__ANTI_SPELL, SP__BLINDNESS, SP__CAUSE_HEAVY_WOUNDS,
93     SP__CAUSE_LIGHT_WOUNDS, SP__CHARM_MONSTER, SP__CHARM_PERSON, SP__CONFUSION,
94     SP__COUNTER_SPELL, SP__COUNTER_SPELL2, SP__CURE_HEAVY_WOUNDS,
95     SP__CURE_LIGHT_WOUNDS, SP__DELAYED_EFFECT, SP__DISEASE, SP__DISPEL_MAGIC,
96     SP__FEAR, SP__FINGER_OF_DEATH, SP__FIRE_STORM, SP__FIREBALL, SP__HASTE,
97     SP__ICE_STORM, SP__INVISIBILITY, SP__LIGHTNING_BOLT, SP__LIGHTNING_BOLT2,
98     SP__MAGIC_MIRROR, SP__MISSILE, SP__PARALYSIS, SP__PERMANENCY, SP__POISON,
99     SP__PROTECTION_FROM_EVIL, SP__RAISE_DEAD, SP__REMOVE_ENCHANTMENT,
100     SP__RESIST_COLD, SP__RESIST_HEAT, SP__SHIELD, SP__SUMMON_ELEMENTAL,
101     SP__SUMMON_GIANT, SP__SUMMON_GOBLIN, SP__SUMMON_OGRE, SP__SUMMON_TROLL,
102     SP__SURRENDER, SP__TIME_STOP, SP__STAB
103 };
104 
check_one_spell(numgests,glist,mainhand,spel)105 static int check_one_spell(numgests, glist, mainhand, spel)
106 int numgests;
107 struct wizgesture *glist;
108 int mainhand;
109 struct spelldef *spel;
110 {
111     int otherhand = (1-mainhand);
112     int jx, result, pos;
113 
114     for (jx=spel->length-1; jx>=0; jx--) {
115 	pos = numgests - (spel->length - jx);
116 	if (pos<0) {
117 	    /* fell off beginning of gesture list */
118 	    return 0;
119 	}
120 	if (spel->gests[jx] & Gesture_DOUBLE) {
121 	    result = spel->gests[jx] & (~Gesture_DOUBLE);
122 	    if (!(glist[pos].did[mainhand] == result
123 		  && glist[pos].did[otherhand] == result)) {
124 		/* failed to do two-handed gesture */
125 		return 0;
126 	    }
127 	}
128 	else {
129 	    if (!(glist[pos].did[mainhand] == spel->gests[jx])) {
130 		/* failed to do one-handed gesture */
131 		 return 0;
132 	    }
133 	}
134     }
135 
136     return 1;
137 }
138 
139 /* writes results into found[] (OR of MASK_LEFT and MASK_RIGHT, or else MASK_BOTH) */
find_castspells(found,numgests,glist)140 void find_castspells(found, numgests, glist)
141 int *found; /* pointer to array[NUMSPELLS] */
142 int numgests;
143 struct wizgesture *glist;
144 {
145     int ix, result;
146     struct spelldef *spel;
147 
148     for (ix=0; ix<NUMSPELLS; ix++) {
149 	spel = &(spelllist[ix]);
150 	result = 0;
151 	if (check_one_spell(numgests, glist, 0, spel))
152 	    result |= MASK_LEFT;
153 	if (check_one_spell(numgests, glist, 1, spel))
154 	    result |= MASK_RIGHT;
155 	if (result && (spel->gests[spel->length-1] & Gesture_DOUBLE)) {
156 	    /* spell was completed with a double-handed gesture */
157 	    result = MASK_TWOHAND;
158 	}
159 	found[ix] = result;
160     }
161 }
162