예제 #1
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Check if the given tile is a valid destination. In case of for example
 *  a carry-all it checks if the unit carrying can be placed on destination.
 * In case of structures, it checks if you can walk into it.
 *
 * Stack: 1 - An encoded tile, indicating the destination.
 *
 * @param script The script engine to operate on.
 * @return ??.
 */
uint16 Script_Unit_IsValidDestination(ScriptEngine *script)
{
	Unit *u;
	Unit *u2;
	uint16 encoded;
	uint16 index;

	u = g_scriptCurrentUnit;
	encoded = STACK_PEEK(1);
	index = Tools_Index_Decode(encoded);

	switch (Tools_Index_GetType(encoded)) {
		case IT_TILE:
			if (!Map_IsValidPosition(index)) return 1;
			if (u->o.linkedID == 0xFF) return 1;
			u2 = Unit_Get_ByIndex(u->o.linkedID);
			u2->o.position = Tools_Index_GetTile(encoded);
			if (!Unit_IsTileOccupied(u2)) return 0;
			u2->o.position.tile = 0xFFFFFFFF;
			return 1;

		case IT_STRUCTURE: {
			Structure *s;

			s = Structure_Get_ByIndex(index);
			if (s->o.houseID == Unit_GetHouseID(u)) return 0;
			if (u->o.linkedID == 0xFF) return 1;
			u2 = Unit_Get_ByIndex(u->o.linkedID);
			return Unit_IsValidMovementIntoStructure(u2, s) != 0 ? 1 : 0;
		}

		default: return 1;
	}
}
예제 #2
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Set the new destination of the unit.
 *
 * Stack: 1 - An encoded index where to move to.
 *
 * @param script The script engine to operate on.
 * @return The value 0. Always.
 */
uint16 Script_Unit_SetDestination(ScriptEngine *script)
{
	Unit *u;
	uint16 encoded;

	u = g_scriptCurrentUnit;
	encoded = STACK_PEEK(1);

	if (encoded == 0 || !Tools_Index_IsValid(encoded)) {
		u->targetMove = 0;
		return 0;
	}

	if (u->o.type == UNIT_HARVESTER) {
		Structure *s;

		s = Tools_Index_GetStructure(encoded);
		if (s == NULL) {
			u->targetMove = encoded;
			u->route[0] = 0xFF;
			return 0;
		}

		if (s->o.script.variables[4] != 0) return 0;
	}

	Unit_SetDestination(u, encoded);
	return 0;
}
예제 #3
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Set a new target, and rotate towards him if needed.
 *
 * Stack: 1 - An encoded tile of the unit/tile to target.
 *
 * @param script The script engine to operate on.
 * @return The new target.
 */
uint16 Script_Unit_SetTarget(ScriptEngine *script)
{
	Unit *u;
	uint16 target;
	tile32 tile;
	int8 orientation;

	u = g_scriptCurrentUnit;

	target = STACK_PEEK(1);

	if (target == 0 || !Tools_Index_IsValid(target)) {
		u->targetAttack = 0;
		return 0;
	}

	tile = Tools_Index_GetTile(target);

	orientation = Tile_GetDirection(u->o.position, tile);

	u->targetAttack = target;
	if (!g_table_unitInfo[u->o.type].o.flags.hasTurret) {
		u->targetMove = target;
		Unit_SetOrientation(u, orientation, false, 0);
	}
	Unit_SetOrientation(u, orientation, false, 1);

	return u->targetAttack;
}
예제 #4
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Finds a structure.
 *
 * Stack: 1 - A structure type.
 *
 * @param script The script engine to operate on.
 * @return An encoded structure index, or 0 if none found.
 */
uint16 Script_Unit_FindStructure(ScriptEngine *script)
{
	Unit *u;
	PoolFindStruct find;

	u = g_scriptCurrentUnit;

	find.houseID = Unit_GetHouseID(u);
	find.index   = 0xFFFF;
	find.type    = STACK_PEEK(1);

	while (true) {
		Structure *s;

		s = Structure_Find(&find);
		if (s == NULL) break;
		if (s->state != STRUCTURE_STATE_IDLE) continue;
		if (s->o.linkedID != 0xFF) continue;
		if (s->o.script.variables[4] != 0) continue;

		return Tools_Index_Encode(s->o.index, IT_STRUCTURE);
	}

	return 0;
}
예제 #5
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Get information about the unit, like hitpoints, current target, etc.
 *
 * Stack: 1 - Which information you would like.
 *
 * @param script The script engine to operate on.
 * @return The information you requested.
 */
uint16 Script_Unit_GetInfo(ScriptEngine *script)
{
	const UnitInfo *ui;
	Unit *u;

	u = g_scriptCurrentUnit;
	ui = &g_table_unitInfo[u->o.type];

	switch (STACK_PEEK(1)) {
		case 0x00: return u->o.hitpoints * 256 / ui->o.hitpoints;
		case 0x01: return Tools_Index_IsValid(u->targetMove) ? u->targetMove : 0;
		case 0x02: return ui->fireDistance << 8;
		case 0x03: return u->o.index;
		case 0x04: return u->orientation[0].current;
		case 0x05: return u->targetAttack;
		case 0x06:
			if (u->originEncoded == 0 || u->o.type == UNIT_HARVESTER) Unit_FindClosestRefinery(u);
			return u->originEncoded;
		case 0x07: return u->o.type;
		case 0x08: return Tools_Index_Encode(u->o.index, IT_UNIT);
		case 0x09: return u->movingSpeed;
		case 0x0A: return abs(u->orientation[0].target - u->orientation[0].current);
		case 0x0B: return u->currentDestination.tile == 0 ? 0 : 1;
		case 0x0C: return u->fireDelay == 0 ? 1 : 0;
		case 0x0D: return ui->flags.explodeOnDeath;
		case 0x0E: return Unit_GetHouseID(u);
		case 0x0F: return u->o.flags.s.byScenario ? 1 : 0;
		case 0x10: return u->orientation[ui->o.flags.hasTurret ? 1 : 0].current;
		case 0x11: return abs(u->orientation[ui->o.flags.hasTurret ? 1 : 0].target - u->orientation[ui->o.flags.hasTurret ? 1 : 0].current);
		case 0x12: return (ui->movementType & 0x40) == 0 ? 0 : 1;
		case 0x13: return (u->o.seenByHouses & (1 << g_playerHouseID)) == 0 ? 0 : 1;
		default:   return 0;
	}
}
예제 #6
0
파일: team.c 프로젝트: 166MMX/OpenDUNE
/**
 * Draws a string.
 *
 * Stack: 1 - The index of the string to draw.
 *        2-4 - The arguments for the string.
 *
 * @param script The script engine to operate on.
 * @return The value 0. Always.
 */
uint16 Script_Team_DisplayText(ScriptEngine *script)
{
	Team *t;
	char *text;
	uint16 offset;

	t = g_scriptCurrentTeam;
	if (t->houseID == g_playerHouseID) return 0;

	offset = BETOH16(*(script->scriptInfo->text + STACK_PEEK(1)));
	text = (char *)script->scriptInfo->text + offset;

	GUI_DisplayText(text, 0, STACK_PEEK(2), STACK_PEEK(3), STACK_PEEK(4));

	return 0;
}
예제 #7
0
파일: structure.c 프로젝트: rofl0r/OpenDUNE
/**
 * Find a UnitType and make it go to the current structure. In general, type
 *  should be a Carry-All for this to make any sense.
 *
 * Stack: 1 - An unit type.
 *
 * @param script The script engine to operate on.
 * @return unknown.
 */
uint16 Script_Structure_FindUnitByType(ScriptEngine *script)
{
	Structure *s;
	Unit *u;
	Unit *carryall;
	uint16 type;
	uint16 position;
	uint16 carryallIndex;

	s = g_scriptCurrentStructure;

	if (s->state != STRUCTURE_STATE_READY) return IT_NONE;
	if (s->o.linkedID == 0xFF) return IT_NONE;

	type = STACK_PEEK(1);

	position = Structure_FindFreePosition(s, false);

	u = Unit_Get_ByIndex(s->o.linkedID);

	if (g_playerHouseID == s->o.houseID && u->o.type == UNIT_HARVESTER && u->targetLast.tile == 0 && position != 0) {
		return IT_NONE;
	}

	carryall = Unit_CallUnitByType(type, s->o.houseID, Tools_Index_Encode(s->o.index, IT_STRUCTURE), position == 0);

	if (carryall == NULL) return IT_NONE;

	carryallIndex = Tools_Index_Encode(carryall->o.index, IT_UNIT);
	Object_Script_Variable4_Set(&s->o, carryallIndex);

	return carryallIndex;
}
예제 #8
0
int StartElement(void *UserData, const XMLCH *uri, const XMLCH *localName, const XMLCH *qName, LPXMLVECTOR atts)
{	
	XMLCONFPARSER *xcp = (XMLCONFPARSER*)UserData;
	LPXMLRUNTIMEATT att;
	int *pstate = STACK_PEEK(xcp->stateStack);
	xcp->state = (pstate) ? *pstate : NONE;
	
	if (xcp->inMixedContent || xcp->state == TEST) { 
		/* + other tags that allow mixed content tested here */
		/* if we're in mixed content, we don't bother to use stack, just
		   incrementing (and decrementing in EndElement) the counter: */
		xcp->inMixedContent++;	
		/* could call mixed content legal tag check routine here e.g.
		if (!isvalidmixedcontent(state, qName)) return sin(); */
		fprintf(PFOUT, "<%s>", qName);
		return 0;
	}
	
	if (xcp->state == NONE && !strcmp(qName, "TESTSUITE")) { 
		
		if (att = XMLParser_GetNamedItem(xcp->parser, "PROFILE"))
			fprintf(PFOUT, "<h1><b>%s</b></h1><br><h3>Parsifal XML Parser %s</h3>", 
				att->value, XMLParser_GetVersionString());		
		xcp->state = TESTSUITE;
	}
	else if (xcp->state == TESTSUITE && !strcmp(qName, "TESTCASES")) {
		
		if (att = XMLParser_GetNamedItem(xcp->parser, "PROFILE")) {
			/* new testcase, spit out the profile header: */
			fprintf(PFOUT, "<br><br><h2>Testcase profile: <b>%s</b></h2><br>", att->value);
			fputs("<table cellspacing='0'>", PFOUT); /* open table for results */
		}
		xcp->state = TESTCASES;
	}
	else if (xcp->state == TESTCASES) {
		
		if (!strcmp(qName, "TEST")) {			
			if (att = XMLParser_GetNamedItem(xcp->parser, "URI")) {
				/* new test, run it: */
				if (!RunTest(xcp, att->value))
					fprintf(PFERR, "Fatal Error running test: %s\n", att->value);
			}
			xcp->state = TEST;
		}
		else if (!strcmp(qName, "TESTCASES")) { /* for some reason

			there's TESTCASES inside TESTCASES in ibm tests,
			so it must ust be handled here: */
			xcp->state = TESTCASES;
		}
	}
	else {
		fprintf(PFERR, "Unexpected tag: %s\n", qName);
		return XML_ABORT;
	}

	STACK_PUSH(xcp->stateStack, &xcp->state);
	return 0;
}
예제 #9
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Gets the best target for the current unit.
 *
 * Stack: 1 - How to determine the best target.
 *
 * @param script The script engine to operate on.
 * @return The encoded index of the best target or 0 if none found.
 */
uint16 Script_Unit_FindBestTarget(ScriptEngine *script)
{
	Unit *u;

	u = g_scriptCurrentUnit;

	return Unit_FindBestTargetEncoded(u, STACK_PEEK(1));
}
예제 #10
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Calculate the route to a tile.
 *
 * Stack: 1 - An encoded tile to calculate the route to.
 *
 * @param script The script engine to operate on.
 * @return 0 if we arrived on location, 1 otherwise.
 */
uint16 Script_Unit_CalculateRoute(ScriptEngine *script)
{
	Unit *u;
	uint16 encoded;
	uint16 packedSrc;
	uint16 packedDst;

	u = g_scriptCurrentUnit;
	encoded = STACK_PEEK(1);

	if (u->currentDestination.tile != 0 || !Tools_Index_IsValid(encoded)) return 1;

	packedSrc = Tile_PackTile(u->o.position);
	packedDst = Tools_Index_GetPackedTile(encoded);

	if (packedDst == packedSrc) {
		u->route[0] = 0xFF;
		u->targetMove = 0;
		return 0;
	}

	if (u->route[0] == 0xFF) {
		Pathfinder_Data res;
		uint8 buffer[42];

		res = Script_Unit_Pathfinder(packedSrc, packedDst, buffer, 40);

		memcpy(u->route, res.buffer, min(res.routeSize, 14));

		if (u->route[0] == 0xFF) {
			u->targetMove = 0;
			if (u->o.type == UNIT_SANDWORM) {
				script->delay = 720;
			}
		}
	} else {
		uint16 distance;

		distance = Tile_GetDistancePacked(packedDst, packedSrc);
		if (distance < 14) u->route[distance] = 0xFF;
	}

	if (u->route[0] == 0xFF) return 1;

	if (u->orientation[0].current != (int8)(u->route[0] * 32)) {
		Unit_SetOrientation(u, (int8)(u->route[0] * 32), false, 0);
		return 1;
	}

	if (!Unit_StartMovement(u)) {
		u->route[0] = 0xFF;
		return 0;
	}

	memmove(&u->route[0], &u->route[1], 13);
	u->route[13] = 0xFF;
	return 1;
}
예제 #11
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Make an explosion at the coordinates of the unit.
 *  It does damage to the surrounding units based on the unit.
 *
 * Stack: 1 - Explosion type
 *
 * @param script The script engine to operate on.
 * @return The value 0. Always.
 */
uint16 Script_Unit_ExplosionSingle(ScriptEngine *script)
{
	Unit *u;

	u = g_scriptCurrentUnit;

	Map_MakeExplosion(STACK_PEEK(1), u->o.position, g_table_unitInfo[u->o.type].o.hitpoints, Tools_Index_Encode(u->o.index, IT_UNIT));
	return 0;
}
예제 #12
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Set the orientation of a unit.
 *
 * Stack: 1 - New orientation for unit.
 *
 * @param script The script engine to operate on.
 * @return The current orientation of the unit (it will move to the requested over time).
 */
uint16 Script_Unit_SetOrientation(ScriptEngine *script)
{
	Unit *u;

	u = g_scriptCurrentUnit;

	Unit_SetOrientation(u, (int8)STACK_PEEK(1), false, 0);

	return u->orientation[0].current;
}
예제 #13
0
파일: structure.c 프로젝트: rofl0r/OpenDUNE
/**
 * Rotate the turret to look at a tile.
 *
 * Stack: 1 - Tile to look at.
 *
 * @param script The script engine to operate on.
 * @return 0 if looking at target, otherwise 1.
 */
uint16 Script_Structure_RotateTurret(ScriptEngine *script)
{
	Structure *s;
	tile32 lookAt;
	Tile *tile;
	uint16 baseSpriteID;
	uint16 encoded;
	int16 rotation;
	int16 rotationNeeded;
	int16 rotateDiff;

	encoded = STACK_PEEK(1);

	if (encoded == 0) return 0;

	s      = g_scriptCurrentStructure;
	lookAt = Tools_Index_GetTile(encoded);
	tile   = &g_map[Tile_PackTile(s->o.position)];

	/* Find the base sprite of the structure */
	if (s->o.type == STRUCTURE_ROCKET_TURRET) {
		baseSpriteID = g_iconMap[g_iconMap[ICM_ICONGROUP_BASE_ROCKET_TURRET] + 2];
	} else {
		baseSpriteID = g_iconMap[g_iconMap[ICM_ICONGROUP_BASE_DEFENSE_TURRET] + 2];
	}

	rotation = tile->groundSpriteID - baseSpriteID;
	if (rotation < 0 || rotation > 7) return 1;

	/* Find what rotation we should have to look at the target */
	rotationNeeded = Orientation_Orientation256ToOrientation8(Tile_GetDirection(s->o.position, lookAt));

	/* Do we need to rotate */
	if (rotationNeeded == rotation) return 0;

	/* Find the fastest way to rotate to the correct rotation */
	rotateDiff = rotationNeeded - rotation;
	if (rotateDiff < 0) rotateDiff += 8;

	if (rotateDiff < 4) {
		rotation++;
	} else {
		rotation--;
	}
	rotation &= 0x7;

	/* Set the new sprites */
	tile->groundSpriteID = baseSpriteID + rotation;
	s->rotationSpriteDiff = rotation;

	Map_Update(Tile_PackTile(s->o.position), 0, false);

	return 1;
}
예제 #14
0
int XMLAPI DTDValidate_Characters(void *UserData, 
								  const XMLCH *chars, int cbSize)
{	
	LPXMLDTDVALIDATOR v = (LPXMLDTDVALIDATOR)UserData;
	struct vContext *c = STACK_PEEK(v->ContextStack);
	if (c && !(c->e->type ==  XMLCTYPE_MIXED || c->e->type == XMLCTYPE_ANY)) {
		Er_(v, NULL, ERR_XMLDTDV_PCDATA_NOT_ALLOWED, c->e->name);
		MAYRET(XML_ABORT);
	}
	return (v->charactersHandler) ? v->charactersHandler(v, chars, cbSize) : 0;
}
예제 #15
0
int XMLAPI DTDValidate_IgnorableWhitespace(void *UserData, 
										   const XMLCH *chars, int cbSize)
{
	LPXMLDTDVALIDATOR v = (LPXMLDTDVALIDATOR)UserData;
	struct vContext *c = STACK_PEEK(v->ContextStack);
	if (c && (c->e->type ==  XMLCTYPE_MIXED || c->e->type == XMLCTYPE_ANY)) {
		return (v->charactersHandler) ? v->charactersHandler(v, chars, cbSize) : 0;
	}
	return (v->ignorableWhitespaceHandler) ? 
		v->ignorableWhitespaceHandler(v, chars, cbSize) : 0;
}
예제 #16
0
파일: structure.c 프로젝트: rofl0r/OpenDUNE
/**
 * Play a voice on the structure.
 *
 * Stack: 1 - The VoiceID to play.
 *
 * @param script The script engine to operate on.
 * @return unknown.
 */
uint16 Script_Structure_VoicePlay(ScriptEngine *script)
{
	Structure *s;

	s = g_scriptCurrentStructure;

	if (s->o.houseID != g_playerHouseID) return 0;

	Voice_PlayAtTile(STACK_PEEK(1), s->o.position);

	return 0;
}
예제 #17
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Change the sprite (offset) of the unit.
 *
 * Stack: 1 - The new sprite offset.
 *
 * @param script The script engine to operate on.
 * @return The value 0. Always.
 */
uint16 Script_Unit_SetSprite(ScriptEngine *script)
{
	Unit *u;

	u = g_scriptCurrentUnit;

	u->spriteOffset = -(STACK_PEEK(1) & 0xFF);

	Unit_UpdateMap(2, u);

	return 0;
}
예제 #18
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Get a random tile around the Unit.
 *
 * Stack: 1 - An encoded index of a tile, completely ignored, as long as it is a tile.
 *
 * @param script The script engine to operate on.
 * @return An encoded tile, or 0.
 */
uint16 Script_Unit_GetRandomTile(ScriptEngine *script)
{
	Unit *u;
	tile32 tile;

	u = g_scriptCurrentUnit;

	if (Tools_Index_GetType(STACK_PEEK(1)) != IT_TILE) return 0;

	tile = Tile_MoveByRandom(u->o.position, 80, true);

	return Tools_Index_Encode(Tile_PackTile(tile), IT_TILE);
}
예제 #19
0
파일: team.c 프로젝트: 166MMX/OpenDUNE
/**
 * Unknown function 0543.
 *
 * Stack: 1 - A distance.
 *
 * @param script The script engine to operate on.
 * @return The number of moving units.
 */
uint16 Script_Team_Unknown0543(ScriptEngine *script)
{
	Team *t;
	uint16 count = 0;
	uint16 distance;
	PoolFindStruct find;

	t = g_scriptCurrentTeam;
	distance = STACK_PEEK(1);

	find.houseID = t->houseID;
	find.index   = 0xFFFF;
	find.type    = 0xFFFF;

	while (true) {
		Unit *u;
		tile32 tile;
		uint16 distanceUnitDest;
		uint16 distanceUnitTeam;
		uint16 distanceTeamDest;

		u = Unit_Find(&find);
		if (u == NULL) break;
		if (t->index != u->team - 1) continue;

		tile = Tools_Index_GetTile(u->targetMove);
		distanceUnitTeam = Tile_GetDistanceRoundedUp(u->o.position, t->position);

		if (u->targetMove != 0) {
			distanceUnitDest = Tile_GetDistanceRoundedUp(u->o.position, tile);
			distanceTeamDest = Tile_GetDistanceRoundedUp(t->position, tile);
		} else {
			distanceUnitDest = 64;
			distanceTeamDest = 64;
		}

		if ((distanceUnitDest < distanceTeamDest && (distance + 2) < distanceUnitTeam) || (distanceUnitDest >= distanceTeamDest && distanceUnitTeam > distance)) {
			Unit_SetAction(u, ACTION_MOVE);

			tile = Tile_MoveByRandom(t->position, distance << 4, true);

			Unit_SetDestination(u, Tools_Index_Encode(Tile_PackTile(tile), IT_TILE));
			count++;
			continue;
		}

		Unit_SetAction(u, ACTION_GUARD);
	}

	return count;
}
예제 #20
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Move the unit to the first available structure it can find of the required
 *  type.
 *
 * Stack: 1 - Type of structure.
 *
 * @param script The script engine to operate on.
 * @return An encoded structure index.
 */
uint16 Script_Unit_MoveToStructure(ScriptEngine *script)
{
	Unit *u;
	PoolFindStruct find;

	u = g_scriptCurrentUnit;

	if (u->o.linkedID != 0xFF) {
		Structure *s;

		s = Tools_Index_GetStructure(Unit_Get_ByIndex(u->o.linkedID)->originEncoded);

		if (s != NULL && s->state == STRUCTURE_STATE_IDLE && s->o.script.variables[4] == 0) {
			uint16 encoded;

			encoded = Tools_Index_Encode(s->o.index, IT_STRUCTURE);

			Object_Script_Variable4_Link(Tools_Index_Encode(u->o.index, IT_UNIT), encoded);

			u->targetMove = u->o.script.variables[4];

			return encoded;
		}
	}

	find.houseID = Unit_GetHouseID(u);
	find.index   = 0xFFFF;
	find.type    = STACK_PEEK(1);

	while (true) {
		Structure *s;
		uint16 encoded;

		s = Structure_Find(&find);
		if (s == NULL) break;

		if (s->state != STRUCTURE_STATE_IDLE) continue;
		if (s->o.script.variables[4] != 0) continue;

		encoded = Tools_Index_Encode(s->o.index, IT_STRUCTURE);

		Object_Script_Variable4_Link(Tools_Index_Encode(u->o.index, IT_UNIT), encoded);

		u->targetMove = encoded;

		return encoded;
	}

	return 0;
}
예제 #21
0
파일: unit.c 프로젝트: 166MMX/OpenDUNE
/**
 * Set the speed of a Unit.
 *
 * Stack: 1 - The new speed of the Unit.
 *
 * @param script The script engine to operate on.
 * @return The new speed; it might differ from the value given.
 */
uint16 Script_Unit_SetSpeed(ScriptEngine *script)
{
	Unit *u;
	uint16 speed;

	u = g_scriptCurrentUnit;
	speed = clamp(STACK_PEEK(1), 0, 255);

	if (!u->o.flags.s.byScenario) speed = speed * 192 / 256;

	Unit_SetSpeed(u, speed);

	return u->speed;
}
예제 #22
0
int XMLAPI DTDValidate_EndElement(void *UserData, const XMLCH *uri, 
								  const XMLCH *localName, const XMLCH *qName)
{
	LPXMLDTDVALIDATOR v = (LPXMLDTDVALIDATOR)UserData;
	struct vContext *c = STACK_PEEK(v->ContextStack);
	if (c) {
		if (!(c->ctx->mark & SMARK_FINAL)) {
			Er_(v, c->ctx, ERR_XMLDTDV_CONTENT_MODEL_CANNOT_END, c->e->name);
			MAYRET(XML_ABORT);
		}
		STACK_REMOVE(v->ContextStack);
	}
	return (v->endElementHandler) ? v->endElementHandler(v, uri, localName, qName) : 0;
}
예제 #23
0
int XMLAPI DTDValidate_StartElement(void *UserData, const XMLCH *uri, 
									const XMLCH *localName, const XMLCH *qName, LPXMLVECTOR atts)
{
	LPXMLDTDVALIDATOR v = (LPXMLDTDVALIDATOR)UserData;
	struct vContext *c;
	void *d;
	
	if (v->ContextStack->length) {
		c = STACK_PEEK(v->ContextStack);
		if (c->e->type != XMLCTYPE_ANY) {
			struct FSAState *ctx = Validate(c->ctx, (XMLCH*)qName);
			if (!ctx) {
				Er_(v, c->ctx, ERR_XMLDTDV_ELEMENT_NOT_ALLOWED, c->e->name, qName);
				MAYRET(XML_ABORT);
			}
			else c->ctx = ctx;
		}
	}
	else if (v->startElementHandlerFilter == DTDValidate_StartElement &&
		v->parser->prt->doctypeStr) {
		/* test for ERR_XMLDTDV_ROOTELEMENT_MISMATCH */
		if (strcmp(qName, v->parser->prt->doctypeStr)) {
			Er_(v, NULL, ERR_XMLDTDV_ROOTELEMENT_MISMATCH, v->parser->prt->doctypeStr);
			MAYRET(XML_ABORT);
		}
	}
	
	if (!(c = STACK_PUSH(v->ContextStack, NULL))) {
		Er_(v, NULL, ERR_XMLDTDV_MEMORY_ALLOC);
		return XML_ABORT;
	}

	d = (v->ElementTable) ? 
		XMLHTable_Lookup(v->ElementTable, (char*)qName) : NULL; /* catches the case
															of missing DTD too */
	if (!d || d == EMPTYSTR) { /* note that we're also testing the empty string 
		(element is in hashtable because it was used in cp but it wasn't declared) */
		Er_(v, NULL, ERR_XMLDTDV_UNDECLARED_ELEMENT, qName);
		MAYRET(XML_ABORT);
		c->e = (struct ElementDecl*)&AnyElement;
		c->ctx = c->e->startState;
		return (v->startElementHandler) ?
			v->startElementHandler(v, uri, localName, qName, atts) : 0;
	}
	c->e = d;
	c->ctx = c->e->startState;
	if (!ValidateAtts(v, c->e, atts)) return XML_ABORT;
	return (v->startElementHandler) ?
		v->startElementHandler(v, uri, localName, qName, atts) : 0;
}
예제 #24
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Make 8 explosions: 1 at the unit, and 7 around him.
 * It does damage to the surrounding units with predefined damage, but
 *  anonymous.
 *
 * Stack: 1 - The radius of the 7 explosions.
 *
 * @param script The script engine to operate on.
 * @return The value 0. Always.
 */
uint16 Script_Unit_ExplosionMultiple(ScriptEngine *script)
{
	Unit *u;
	uint8 i;

	u = g_scriptCurrentUnit;

	Map_MakeExplosion(EXPLOSION_DEATH_HAND, u->o.position, Tools_RandomLCG_Range(25, 50), 0);

	for (i = 0; i < 7; i++) {
		Map_MakeExplosion(EXPLOSION_DEATH_HAND, Tile_MoveByRandom(u->o.position, STACK_PEEK(1), false), Tools_RandomLCG_Range(75, 150), 0);
	}

	return 0;
}
예제 #25
0
파일: structure.c 프로젝트: rofl0r/OpenDUNE
/**
 * Find the direction a tile is, seen from the structure. If the tile is
 *  invalid it gives the direction the structure is currently looking at.
 *
 * Stack: 1 - Tile to get the direction to, or the current direction of the
 *   structure in case the tile is invalid.
 *
 * @param script The script engine to operate on.
 * @return The direction (value between 0 and 7, shifted to the left with 5).
 */
uint16 Script_Structure_GetDirection(ScriptEngine *script)
{
	Structure *s;
	tile32 tile;
	uint16 encoded;

	s = g_scriptCurrentStructure;
	encoded = STACK_PEEK(1);

	if (!Tools_Index_IsValid(encoded)) return s->rotationSpriteDiff << 5;

	tile = Tools_Index_GetTile(encoded);

	return Orientation_Orientation256ToOrientation8(Tile_GetDirection(s->o.position, tile)) << 5;
}
예제 #26
0
파일: unit.c 프로젝트: AndO3131/OpenDUNE
/**
 * Set the speed of a Unit.
 *
 * Stack: 1 - The new speed of the Unit.
 *
 * @param script The script engine to operate on.
 * @return The new speed; it might differ from the value given.
 */
uint16 Script_Unit_SetSpeed(ScriptEngine *script)
{
	Unit *u;
	uint16 speed;

	u = g_scriptCurrentUnit;
	speed = STACK_PEEK(1);

	/* Scenario-based units move on a different speed */
	if (!u->o.flags.s.byScenario) speed = speed * 192 / 256;

	Unit_SetSpeed(u, speed);

	return u->speed;
}
예제 #27
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Sets the action for the current unit.
 *
 * Stack: 1 - The action.
 *
 * @param script The script engine to operate on.
 * @return The value 0. Always.
 */
uint16 Script_Unit_SetAction(ScriptEngine *script)
{
	Unit *u;
	ActionType action;

	u = g_scriptCurrentUnit;

	action = STACK_PEEK(1);

	if (u->o.houseID == g_playerHouseID && action == ACTION_HARVEST && u->nextActionID != ACTION_INVALID) return 0;

	Unit_SetAction(u, action);

	return 0;
}
예제 #28
0
파일: unit.c 프로젝트: rofl0r/OpenDUNE
/**
 * Set the speed of a Unit.
 *
 * Stack: 1 - The new speed of the Unit.
 *
 * @param script The script engine to operate on.
 * @return The new speed; it might differ from the value given.
 */
uint16 Script_Unit_SetSpeed(ScriptEngine *script)
{
	Unit *u;
	uint16 speed;

	u = g_scriptCurrentUnit;
	speed = clamp(STACK_PEEK(1), 0, 255);

	if (!u->o.flags.s.byScenario) speed = speed * 192 / 256;

	if (g_table_unitInfo[u->o.type].movementType == MOVEMENT_WINGER) speed = Tools_AdjustToGameSpeed(speed, 0, 255, true);

	Unit_SetSpeed(u, speed);

	return u->speed;
}
예제 #29
0
파일: structure.c 프로젝트: rofl0r/OpenDUNE
/**
 * Find a Unit which is within range and not an ally.
 *
 * Stack: 1 - Range to find a target in (amount of tiles multiplied with 256).
 *
 * @param script The script engine to operate on.
 * @return The Unit Index of the closest unit within range and not friendly,
 *   or 0 if none exists.
 */
uint16 Script_Structure_FindTargetUnit(ScriptEngine *script)
{
	PoolFindStruct find;
	Structure *s;
	Unit *u;
	uint32 distanceCurrent;
	uint32 targetRange;

	s = g_scriptCurrentStructure;
	targetRange = STACK_PEEK(1);
	distanceCurrent = 32000;
	u = NULL;

	find.houseID = HOUSE_INVALID;
	find.index   = 0xFFFF;
	find.type    = 0xFFFF;

	while (true) {
		uint16 distance;
		Unit *uf;

		uf = Unit_Find(&find);
		if (uf == NULL) break;

		if (House_AreAllied(s->o.houseID, uf->o.houseID)) continue;

		if (uf->o.type != UNIT_ORNITHOPTER) {
			if ((uf->o.seenByHouses & (1 << s->o.houseID)) == 0) continue;
		}

		distance = Tile_GetDistance(uf->o.position, s->o.position);
		if (distance >= distanceCurrent) continue;

		if (uf->o.type == UNIT_ORNITHOPTER) {
			if (distance >= targetRange * 3) continue;
		} else {
			if (distance >= targetRange) continue;
		}

		/* ENHANCEMENT -- The original code swapped the assignment, making it do nothing, Now it finds the closest unit to shoot at, what seems to be the intention */
		if (g_dune2_enhanced) distanceCurrent = distance;
		u = uf;
	}

	if (u == NULL) return IT_NONE;
	return Tools_Index_Encode(u->o.index, IT_UNIT);
}
예제 #30
0
파일: team.c 프로젝트: 166MMX/OpenDUNE
/**
 * Loads a new script for the current team.
 *
 * Stack: 1 - The script type.
 *
 * @param script The script engine to operate on.
 * @return The value 0. Always.
 */
uint16 Script_Team_Load(ScriptEngine *script)
{
	Team *t;
	uint16 type;

	t = g_scriptCurrentTeam;
	type = STACK_PEEK(1);

	if (t->action == type) return 0;

	t->action = type;

	Script_Reset(&t->script, g_scriptTeam);
	Script_Load(&t->script, type & 0xFF);

	return 0;
}