Ejemplo n.º 1
0
map_location::DIRECTION map_location::parse_direction(const std::string& str)
{
	if(str.empty()) {
		return NDIRECTIONS;
	}
	
	// Syntax: [-] (n|ne|se|s|sw|nw) [:cw|:ccw]
	// - means "take opposite direction" and has higher precedence
	// :cw and :ccw mean "one step (counter-)clockwise"
	// Parentheses can be used for grouping or to apply an operator more than once
	
	const size_t open = str.find_first_of('('), close = str.find_last_of(')');
	if (open != std::string::npos && close != std::string::npos) {
		std::string sub = str.substr(open + 1, close - open - 1);
		map_location::DIRECTION dir = parse_direction(sub);
		sub = str;
		sub.replace(open, close - open + 1, write_direction(dir));
		return parse_direction(sub);
	}
	
	const size_t start = str[0] == '-' ? 1 : 0;
	const size_t end = str.find_first_of(':');
	const std::string& main_dir = str.substr(start, end - start);
	map_location::DIRECTION dir;
	
	if (main_dir == "n") {
		dir = NORTH;
	} else if (main_dir == "ne") {
		dir = NORTH_EAST;
	} else if (main_dir == "se") {
		dir = SOUTH_EAST;
	} else if (main_dir == "s") {
		dir = SOUTH;
	} else if (main_dir == "sw") {
		dir = SOUTH_WEST;
	} else if (main_dir == "nw") {
		dir = NORTH_WEST;
	} else {
		return NDIRECTIONS;
	}
	
	if (start == 1) {
		dir = get_opposite_dir(dir);
	}
	
	if (end != std::string::npos) {
		const std::string rel_dir = str.substr(end + 1);
		if (rel_dir == "cw") {
			dir = rotate_right(dir, 1);
		} else if (rel_dir == "ccw") {
			dir = rotate_right(dir, -1);
		} else {
			return NDIRECTIONS;
		}
	}
	
	return dir;
}
Ejemplo n.º 2
0
	void FlexFlowPropertyParser::parse(StylePropertySetter *setter, const std::string &name, StyleParser &parser)
	{
		auto &tokens = parser.tokens;

		size_t pos = 0;
		StyleToken token = next_token(pos, tokens);

		StyleSetValue direction = StyleSetValue::from_keyword("row");
		StyleSetValue wrap = StyleSetValue::from_keyword("nowrap");

		bool direction_specified = false;
		bool wrap_specified = false;

		do
		{
			if (!direction_specified && parse_direction(direction, pos, tokens))
			{
				direction_specified = true;
			}
			else if (!wrap_specified && parse_wrap(wrap, pos, tokens))
			{
				wrap_specified = true;
			}
			else
			{
				return;
			}
		} while (pos != tokens.size());

		setter->set_value("flex-direction", direction);
		setter->set_value("flex-wrap", wrap);
	}
Ejemplo n.º 3
0
void RouteParser::element_open_actions() {
  if (!substring.compare("route")) {
    parse_route();
  } else if (!substring.compare("stop")) {
    parse_stop();
  } else if (!substring.compare("direction")) {
    parse_direction();
  }
}
Ejemplo n.º 4
0
int main(int argc, char **argv)
{
    FILE* fp;  // file pointer to input file
    char move = '\0';  // character depicting next move
    int direction[2];  // direction of the move in cartesian plane

    Position* head = NULL;  // head of set (linked list)
    Position santa_position;  // current santa position
    santa_position.x = 0;
    santa_position.y = 0;
    Position robot_position;  // current robot position
    robot_position.x = 0;
    robot_position.y = 0;
    mark_position_visited(&head, santa_position);

    // Since Santa goes first,
    // Robot would have been the one before that.
    // Current member will hold whoever is moving currently.
    Position* current_member = &robot_position;

    fp = fopen("./input.txt", "r");

    // Read the file one character at a time
    while((move=fgetc(fp)) != EOF) {

        // Get the next move
        parse_direction(move, direction);

        // Get position of currently active member
        current_member = switcher(current_member, &santa_position, &robot_position);

        // Add the next move to current position
        current_member->x += direction[0];
        current_member->y += direction[1];

        // Check if position has been previously visited.
        // If it hasn't been, mark it as visited.
        if (!position_was_visited(head, *current_member)) {
            mark_position_visited(&head, *current_member);
        }
    }

    printf("%ld\n", list_length(head));

    // Free the list and close the file.
    clear_memory(&head);
    fclose(fp);

    return 0;
}
Ejemplo n.º 5
0
/**
 * Load avatar sprite layer definitions into vector.
 */
void Avatar::loadLayerDefinitions() {
	layer_def = std::vector<std::vector<unsigned> >(8, std::vector<unsigned>());
	layer_reference_order = std::vector<std::string>();

	FileParser infile;
	// @CLASS Avatar: Hero layers|Description of engine/hero_layers.txt
	if (infile.open("engine/hero_layers.txt")) {
		while(infile.next()) {
			if (infile.key == "layer") {
				// @ATTR layer|direction, list(string) : Direction, Layer name(s)|Defines the hero avatar sprite layer
				unsigned dir = parse_direction(popFirstString(infile.val));
				if (dir>7) {
					infile.error("Avatar: Hero layer direction must be in range [0,7]");
					Exit(1);
				}
				std::string layer = popFirstString(infile.val);
				while (layer != "") {
					// check if already in layer_reference:
					unsigned ref_pos;
					for (ref_pos = 0; ref_pos < layer_reference_order.size(); ++ref_pos)
						if (layer == layer_reference_order[ref_pos])
							break;
					if (ref_pos == layer_reference_order.size())
						layer_reference_order.push_back(layer);
					layer_def[dir].push_back(ref_pos);

					layer = popFirstString(infile.val);
				}
			}
			else {
				infile.error("Avatar: '%s' is not a valid key.", infile.key.c_str());
			}
		}
		infile.close();
	}

	// There are the positions of the items relative to layer_reference_order
	// so if layer_reference_order=main,body,head,off
	// and we got a layer=3,off,body,head,main
	// then the layer_def[3] looks like (3,1,2,0)
}
Ejemplo n.º 6
0
static int
parse_mirred(struct action_util *a, int *argc_p, char ***argv_p,
	     int tca_id, struct nlmsghdr *n)
{

	int argc = *argc_p;
	char **argv = *argv_p;

	if (argc < 0) {
		fprintf(stderr, "mirred bad argument count %d\n", argc);
		return -1;
	}

	if (matches(*argv, "mirred") == 0) {
		NEXT_ARG();
	} else {
		fprintf(stderr, "mirred bad argument %s\n", *argv);
		return -1;
	}


	if (matches(*argv, "egress") == 0 || matches(*argv, "ingress") == 0 ||
	    matches(*argv, "index") == 0) {
		int ret = parse_direction(a, &argc, &argv, tca_id, n);

		if (ret == 0) {
			*argc_p = argc;
			*argv_p = argv;
			return 0;
		}

	} else if (matches(*argv, "help") == 0) {
		usage();
	} else {
		fprintf(stderr, "mirred option not supported %s\n", *argv);
	}

	return -1;

}
map_location::DIRECTION map_location::parse_direction(const std::string& str)
{
	if(!str.empty()) {
		if(str == "n") {
			return NORTH;
		} else if(str == "ne") {
			return NORTH_EAST;
		} else if(str == "se") {
			return SOUTH_EAST;
		} else if(str == "s") {
			return SOUTH;
		} else if(str == "sw") {
			return SOUTH_WEST;
		} else if(str == "nw") {
			return NORTH_WEST;
		} else if(str[0] == '-' && str.length() <= 10) {
			// A minus sign reverses the direction
			return get_opposite_dir(parse_direction(str.substr(1)));
		}
	}
	return NDIRECTIONS;
}
Ejemplo n.º 8
0
void Map::loadEnemyGroup(FileParser &infile, Map_Group *group) {
	if (infile.key == "type") {
		// @ATTR enemygroup.type|string|The category of enemies that will spawn in this group.
		group->category = infile.val;
	}
	else if (infile.key == "level") {
		// @ATTR enemygroup.level|[min(integer), max(integer)]|Defines the level range of enemies in group. If only one number is given, it's the exact level.
		group->levelmin = std::max(0, toInt(infile.nextValue()));
		group->levelmax = std::max(0, toInt(infile.nextValue(), group->levelmin));
	}
	else if (infile.key == "location") {
		// @ATTR enemygroup.location|[x(integer), y(integer), x2(integer), y2(integer)]|Location area for enemygroup
		group->pos.x = toInt(infile.nextValue());
		group->pos.y = toInt(infile.nextValue());
		group->area.x = toInt(infile.nextValue());
		group->area.y = toInt(infile.nextValue());
	}
	else if (infile.key == "number") {
		// @ATTR enemygroup.number|[min(integer), max(integer]|Defines the range of enemies in group. If only one number is given, it's the exact amount.
		group->numbermin = std::max(0, toInt(infile.nextValue()));
		group->numbermax = std::max(0, toInt(infile.nextValue(), group->numbermin));
	}
	else if (infile.key == "chance") {
		// @ATTR enemygroup.chance|integer|Percentage of chance
		float n = static_cast<float>(std::max(0, toInt(infile.nextValue()))) / 100.0f;
		group->chance = std::min(1.0f, std::max(0.0f, n));
	}
	else if (infile.key == "direction") {
		// @ATTR enemygroup.direction|direction|Direction that enemies will initially face.
		group->direction = parse_direction(infile.val);
	}
	else if (infile.key == "waypoints") {
		// @ATTR enemygroup.waypoints|[x(integer), y(integer)]|Enemy waypoints; single enemy only; negates wander_radius
		std::string none = "";
		std::string a = infile.nextValue();
		std::string b = infile.nextValue();

		while (a != none) {
			FPoint p;
			p.x = static_cast<float>(toInt(a)) + 0.5f;
			p.y = static_cast<float>(toInt(b)) + 0.5f;
			group->waypoints.push(p);
			a = infile.nextValue();
			b = infile.nextValue();
		}

		// disable wander radius, since we can't have waypoints and wandering at the same time
		group->wander_radius = 0;
	}
	else if (infile.key == "wander_radius") {
		// @ATTR enemygroup.wander_radius|integer|The radius (in tiles) that an enemy will wander around randomly; negates waypoints
		group->wander_radius = std::max(0, toInt(infile.nextValue()));

		// clear waypoints, since wandering will use the waypoint queue
		while (!group->waypoints.empty()) {
			group->waypoints.pop();
		}
	}
	else if (infile.key == "requires_status") {
		// @ATTR enemygroup.requires_status|string|Status required for loading enemies
		group->requires_status.push_back(infile.nextValue());
	}
	else if (infile.key == "requires_not_status") {
		// @ATTR enemygroup.requires_not_status|string|Status required to be missing for loading enemies
		group->requires_not_status.push_back(infile.nextValue());
	}
	else {
		infile.error("Map: '%s' is not a valid key.", infile.key.c_str());
	}
}
Ejemplo n.º 9
0
static int parse(int c, char **argv, int invert, unsigned int *flags,
                 const struct ipt_entry *entry,
                 unsigned int *nfcache,
                 struct ipt_entry_match **match)
{
	struct ipt_policy_info *info = (void *)(*match)->data;
	struct ipt_policy_elem *e = &info->pol[info->len];
	struct in_addr *addr = NULL, mask;
	unsigned int naddr = 0;
	int mode;

	check_inverse(optarg, &invert, &optind, 0);

	switch (c) {
	case '1':
		if (info->flags & (IPT_POLICY_MATCH_IN|IPT_POLICY_MATCH_OUT))
			exit_error(PARAMETER_PROBLEM,
			           "policy match: double --dir option");
		if (invert)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --dir option");

		info->flags |= parse_direction(argv[optind-1]);
		break;
	case '2':
		if (invert)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --policy option");

		info->flags |= parse_policy(argv[optind-1]);
		break;
	case '3':
		if (info->flags & IPT_POLICY_MATCH_STRICT)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: double --strict option");

		if (invert)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --strict option");

		info->flags |= IPT_POLICY_MATCH_STRICT;
		break;
	case '4':
		if (e->match.reqid)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: double --reqid option");

		e->match.reqid = 1;
		e->invert.reqid = invert;
		e->reqid = strtol(argv[optind-1], NULL, 10);
		break;
	case '5':
		if (e->match.spi)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: double --spi option");

		e->match.spi = 1;
		e->invert.spi = invert;
		e->spi = strtol(argv[optind-1], NULL, 0x10);
		break;
	case '6':
		if (e->match.saddr)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: double --tunnel-src option");

		parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
		if (naddr > 1)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: name resolves to multiple IPs");

		e->match.saddr = 1;
		e->invert.saddr = invert;
		e->saddr.a4 = addr[0];
		e->smask.a4 = mask;
                break;
	case '7':
		if (e->match.daddr)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: double --tunnel-dst option");

		parse_hostnetworkmask(argv[optind-1], &addr, &mask, &naddr);
		if (naddr > 1)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: name resolves to multiple IPs");

		e->match.daddr = 1;
		e->invert.daddr = invert;
		e->daddr.a4 = addr[0];
		e->dmask.a4 = mask;
		break;
	case '8':
		if (e->match.proto)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: double --proto option");

		e->proto = parse_protocol(argv[optind-1]);
		if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP &&
		    e->proto != IPPROTO_COMP)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: protocol must ah/esp/ipcomp");
		e->match.proto = 1;
		e->invert.proto = invert;
		break;
	case '9':
		if (e->match.mode)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: double --mode option");

		mode = parse_mode(argv[optind-1]);
		e->match.mode = 1;
		e->invert.mode = invert;
		e->mode = mode;
		break;
	case 'a':
		if (invert)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --next option");

		if (++info->len == IPT_POLICY_MAX_ELEM)
			exit_error(PARAMETER_PROBLEM,
			           "policy match: maximum policy depth reached");
		break;
	default:
		return 0;
	}

	policy_info = info;
	return 1;
}
Ejemplo n.º 10
0
/**
 * NPCs are stored in simple config files
 *
 * @param npc_id Config file for npc
 */
void NPC::load(const std::string& npc_id) {

	FileParser infile;
	ItemStack stack;

	portrait_filenames.resize(1);

	// @CLASS NPC|Description of NPCs in npcs/
	if (infile.open(npc_id)) {
		bool clear_random_table = true;

		while (infile.next()) {
			if (infile.section == "dialog") {
				if (infile.new_section) {
					dialog.push_back(std::vector<Event_Component>());
				}
				Event_Component e;
				e.type = EC_NONE;
				if (infile.key == "him" || infile.key == "her") {
					// @ATTR dialog.him|repeatable(string)|A line of dialog from the NPC.
					// @ATTR dialog.her|repeatable(string)|A line of dialog from the NPC.
					e.type = EC_NPC_DIALOG_THEM;
					e.s = msg->get(infile.val);
				}
				else if (infile.key == "you") {
					// @ATTR dialog.you|repeatable(string)|A line of dialog from the player.
					e.type = EC_NPC_DIALOG_YOU;
					e.s = msg->get(infile.val);
				}
				else if (infile.key == "voice") {
					// @ATTR dialog.voice|repeatable(string)|Filename of a voice sound file to play.
					e.type = EC_NPC_VOICE;
					e.x = loadSound(infile.val, NPC_VOX_QUEST);
				}
				else if (infile.key == "topic") {
					// @ATTR dialog.topic|string|The name of this dialog topic. Displayed when picking a dialog tree.
					e.type = EC_NPC_DIALOG_TOPIC;
					e.s = msg->get(infile.val);
				}
				else if (infile.key == "group") {
					// @ATTR dialog.group|string|Dialog group.
					e.type = EC_NPC_DIALOG_GROUP;
					e.s = infile.val;
				}
				else if (infile.key == "allow_movement") {
					// @ATTR dialog.allow_movement|bool|Restrict the player's mvoement during dialog.
					e.type = EC_NPC_ALLOW_MOVEMENT;
					e.s = infile.val;
				}
				else if (infile.key == "portrait_him" || infile.key == "portrait_her") {
					// @ATTR dialog.portrait_him|repeatable(filename)|Filename of a portrait to display for the NPC during this dialog.
					// @ATTR dialog.portrait_her|repeatable(filename)|Filename of a portrait to display for the NPC during this dialog.
					e.type = EC_NPC_PORTRAIT_THEM;
					e.s = infile.val;
					portrait_filenames.push_back(e.s);
				}
				else if (infile.key == "portrait_you") {
					// @ATTR dialog.portrait_you|repeatable(filename)|Filename of a portrait to display for the player during this dialog.
					e.type = EC_NPC_PORTRAIT_YOU;
					e.s = infile.val;
					portrait_filenames.push_back(e.s);
				}
				else {
					Event ev;
					EventManager::loadEventComponent(infile, &ev, NULL);

					for (size_t i=0; i<ev.components.size(); ++i) {
						if (ev.components[i].type != EC_NONE) {
							dialog.back().push_back(ev.components[i]);
						}
					}
				}

				if (e.type != EC_NONE) {
					dialog.back().push_back(e);
				}
			}
			else {
				filename = npc_id;

				if (infile.new_section) {
					// APPENDed file
					clear_random_table = true;
				}

				if (infile.key == "name") {
					// @ATTR name|string|NPC's name.
					name = msg->get(infile.val);
				}
				else if (infile.key == "gfx") {
					// @ATTR gfx|filename|Filename of an animation definition.
					gfx = infile.val;
				}
				else if (infile.key == "direction") {
					// @ATTR direction|direction|The direction to use for this NPC's stance animation.
					direction = parse_direction(infile.val);
				}

				// handle talkers
				else if (infile.key == "talker") {
					// @ATTR talker|bool|Allows this NPC to be talked to.
					talker = toBool(infile.val);
				}
				else if (infile.key == "portrait") {
					// @ATTR portrait|filename|Filename of the default portrait image.
					portrait_filenames[0] = infile.val;
				}

				// handle vendors
				else if (infile.key == "vendor") {
					// @ATTR vendor|bool|Allows this NPC to buy/sell items.
					vendor = toBool(infile.val);
				}
				else if (infile.key == "vendor_requires_status") {
					// @ATTR vendor_requires_status|list(string)|The player must have these statuses in order to use this NPC as a vendor.
					while (infile.val != "") {
						vendor_requires_status.push_back(popFirstString(infile.val));
					}
				}
				else if (infile.key == "vendor_requires_not_status") {
					// @ATTR vendor_requires_not_status|list(string)|The player must not have these statuses in order to use this NPC as a vendor.
					while (infile.val != "") {
						vendor_requires_not_status.push_back(popFirstString(infile.val));
					}
				}
				else if (infile.key == "constant_stock") {
					// @ATTR constant_stock|repeatable(list(item_id))|A list of items this vendor has for sale.
					stack.quantity = 1;
					while (infile.val != "") {
						stack.item = popFirstInt(infile.val);
						stock.add(stack);
					}
				}
				else if (infile.key == "status_stock") {
					// @ATTR status_stock|repeatable(string, list(item_id)) : Required status, Item(s)|A list of items this vendor will have for sale if the required status is met.
					if (camp->checkStatus(popFirstString(infile.val))) {
						stack.quantity = 1;
						while (infile.val != "") {
							stack.item = popFirstInt(infile.val);
							stock.add(stack);
						}
					}
				}
				else if (infile.key == "random_stock") {
					// @ATTR random_stock|list(loot)|Use a loot table to add random items to the stock; either a filename or an inline definition.
					if (clear_random_table) {
						random_table.clear();
						clear_random_table = false;
					}

					random_table.push_back(Event_Component());
					loot->parseLoot(infile.val, &random_table.back(), &random_table);
				}
				else if (infile.key == "random_stock_count") {
					// @ATTR random_stock_count|int, int : Min, Max|Sets the minimum (and optionally, the maximum) amount of random items this npc can have.
					random_table_count.x = popFirstInt(infile.val);
					random_table_count.y = popFirstInt(infile.val);
					if (random_table_count.x != 0 || random_table_count.y != 0) {
						random_table_count.x = std::max(random_table_count.x, 1);
						random_table_count.y = std::max(random_table_count.y, random_table_count.x);
					}
				}

				// handle vocals
				else if (infile.key == "vox_intro") {
					// @ATTR vox_intro|repeatable(filename)|Filename of a sound file to play when initially interacting with the NPC.
					loadSound(infile.val, NPC_VOX_INTRO);
				}

				else {
					infile.error("NPC: '%s' is not a valid key.", infile.key.c_str());
				}
			}
		}
		infile.close();
	}
	loadGraphics();

	// fill inventory with items from random stock table
	unsigned rand_count = randBetween(random_table_count.x, random_table_count.y);

	std::vector<ItemStack> rand_itemstacks;
	for (unsigned i=0; i<rand_count; ++i) {
		loot->checkLoot(random_table, NULL, &rand_itemstacks);
	}
	std::sort(rand_itemstacks.begin(), rand_itemstacks.end(), compareItemStack);
	for (size_t i=0; i<rand_itemstacks.size(); ++i) {
		stock.add(rand_itemstacks[i]);
	}
}
Ejemplo n.º 11
0
void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
{
	monitor_t *m = mon;
	desktop_t *d = mon->desk;
	node_t *f = mon->desk->focus;

	parse_rule_consequence(fd, csq);

	if (!csq->manage) {
		free(csq->layer);
		free(csq->state);
		window_show(win);
		return;
	}

	if (csq->node_desc[0] != '\0') {
		coordinates_t ref = {m, d, f};
		coordinates_t trg = {NULL, NULL, NULL};
		if (node_from_desc(csq->node_desc, &ref, &trg)) {
			m = trg.monitor;
			d = trg.desktop;
			f = trg.node;
		}
	} else if (csq->desktop_desc[0] != '\0') {
		coordinates_t ref = {m, d, NULL};
		coordinates_t trg = {NULL, NULL, NULL};
		if (desktop_from_desc(csq->desktop_desc, &ref, &trg)) {
			m = trg.monitor;
			d = trg.desktop;
			f = trg.desktop->focus;
		}
	} else if (csq->monitor_desc[0] != '\0') {
		coordinates_t ref = {m, NULL, NULL};
		coordinates_t trg = {NULL, NULL, NULL};
		if (monitor_from_desc(csq->monitor_desc, &ref, &trg)) {
			m = trg.monitor;
			d = trg.monitor->desk;
			f = trg.monitor->desk->focus;
		}
	}

	if (csq->sticky) {
		m = mon;
		d = mon->desk;
		f = mon->desk->focus;
	}

	if (csq->split_dir[0] != '\0' && f != NULL) {
		direction_t dir;
		if (parse_direction(csq->split_dir, &dir)) {
			presel_dir(m, d, f, dir);
		}
	}

	if (csq->split_ratio != 0 && f != NULL) {
		presel_ratio(m, d, f, csq->split_ratio);
	}

	node_t *n = make_node(win);
	client_t *c = make_client();
	c->border_width = csq->border ? d->border_width : 0;
	n->client = c;
	initialize_client(n);
	update_floating_rectangle(n);

	if (c->floating_rectangle.x == 0 && c->floating_rectangle.y == 0) {
		csq->center = true;
	}

	c->min_width = csq->min_width;
	c->max_width = csq->max_width;
	c->min_height = csq->min_height;
	c->max_height = csq->max_height;

	monitor_t *mm = monitor_from_client(c);
	embrace_client(mm, c);
	adapt_geometry(&mm->rectangle, &m->rectangle, n);

	if (csq->center) {
		window_center(m, c);
	}

	snprintf(c->class_name, sizeof(c->class_name), "%s", csq->class_name);
	snprintf(c->instance_name, sizeof(c->instance_name), "%s", csq->instance_name);

	f = insert_node(m, d, n, f);
	clients_count++;

	put_status(SBSC_MASK_NODE_MANAGE, "node_manage %s %s 0x%X 0x%X\n", m->name, d->name, win, f!=NULL?f->id:0);

	if (f != NULL && f->client != NULL && csq->state != NULL && *(csq->state) == STATE_FLOATING) {
		c->last_layer = c->layer = f->client->layer;
	}

	if (csq->layer != NULL) {
		c->last_layer = c->layer = *(csq->layer);
	}

	if (csq->state != NULL) {
		set_state(m, d, n, *(csq->state));
		c->last_state = c->state;
	}

	set_locked(m, d, n, csq->locked);
	set_sticky(m, d, n, csq->sticky);
	set_private(m, d, n, csq->private);

	arrange(m, d);

	bool give_focus = (csq->focus && (d == mon->desk || csq->follow));

	if (give_focus) {
		focus_node(m, d, n);
	} else if (csq->focus) {
		activate_node(m, d, n);
	} else {
		stack(d, n, false);
	}

	uint32_t values[] = {CLIENT_EVENT_MASK | (focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0)};
	xcb_change_window_attributes(dpy, win, XCB_CW_EVENT_MASK, values);

	if (d == m->desk) {
		window_show(n->id);
	} else {
		window_hide(n->id);
	}

	/* the same function is already called in `focus_node` but has no effects on unmapped windows */
	if (give_focus) {
		xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, win, XCB_CURRENT_TIME);
	}

	ewmh_set_wm_desktop(n, d);
	ewmh_update_client_list(false);
	free(csq->layer);
	free(csq->state);
}
Ejemplo n.º 12
0
void Map::loadEnemyGroup(FileParser &infile, Map_Group *group) {
	if (infile.key == "type") {
		// @ATTR enemygroup.type|string|(IGNORED BY ENGINE) The "type" field, as used by Tiled and other mapping tools.
		group->type = infile.val;
	}
	else if (infile.key == "category") {
		// @ATTR enemygroup.category|predefined_string|The category of enemies that will spawn in this group.
		group->category = infile.val;
	}
	else if (infile.key == "level") {
		// @ATTR enemygroup.level|int, int : Min, Max|Defines the level range of enemies in group. If only one number is given, it's the exact level.
		group->levelmin = std::max(0, popFirstInt(infile.val));
		group->levelmax = std::max(std::max(0, toInt(popFirstString(infile.val))), group->levelmin);
	}
	else if (infile.key == "location") {
		// @ATTR enemygroup.location|rectangle|Location area for enemygroup
		group->pos.x = popFirstInt(infile.val);
		group->pos.y = popFirstInt(infile.val);
		group->area.x = popFirstInt(infile.val);
		group->area.y = popFirstInt(infile.val);
	}
	else if (infile.key == "number") {
		// @ATTR enemygroup.number|int, int : Min, Max|Defines the range of enemies in group. If only one number is given, it's the exact amount.
		group->numbermin = std::max(0, popFirstInt(infile.val));
		group->numbermax = std::max(std::max(0, toInt(popFirstString(infile.val))), group->numbermin);
	}
	else if (infile.key == "chance") {
		// @ATTR enemygroup.chance|int|Percentage of chance
		float n = static_cast<float>(std::max(0, popFirstInt(infile.val))) / 100.0f;
		group->chance = std::min(1.0f, std::max(0.0f, n));
	}
	else if (infile.key == "direction") {
		// @ATTR enemygroup.direction|direction|Direction that enemies will initially face.
		group->direction = parse_direction(infile.val);
	}
	else if (infile.key == "waypoints") {
		// @ATTR enemygroup.waypoints|list(point)|Enemy waypoints; single enemy only; negates wander_radius
		std::string none = "";
		std::string a = popFirstString(infile.val);
		std::string b = popFirstString(infile.val);

		while (a != none) {
			FPoint p;
			p.x = static_cast<float>(toInt(a)) + 0.5f;
			p.y = static_cast<float>(toInt(b)) + 0.5f;
			group->waypoints.push(p);
			a = popFirstString(infile.val);
			b = popFirstString(infile.val);
		}

		// disable wander radius, since we can't have waypoints and wandering at the same time
		group->wander_radius = 0;
	}
	else if (infile.key == "wander_radius") {
		// @ATTR enemygroup.wander_radius|int|The radius (in tiles) that an enemy will wander around randomly; negates waypoints
		group->wander_radius = std::max(0, popFirstInt(infile.val));

		// clear waypoints, since wandering will use the waypoint queue
		while (!group->waypoints.empty()) {
			group->waypoints.pop();
		}
	}
	else if (infile.key == "requires_status") {
		// @ATTR enemygroup.requires_status|list(string)|Status required for loading enemies
		std::string s;
		while ((s = popFirstString(infile.val)) != "") {
			group->requires_status.push_back(s);
		}
	}
	else if (infile.key == "requires_not_status") {
		// @ATTR enemygroup.requires_not_status|list(string)|Status required to be missing for loading enemies
		std::string s;
		while ((s = popFirstString(infile.val)) != "") {
			group->requires_not_status.push_back(s);
		}
	}
	else {
		infile.error("Map: '%s' is not a valid key.", infile.key.c_str());
	}
}
Ejemplo n.º 13
0
static int policy_parse(int c, int invert, unsigned int *flags,
                        struct xt_policy_info *info, uint8_t family)
{
	struct xt_policy_elem *e = &info->pol[info->len];
	struct in_addr *addr = NULL, mask;
	struct in6_addr *addr6 = NULL, mask6;
	unsigned int naddr = 0, num;
	int mode;

	xtables_check_inverse(optarg, &invert, &optind, 0);

	switch (c) {
	case '1':
		if (info->flags & (XT_POLICY_MATCH_IN | XT_POLICY_MATCH_OUT))
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --dir option");
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --dir option");

		info->flags |= parse_direction(optarg);
		break;
	case '2':
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --policy option");

		info->flags |= parse_policy(optarg);
		break;
	case '3':
		if (info->flags & XT_POLICY_MATCH_STRICT)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --strict option");

		if (invert)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --strict option");

		info->flags |= XT_POLICY_MATCH_STRICT;
		break;
	case '4':
		if (e->match.reqid)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --reqid option");

		e->match.reqid = 1;
		e->invert.reqid = invert;
		if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg);
		e->reqid = num;
		break;
	case '5':
		if (e->match.spi)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --spi option");

		e->match.spi = 1;
		e->invert.spi = invert;
		if (!xtables_strtoui(optarg, NULL, &num, 0, UINT32_MAX))
			xtables_param_act(XTF_BAD_VALUE, "policy", "--spi", optarg);
		e->spi = num;
		break;
	case '6':
		if (e->match.saddr)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --tunnel-src option");

		if (family == NFPROTO_IPV6)
			xtables_ip6parse_any(optarg, &addr6, &mask6, &naddr);
		else
			xtables_ipparse_any(optarg, &addr, &mask, &naddr);
		if (naddr > 1)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: name resolves to multiple IPs");

		e->match.saddr = 1;
		e->invert.saddr = invert;
		if (family == NFPROTO_IPV6) {
			memcpy(&e->saddr.a6, addr6, sizeof(*addr6));
			memcpy(&e->smask.a6, &mask6, sizeof(mask6));
		} else {
			e->saddr.a4 = addr[0];
			e->smask.a4 = mask;
		}
                break;
	case '7':
		if (e->match.daddr)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --tunnel-dst option");

		if (family == NFPROTO_IPV6)
			xtables_ip6parse_any(optarg, &addr6, &mask6, &naddr);
		else
			xtables_ipparse_any(optarg, &addr, &mask, &naddr);
		if (naddr > 1)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: name resolves to multiple IPs");

		e->match.daddr = 1;
		e->invert.daddr = invert;
		if (family == NFPROTO_IPV6) {
			memcpy(&e->daddr.a6, addr6, sizeof(*addr6));
			memcpy(&e->dmask.a6, &mask6, sizeof(mask6));
		} else {
			e->daddr.a4 = addr[0];
			e->dmask.a4 = mask;
		}
		break;
	case '8':
		if (e->match.proto)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --proto option");

		e->proto = xtables_parse_protocol(optarg);
		if (e->proto != IPPROTO_AH && e->proto != IPPROTO_ESP &&
		    e->proto != IPPROTO_COMP)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: protocol must ah/esp/ipcomp");
		e->match.proto = 1;
		e->invert.proto = invert;
		break;
	case '9':
		if (e->match.mode)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: double --mode option");

		mode = parse_mode(optarg);
		e->match.mode = 1;
		e->invert.mode = invert;
		e->mode = mode;
		break;
	case 'a':
		if (invert)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: can't invert --next option");

		if (++info->len == XT_POLICY_MAX_ELEM)
			xtables_error(PARAMETER_PROBLEM,
			           "policy match: maximum policy depth reached");
		break;
	default:
		return 0;
	}

	return 1;
}
Ejemplo n.º 14
0
Archivo: window.c Proyecto: nfnty/bspwm
void manage_window(xcb_window_t win, rule_consequence_t *csq, int fd)
{
	monitor_t *m = mon;
	desktop_t *d = mon->desk;
	node_t *f = mon->desk->focus;

	parse_rule_consequence(fd, csq);

	if (!csq->manage) {
		free(csq->layer);
		free(csq->state);
		window_show(win);
		return;
	}

	if (csq->node_desc[0] != '\0') {
		coordinates_t ref = {m, d, f};
		coordinates_t trg = {NULL, NULL, NULL};
		if (node_from_desc(csq->node_desc, &ref, &trg) == SELECTOR_OK) {
			m = trg.monitor;
			d = trg.desktop;
			f = trg.node;
		}
	} else if (csq->desktop_desc[0] != '\0') {
		coordinates_t ref = {m, d, NULL};
		coordinates_t trg = {NULL, NULL, NULL};
		if (desktop_from_desc(csq->desktop_desc, &ref, &trg) == SELECTOR_OK) {
			m = trg.monitor;
			d = trg.desktop;
			f = trg.desktop->focus;
		}
	} else if (csq->monitor_desc[0] != '\0') {
		coordinates_t ref = {m, NULL, NULL};
		coordinates_t trg = {NULL, NULL, NULL};
		if (monitor_from_desc(csq->monitor_desc, &ref, &trg) == SELECTOR_OK) {
			m = trg.monitor;
			d = trg.monitor->desk;
			f = trg.monitor->desk->focus;
		}
	}

	if (csq->sticky) {
		m = mon;
		d = mon->desk;
		f = mon->desk->focus;
	}

	if (csq->split_dir[0] != '\0' && f != NULL) {
		direction_t dir;
		if (parse_direction(csq->split_dir, &dir)) {
			presel_dir(m, d, f, dir);
		}
	}

	if (csq->split_ratio != 0 && f != NULL) {
		presel_ratio(m, d, f, csq->split_ratio);
	}

	node_t *n = make_node(win);
	client_t *c = make_client();
	c->border_width = csq->border ? d->border_width : 0;
	n->client = c;
	initialize_client(n);
	initialize_floating_rectangle(n);

	if (c->floating_rectangle.x == 0 && c->floating_rectangle.y == 0) {
		csq->center = true;
	}

	monitor_t *mm = monitor_from_client(c);
	embrace_client(mm, c);
	adapt_geometry(&mm->rectangle, &m->rectangle, n);

	if (csq->center) {
		window_center(m, c);
	}

	snprintf(c->class_name, sizeof(c->class_name), "%s", csq->class_name);
	snprintf(c->instance_name, sizeof(c->instance_name), "%s", csq->instance_name);

	f = insert_node(m, d, n, f);
	clients_count++;

	put_status(SBSC_MASK_NODE_MANAGE, "node_manage 0x%08X 0x%08X 0x%08X 0x%08X\n", m->id, d->id, win, f!=NULL?f->id:0);

	if (f != NULL && f->client != NULL && csq->state != NULL && *(csq->state) == STATE_FLOATING) {
		c->layer = f->client->layer;
	}

	if (csq->layer != NULL) {
		c->layer = *(csq->layer);
	}

	if (csq->state != NULL) {
		set_state(m, d, n, *(csq->state));
	}

	set_hidden(m, d, n, csq->hidden);
	set_sticky(m, d, n, csq->sticky);
	set_private(m, d, n, csq->private);
	set_locked(m, d, n, csq->locked);

	arrange(m, d);

	uint32_t values[] = {CLIENT_EVENT_MASK | (focus_follows_pointer ? XCB_EVENT_MASK_ENTER_WINDOW : 0)};
	xcb_change_window_attributes(dpy, win, XCB_CW_EVENT_MASK, values);

	if (d == m->desk) {
		show_node(d, n);
	} else {
		hide_node(d, n);
	}

	if (!csq->hidden && csq->focus) {
		if (d == mon->desk || csq->follow) {
			focus_node(m, d, n);
		} else {
			activate_node(m, d, n);
		}
	} else {
		stack(d, n, false);
	}

	ewmh_set_wm_desktop(n, d);
	ewmh_update_client_list(false);
	free(csq->layer);
	free(csq->state);
}