void Battle::DoSpecialAttack(int round, Soldier *a, Army *attackers, Army *def, int behind) { SpecialType *spd; int i, num, tot = -1; AString results[4]; int dam = 0; if(a->special == NULL) return; spd = FindSpecial(a->special); if(!(spd->effectflags & SpecialType::FX_DAMAGE)) return; for(i = 0; i < 4; i++) { if(spd->damage[i].type == -1) continue; int times = spd->damage[i].value; if(spd->effectflags & SpecialType::FX_USE_LEV) times *= a->slevel; int realtimes = spd->damage[i].minnum + getrandom(times) + getrandom(times); num = def->DoAnAttack(a->special, realtimes, spd->damage[i].type, a->slevel, spd->damage[i].flags, spd->damage[i].dclass, spd->damage[i].effect, 0); if(spd->effectflags & SpecialType::FX_DONT_COMBINE && num != -1) { if(spd->damage[i].effect == NULL) { results[dam] = AString("killing ") + num; dam++; } else { results[dam] = AString(spd->spelldesc2) + num; } } if(num != -1) { if(tot == -1) tot = num; else tot += num; } } if(tot == -1) { AddLine(a->name + " " + spd->spelldesc + ", but it is deflected."); } else { if(spd->effectflags & SpecialType::FX_DONT_COMBINE) { AString temp = a->name + " " + spd->spelldesc; for(i = 0; i < dam; i++) { if(i) temp += ", "; if(i == dam-1) temp += " and "; temp += results[dam]; } temp += AString(spd->spelltarget) + "."; AddLine(temp); } else { AddLine(a->name + " " + spd->spelldesc + ", " + spd->spelldesc2 + tot + spd->spelltarget + "."); } } }
bool FLARM::SendEscaped(Port &port, const void *buffer, size_t length, OperationEnvironment &env, unsigned timeout_ms) { assert(buffer != nullptr); assert(length > 0); const TimeoutClock timeout(timeout_ms); // Send data byte-by-byte including escaping const uint8_t *p = (const uint8_t *)buffer, *end = p + length; while (true) { const uint8_t *special = FindSpecial(p, end); if (special > p) { /* bulk write of "harmless" characters */ if (!port.FullWrite(p, special - p, env, timeout.GetRemainingOrZero())) return false; p = special; } if (p == end) break; // Check for bytes that need to be escaped and send // the appropriate replacements bool result; if (*p == START_FRAME) result = port.Write(ESCAPE) && port.Write(ESCAPE_START); else if (*p == ESCAPE) result = port.Write(ESCAPE) && port.Write(ESCAPE_ESCAPE); else // Otherwise just send the original byte result = port.Write(*p); if (!result) return false; p++; } return true; }
void Battle::UpdateShields(Army *a) { for (int i=0; i<a->notbehind; i++) { int shtype = -1; SpecialType *spd; if(a->soldiers[i]->special == NULL) continue; spd = FindSpecial(a->soldiers[i]->special); if(!(spd->effectflags & SpecialType::FX_SHIELD) && !(spd->effectflags & SpecialType::FX_DEFBONUS)) continue; if(spd->effectflags & SpecialType::FX_SHIELD) { for(shtype = 0; shtype < 4; shtype++) { if(spd->shield[shtype] == -1) continue; Shield *sh = new Shield; sh->shieldtype = spd->shield[shtype]; sh->shieldskill = a->soldiers[i]->slevel; a->shields.Add(sh); } } if(spd->effectflags & SpecialType::FX_DEFBONUS && a->round == 0) { for(shtype = 0; shtype < 4; shtype++) { if(spd->defs[shtype].type == -1) continue; int bonus = spd->defs[shtype].val; if(spd->effectflags & SpecialType::FX_USE_LEV) bonus *= a->soldiers[i]->slevel; a->soldiers[i]->dskill[spd->defs[shtype].type] += bonus; } } AddLine(*(a->soldiers[i]->unit->name) + " casts " + spd->shielddesc + "."); } }
int Army::CheckSpecialTarget(char *special,int tar) { SpecialType *spd = FindSpecial(special); int i; int match = 0; if(spd->targflags & SpecialType::HIT_BUILDINGIF) { match = 0; if(!soldiers[tar]->building) return 0; for(i = 0; i < 3; i++) { if (soldiers[tar]->building && (spd->buildings[i] == soldiers[tar]->building)) match = 1; } if(!match) return 0; } if(spd->targflags & SpecialType::HIT_BUILDINGEXCEPT) { match = 0; if(!soldiers[tar]->building) return 0; for(i = 0; i < 3; i++) { if (soldiers[tar]->building && (spd->buildings[i] == soldiers[tar]->building)) match = 1; } if(match) return 0; } if(spd->targflags & SpecialType::HIT_SOLDIERIF) { match = 0; if (soldiers[tar]->race == -1) return 0; for(i = 0; i < 7; i++) { if(soldiers[tar]->race == spd->targets[i]) match = 1; } if(!match) return 0; } if(spd->targflags & SpecialType::HIT_SOLDIEREXCEPT) { match = 0; if (soldiers[tar]->race == -1) return 0; for(i = 0; i < 7; i++) { if(soldiers[tar]->race == spd->targets[i]) match = 1; } if(match) return 0; } if(spd->targflags & SpecialType::HIT_EFFECTIF) { match = 0; for(i = 0; i < 3; i++) { if(soldiers[tar]->HasEffect(spd->effects[i])) match = 1; } if(!match) return 0; } if(spd->targflags & SpecialType::HIT_EFFECTEXCEPT) { match = 0; for(i = 0; i < 3; i++) { if(soldiers[tar]->HasEffect(spd->effects[i])) match = 1; } if(match) return 0; } if(spd->targflags & SpecialType::HIT_MOUNTIF) { match = 0; if (soldiers[tar]->riding == -1) return 0; for(i = 0; i < 7; i++) { if(soldiers[tar]->riding == spd->targets[i]) match = 1; } if(!match) return 0; } if(spd->targflags & SpecialType::HIT_MOUNTEXCEPT) { match = 0; if (soldiers[tar]->riding == -1) return 0; for(i = 0; i < 7; i++) { if(soldiers[tar]->riding == spd->targets[i]) match = 1; } if(match) return 0; } if(spd->targflags & SpecialType::HIT_ILLUSION) { // All illusions are of type monster, so lets make sure we get it // right. If we ever have other types of illusions, we can change // this. if(!(ItemDefs[soldiers[tar]->race].type & IT_MONSTER)) return 0; if(!(ItemDefs[soldiers[tar]->race].type & IT_ILLUSION)) return 0; } if(spd->targflags & SpecialType::HIT_NOMONSTER) { if(ItemDefs[soldiers[tar]->race].type & IT_MONSTER) return 0; } return 1; }
static int input_callback(IDL_input_reason reason, union IDL_input_data *cb_data, gpointer user_data) { input_callback_state *callback_state = user_data; input_data *data = callback_state->input_stack; input_data *new_data = NULL; unsigned int len, copy; int rv; char *start; switch(reason) { case IDL_INPUT_REASON_INIT: if (data == NULL || data->next == NULL) { /* * This is the first file being processed. As it's the target * file, we only look for it in the first entry in the include * path, which we assume to be the current directory. */ /* XXXmccabe proper assumption? Do we handle files in other directories? */ IncludePathEntry first_entry; first_entry.directory = callback_state->include_path->directory; first_entry.next = NULL; new_data = new_input_data(cb_data->init.filename, &first_entry); } else { new_data = new_input_data(cb_data->init.filename, callback_state->include_path); } if (!new_data) return -1; IDL_file_set(new_data->filename, (int)new_data->lineno); callback_state->input_stack = new_data; return 0; case IDL_INPUT_REASON_FILL: start = NULL; len = 0; while (data->point >= data->max) { if (!data->next) return 0; /* Current file is done; revert to including file */ callback_state->input_stack = data->next; free(data->filename); free(data->buf); free(data); data = callback_state->input_stack; IDL_file_set(data->filename, (int)data->lineno); IDL_inhibit_pop(); } /* * Now we scan for sequences which require special attention: * \n#include begins an include statement * \n%{ begins a raw-source block * /\* begins a comment * * We used to be fancier here, so make sure that we sent the most * data possible at any given time. To that end, we skipped over * \n%{ raw \n%} blocks and then _continued_ the search for special * sequences like \n#include or /\* comments . * * It was really ugly, though -- liberal use of goto! lots of implicit * state! what fun! -- so now we just do this: * * if (special at start) { * process that special - * - raw: send it to libIDL, and don't look inside for specials * - comments: adjust point and start over * - includes: push new input_data struct for included file, and * start over * } else { * scan for next special * send data up to that special to libIDL * } * * If len is set to zero, it is a sentinel value indicating we a comment * or include was found, and parsing should start over. * * XXX const string foo = "/\*" will just screw us horribly. * Hm but. We could treat strings as we treat raw blocks, eh? */ /* * Order is important, so that you can have /\* comments and * #includes within raw sections, and so that you can comment out * #includes. */ rv = NextIsRaw(data, &start, (int *)&len); if (rv == -1) return -1; if (!rv) { /* * When NextIsComment succeeds, it returns a 0 len (requesting a * restart) and adjusts data->point to pick up after the comment. */ rv = NextIsComment(data, &start, (int *)&len); if (rv == -1) return -1; if (!rv) { /* * NextIsInclude might push a new input_data struct; if so, it * will return a 0 len, letting the callback pick up the new * file the next time around. */ rv = NextIsInclude(callback_state, &start, (int *)&len); if (rv == -1) return -1; if (!rv) FindSpecial(data, &start, (int *)&len); } } if (len == 0) { /* * len == 0 is a sentinel value that means we found a comment or * include. If we found a comment, point has been adjusted to * point past the comment. If we found an include, a new input_data * has been pushed. In both cases, calling the input_callback again * will pick up the new state. */ return input_callback(reason, cb_data, user_data); } copy = MIN(len, (unsigned int) cb_data->fill.max_size); memcpy(cb_data->fill.buffer, start, copy); data->point = start + copy; if (tracefile) fwrite(cb_data->fill.buffer, copy, 1, tracefile); return copy; case IDL_INPUT_REASON_ABORT: case IDL_INPUT_REASON_FINISH: while (data != NULL) { input_data *next; next = data->next; free(data->filename); free(data->buf); free(data); data = next; } return 0; default: g_error("unknown input reason %d!", reason); return -1; } }