Esempio n. 1
0
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 + ".");
		}
	}
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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 + ".");
	}
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
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;
    }
}