<commit_before>/*
 *  PointerAgent.cpp
 *  openc2e
 *
 *  Created by <NAME> on Tue Aug 30 2005.
 *  Copyright (c) 2005 <NAME>. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 */

#include "PointerAgent.h"
#include "openc2e.h"
#include "World.h"
#include "Engine.h"
#include "caosVM.h"
#include "Room.h"

// TODO: change imagecount?
PointerAgent::PointerAgent(std::string spritefile) : SimpleAgent(2, 1, 1, INT_MAX, spritefile, 0, 0) {
	name = "hand";
	handle_events = true;
	holdingWire = 0;
	wireOriginID = 0;
	// TODO: verify attributes on the pointer in c2e
	attr.setInt(256); // camera shy
}

void PointerAgent::finishInit() {
	Agent::finishInit();

	// float relative to main camera
	attr.setInt(attr.getInt() & 32);
	floatSetup();
}

// TODO: this should have a queueScript equiv too
void PointerAgent::firePointerScript(unsigned short event, Agent *src) {
	assert(src); // TODO: I /think/ this should only be called by the engine..
	shared_ptr<script> s = src->findScript(event);
	if (!s && engine.version < 3) { // TODO: are we sure this doesn't apply to c2e?
		s = findScript(event); // TODO: we should make sure this actually belongs to the pointer agent and isn't a fallback, maybe
	}
	if (!s) return;
	if (!vm) vm = world.getVM(this);
	if (vm->fireScript(s, false, src)) { // TODO: should FROM be src?
		vm->setTarg(this);
		zotstack();
	}
}

void PointerAgent::physicsTick() {
	// TODO: this is a hack, which does nothing, because we set a velocity in main() but also move the cursor manually
}

void PointerAgent::kill() {
	// pointer agent isn't killable
}

void PointerAgent::handleEvent(SomeEvent &event) {
	if (event.type == eventmousemove) {
		moveTo(event.x + world.camera.getX(), event.y + world.camera.getY());
		velx.setInt(event.xrel * 4);
		vely.setInt(event.yrel * 4);

		// middle mouse button scrolling
		if (event.button & buttonmiddle)
			world.camera.moveTo(world.camera.getX() - event.xrel, world.camera.getY() - event.yrel, jump);
	} else if (!handle_events) {
		/* mouse move events are (apparently - see eg C3 agent help) still handled with handle_events disabled, but nothing else */
		return;
	} else if (event.type == eventmousebuttondown) {
		// do our custom handling
		if (event.button == buttonleft) {
			CompoundPart *a = world.partAt(x, y);
			if (a /* && a->canActivate() */) { // TODO
				Agent* parent = a->getParent();

				int eve = -1;
			
				bool foundport = false;
				if (engine.version > 2) {
					for (std::map<unsigned int, boost::shared_ptr<OutputPort> >::iterator i = parent->outports.begin();
							 i != parent->outports.end(); i++) {
						// TODO: 4 is a magic number i pulled out of nooooowhere
						if (abs(i->second->x + parent->x - x) < 4 && abs(i->second->y + parent->y - y) < 4) {
							foundport = true;
							if (holdingWire == 2) {
								parent->join(i->first, wireOriginAgent, wireOriginID);
								holdingWire = 0;
								eve = 111;
							} else if (holdingWire == 0) {
								eve = 110;
								holdingWire = 1;
								wireOriginAgent = parent;
								wireOriginID = i->first;
							}
							break;
						}
					}
					if (!foundport) {
						for (std::map<unsigned int, boost::shared_ptr<InputPort> >::iterator i = parent->inports.begin();
								 i != parent->inports.end(); i++) {
							// TODO: 4 is a magic number i pulled out of nooooowhere
							if (abs(i->second->x + parent->x - x) < 4 && abs(i->second->y + parent->y - y) < 4) {
								foundport = true;
								if (holdingWire == 1) {
									wireOriginAgent->join(wireOriginID, parent, i->first);
									holdingWire = 0;
									eve = 111;
								} else if (holdingWire == 0) {
									if (i->second->source) {
										eve = 112;
										holdingWire = 1;
										wireOriginAgent = i->second->source;
										wireOriginID = i->second->sourceid;
										i->second->source->outports[i->second->sourceid]->dests.remove(std::pair<AgentRef, unsigned int>(parent, i->first));
									} else {
										eve = 110;
										holdingWire = 2;
										wireOriginAgent = parent;
										wireOriginID = i->first;
									}
								}
								break;
							}
						}
					}
				}

				if (!foundport) {
					if (holdingWire) {
						holdingWire = 0;
						eve = 113;
					} else {
						// if the agent isn't paused, tell it to handle a click
						int scriptid = a->handleClick(x - a->x - parent->x, y - a->y - parent->y);
						if (scriptid != -1) {
							// fire the script
							// _p1_ is id of part for button clicks, according to Edynn code
							// TODO: should _p1_ always be set? :)
							if (!parent->paused) parent->queueScript(scriptid, world.hand(), (int)a->id);<commit_msg>Fix some of the port bugs. Notably, it shouldn't be possible to have multiple connections to a single input port any more.<commit_after>/*
 *  PointerAgent.cpp
 *  openc2e
 *
 *  Created by <NAME> on Tue Aug 30 2005.
 *  Copyright (c) 2005 <NAME>. All rights reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 */

#include "PointerAgent.h"
#include "openc2e.h"
#include "World.h"
#include "Engine.h"
#include "caosVM.h"
#include "Room.h"

// TODO: change imagecount?
PointerAgent::PointerAgent(std::string spritefile) : SimpleAgent(2, 1, 1, INT_MAX, spritefile, 0, 0) {
	name = "hand";
	handle_events = true;
	holdingWire = 0;
	wireOriginID = 0;
	// TODO: verify attributes on the pointer in c2e
	attr.setInt(256); // camera shy
}

void PointerAgent::finishInit() {
	Agent::finishInit();

	// float relative to main camera
	attr.setInt(attr.getInt() & 32);
	floatSetup();
}

// TODO: this should have a queueScript equiv too
void PointerAgent::firePointerScript(unsigned short event, Agent *src) {
	assert(src); // TODO: I /think/ this should only be called by the engine..
	shared_ptr<script> s = src->findScript(event);
	if (!s && engine.version < 3) { // TODO: are we sure this doesn't apply to c2e?
		s = findScript(event); // TODO: we should make sure this actually belongs to the pointer agent and isn't a fallback, maybe
	}
	if (!s) return;
	if (!vm) vm = world.getVM(this);
	if (vm->fireScript(s, false, src)) { // TODO: should FROM be src?
		vm->setTarg(this);
		zotstack();
	}
}

void PointerAgent::physicsTick() {
	// TODO: this is a hack, which does nothing, because we set a velocity in main() but also move the cursor manually
}

void PointerAgent::kill() {
	// pointer agent isn't killable
}

void PointerAgent::handleEvent(SomeEvent &event) {
	if (event.type == eventmousemove) {
		moveTo(event.x + world.camera.getX(), event.y + world.camera.getY());
		velx.setInt(event.xrel * 4);
		vely.setInt(event.yrel * 4);

		// middle mouse button scrolling
		if (event.button & buttonmiddle)
			world.camera.moveTo(world.camera.getX() - event.xrel, world.camera.getY() - event.yrel, jump);
	} else if (!handle_events) {
		/* mouse move events are (apparently - see eg C3 agent help) still handled with handle_events disabled, but nothing else */
		return;
	} else if (event.type == eventmousebuttondown) {
		// do our custom handling
		if (event.button == buttonleft) {
			CompoundPart *a = world.partAt(x, y);
			if (a /* && a->canActivate() */) { // TODO
				Agent* parent = a->getParent();

				int eve = -1;
			
				bool foundport = false;
				if (engine.version > 2) {
					for (std::map<unsigned int, boost::shared_ptr<OutputPort> >::iterator i = parent->outports.begin();
							 i != parent->outports.end(); i++) {
						// TODO: 4 is a magic number i pulled out of nooooowhere
						if (abs(i->second->x + parent->x - x) < 4 && abs(i->second->y + parent->y - y) < 4) {
							foundport = true;
							if (holdingWire == 2) {
								parent->join(i->first, wireOriginAgent, wireOriginID);
								holdingWire = 0;
								eve = 111;
							} else if (holdingWire == 0) {
								eve = 110;
								holdingWire = 1;
								wireOriginAgent = parent;
								wireOriginID = i->first;
							}
							break;
						}
					}
					if (!foundport) {
						for (std::map<unsigned int, boost::shared_ptr<InputPort> >::iterator i = parent->inports.begin();
								 i != parent->inports.end(); i++) {
							// TODO: 4 is a magic number i pulled out of nooooowhere
							if (abs(i->second->x + parent->x - x) < 4 && abs(i->second->y + parent->y - y) < 4) {
								foundport = true;
								if (holdingWire == 1) {
									if (i->second->source) {
										eve = 114;
									} else {
										wireOriginAgent->join(wireOriginID, parent, i->first);
										holdingWire = 0;
										eve = 111;
									}
								} else if (holdingWire == 0) {
									if (i->second->source) {
										eve = 112;
										holdingWire = 1;
										wireOriginAgent = i->second->source;
										wireOriginID = i->second->sourceid;
										i->second->source->outports[i->second->sourceid]->dests.remove(std::pair<AgentRef, unsigned int>(parent, i->first));
										i->second->source.clear();
									} else {
										eve = 110;
										holdingWire = 2;
										wireOriginAgent = parent;
										wireOriginID = i->first;
									}
								}
								break;
							}
						}
					}
				}

				if (!foundport) {
					if (holdingWire) {
						holdingWire = 0;
						eve = 113;
					} else {
						// if the agent isn't paused, tell it to handle a click
						int scriptid = a->handleClick(x - a->x - parent->x, y - a->y - parent->y);
						if (scriptid != -1) {
							// fire the script
							// _p1_ is id of part for button clicks, according to Edynn code
							// TODO: should _p1_ always be set? :)
							if (!parent->paused) parent->queueScript(scriptid, world.hand(), (int)a->id);
{'fraction_non_alphanumeric': 0.13634208779747795, 'fraction_numerical': 0.0135583578268702, 'mean_word_length': 2.6297315898141775, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 121, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3987772', 'n_tokens_mistral': 4386, 'n_tokens_neox': 3309, 'n_words': 1074}