3 float magicear_matched;
4 float W_Tuba_HasPlayed(entity pl, .entity weaponentity, string melody, float instrument, float ignorepitch, float mintempo, float maxtempo);
5 string trigger_magicear_processmessage(entity ear, entity source, float teamsay, entity privatesay, string msgin)
7 float domatch, dotrigger, matchstart, l;
11 magicear_matched = false;
13 dotrigger = ((IS_PLAYER(source)) && (!IS_DEAD(source)) && ((ear.radius == 0) || (vdist(source.origin - ear.origin, <=, ear.radius))));
14 domatch = ((ear.spawnflags & 32) || dotrigger);
21 // we are in TUBA mode!
22 if (!(ear.spawnflags & 256))
25 for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
27 .entity weaponentity = weaponentities[slot];
28 if(!W_Tuba_HasPlayed(source, weaponentity, ear.message, ear.movedir_x, !(ear.spawnflags & 512), ear.movedir_y, ear.movedir_z))
32 magicear_matched = true;
36 savemessage = ear.message;
37 ear.message = string_null;
38 SUB_UseTargets(ear, source, NULL);
39 ear.message = savemessage;
48 if(ear.spawnflags & 256) // ENOTUBA
53 if(ear.spawnflags & 4)
59 if(ear.spawnflags & 1)
62 if(ear.spawnflags & 2)
65 if(ear.spawnflags & 8)
70 l = strlen(ear.message);
72 if(ear.spawnflags & 128)
75 msg = strdecolorize(msgin);
77 if(substring(ear.message, 0, 1) == "*")
79 if(substring(ear.message, -1, 1) == "*")
82 // as we need multi-replacement here...
83 s = substring(ear.message, 1, -2);
85 if(strstrofs(msg, s, 0) >= 0)
86 matchstart = -2; // we use strreplace on s
91 s = substring(ear.message, 1, -1);
93 if(substring(msg, -l, l) == s)
94 matchstart = strlen(msg) - l;
99 if(substring(ear.message, -1, 1) == "*")
102 s = substring(ear.message, 0, -2);
104 if(substring(msg, 0, l) == s)
111 if(msg == ear.message)
116 if(matchstart == -1) // no match
119 magicear_matched = true;
123 savemessage = ear.message;
124 ear.message = string_null;
125 SUB_UseTargets(ear, source, NULL);
126 ear.message = savemessage;
129 if(ear.spawnflags & 16)
133 else if(ear.netname != "")
136 return strreplace(s, ear.netname, msg);
139 substring(msg, 0, matchstart),
141 substring(msg, matchstart + l, -1)
149 string trigger_magicear_processmessage_forallears(entity source, float teamsay, entity privatesay, string msgin)
153 for(ear = magicears; ear; ear = ear.enemy)
155 msgout = trigger_magicear_processmessage(ear, source, teamsay, privatesay, msgin);
156 if(!(ear.spawnflags & 64))
164 spawnfunc(trigger_magicear)
166 this.enemy = magicears;
169 // actually handled in "say" processing
172 // 2 = ignore teamsay
174 // 8 = ignore tell to unknown player
175 // 16 = let netname replace the whole message (otherwise, netname is a word replacement if set)
176 // 32 = perform the replacement even if outside the radius or dead
177 // 64 = continue replacing/triggering even if this one matched
178 // 128 = don't decolorize message before matching
179 // 256 = message is a tuba note sequence (pitch.duration pitch.duration ...)
180 // 512 = tuba notes must be exact right pitch, no transposing
190 // if set, replacement for the matched text
192 // "hearing distance"
196 // for spawnflags 256, defines 'instrument+1 mintempo maxtempo' (zero component doesn't matter)
198 this.movedir_x -= 1; // map to tuba instrument numbers