Example #1
0
/* virtual */ void CAnimation_Die::Action(CUnit &unit, int &/*move*/, int /*scale*/) const
{
	Assert(unit.Anim.Anim == this);
	if (unit.Anim.Unbreakable) {
		fprintf(stderr, "Can't call \"die\" action in unbreakable section\n");
		Exit(1);
	}
	if (this->DeathType.empty() == false) {
		unit.DamagedType = ExtraDeathIndex(this->DeathType.c_str());
	}
	throw AnimationDie_Exception();
}
/**
**  Define a unit-type animation set.
**
**  @param l  Lua state.
*/
static int CclDefineAnimations(lua_State *l)
{
	LuaCheckArgs(l, 2);
	if (!lua_istable(l, 2)) {
		LuaError(l, "incorrect argument");
	}

	const char *name = LuaToString(l, 1);
	CAnimations *anims = AnimationsByIdent(name);
	if (!anims) {
		anims = new CAnimations;
		AnimationMap[name] = anims;
	}

	lua_pushnil(l);
	while (lua_next(l, 2)) {
		const char *value = LuaToString(l, -2);

		if (!strcmp(value, "Start")) {
			anims->Start = ParseAnimation(l, -1);
		} else if (!strncmp(value, "Still", 5)) {
			anims->Still = ParseAnimation(l, -1);
		} else if (!strncmp(value, "Death", 5)) {
			if (strlen(value) > 5) {
				const int death = ExtraDeathIndex(value + 6);
				if (death == ANIMATIONS_DEATHTYPES) {
					anims->Death[ANIMATIONS_DEATHTYPES] = ParseAnimation(l, -1);
				} else {
					anims->Death[death] = ParseAnimation(l, -1);
				}
			} else {
				anims->Death[ANIMATIONS_DEATHTYPES] = ParseAnimation(l, -1);
			}
		} else if (!strcmp(value, "Attack")) {
			anims->Attack = ParseAnimation(l, -1);
		} else if (!strcmp(value, "SpellCast")) {
			anims->SpellCast = ParseAnimation(l, -1);
		} else if (!strcmp(value, "Move")) {
			anims->Move = ParseAnimation(l, -1);
		} else if (!strcmp(value, "Repair")) {
			anims->Repair = ParseAnimation(l, -1);
		} else if (!strcmp(value, "Train")) {
			anims->Train = ParseAnimation(l, -1);
		} else if (!strcmp(value, "Research")) {
			anims->Research = ParseAnimation(l, -1);
		} else if (!strcmp(value, "Upgrade")) {
			anims->Upgrade = ParseAnimation(l, -1);
		} else if (!strcmp(value, "Build")) {
			anims->Build = ParseAnimation(l, -1);
		} else if (!strncmp(value, "Harvest_", 8)) {
			const int res = GetResourceIdByName(l, value + 8);
			anims->Harvest[res] = ParseAnimation(l, -1);
		} else {
			LuaError(l, "Unsupported animation: %s" _C_ value);
		}
		lua_pop(l, 1);
	}
	// Must add to array in a fixed order for save games
	AddAnimationToArray(anims->Start);
	AddAnimationToArray(anims->Still);
	for (int i = 0; i != ANIMATIONS_DEATHTYPES + 1; ++i) {
		AddAnimationToArray(anims->Death[i]);
	}
	AddAnimationToArray(anims->Attack);
	AddAnimationToArray(anims->SpellCast);
	AddAnimationToArray(anims->Move);
	AddAnimationToArray(anims->Repair);
	AddAnimationToArray(anims->Train);
	for (int i = 0; i != MaxCosts; ++i) {
		AddAnimationToArray(anims->Harvest[i]);
	}
	return 0;
}
Example #3
0
/* virtual */ void CAnimation_SetVar::Action(CUnit &unit, int &/*move*/, int /*scale*/) const
{
	Assert(unit.Anim.Anim == this);

	char arg1[128];
	CUnit *goal = &unit;
	strcpy(arg1, this->varStr.c_str());

	if (this->unitSlotStr.empty() == false) {
		switch (this->unitSlotStr[0]) {
			case 'l': // last created unit
				goal = UnitManager.lastCreatedUnit();
				break;
			case 't': // target unit
				goal = unit.CurrentOrder()->GetGoal();
				break;
			case 's': // unit self (no use)
				goal = &unit;
				break;
		}
	}
	if (!goal) {
		return;
	}

	char *next = strchr(arg1, '.');
	if (next == NULL) {
		// Special case for non-CVariable variables
		if (!strcmp(arg1, "DamageType")) {
			int death = ExtraDeathIndex(this->valueStr.c_str());
			if (death == ANIMATIONS_DEATHTYPES) {
				fprintf(stderr, "Incorrect death type : %s \n" _C_ this->valueStr.c_str());
				Exit(1);
				return;
			}
			goal->Type->DamageType = this->valueStr;
			return;
		}
		fprintf(stderr, "Need also specify the variable '%s' tag \n" _C_ arg1);
		Exit(1);
		return;
	} else {
		*next = '\0';
	}
	const int index = UnitTypeVar.VariableNameLookup[arg1];// User variables
	if (index == -1) {
		fprintf(stderr, "Bad variable name '%s'\n" _C_ arg1);
		Exit(1);
		return;
	}

	const int rop = ParseAnimInt(unit, this->valueStr.c_str());
	int value = 0;
	if (!strcmp(next + 1, "Value")) {
		value = goal->Variable[index].Value;
	} else if (!strcmp(next + 1, "Max")) {
		value = goal->Variable[index].Max;
	} else if (!strcmp(next + 1, "Increase")) {
		value = goal->Variable[index].Increase;
	} else if (!strcmp(next + 1, "Enable")) {
		value = goal->Variable[index].Enable;
	} else if (!strcmp(next + 1, "Percent")) {
		value = goal->Variable[index].Value * 100 / goal->Variable[index].Max;
	}
	switch (this->mod) {
		case modAdd:
			value += rop;
			break;
		case modSub:
			value -= rop;
			break;
		case modMul:
			value *= rop;
			break;
		case modDiv:
			if (!rop) {
				fprintf(stderr, "Division by zero in AnimationSetVar\n");
				Exit(1);
				return;
			}
			value /= rop;
			break;
		case modMod:
			if (!rop) {
				fprintf(stderr, "Division by zero in AnimationSetVar\n");
				Exit(1);
				return;
			}
			value %= rop;
			break;
		case modAnd:
			value &= rop;
			break;
		case modOr:
			value |= rop;
			break;
		case modXor:
			value ^= rop;
			break;
		case modNot:
			value = !value;
			break;
		default:
			value = rop;
	}
	if (!strcmp(next + 1, "Value")) {
		goal->Variable[index].Value = value;
	} else if (!strcmp(next + 1, "Max")) {
		goal->Variable[index].Max = value;
	} else if (!strcmp(next + 1, "Increase")) {
		goal->Variable[index].Increase = value;
	} else if (!strcmp(next + 1, "Enable")) {
		goal->Variable[index].Enable = value;
	} else if (!strcmp(next + 1, "Percent")) {
		goal->Variable[index].Value = goal->Variable[index].Max * value / 100;
	}
	clamp(&goal->Variable[index].Value, 0, goal->Variable[index].Max);
	//Wyrmgus start
	if (index == ATTACKRANGE_INDEX && goal->Container) {
		goal->Container->UpdateContainerAttackRange();
	} else if (index == LEVEL_INDEX || index == POINTS_INDEX) {
		goal->UpdateXPRequired();
	} else if (index == XP_INDEX) {
		goal->XPChanged();
	} else if (index == STUN_INDEX && goal->Variable[index].Value > 0) { //if unit has become stunned, stop it
		CommandStopUnit(*goal);
	}
	//Wyrmgus end
}