5 * Created by Alyssa Milburn on Tue Aug 30 2005.
6 * Copyright (c) 2005 Alyssa Milburn. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
20 #include "PointerAgent.h"
27 // TODO: change imagecount?
28 PointerAgent::PointerAgent(std::string spritefile
) : SimpleAgent(2, 1, 1, INT_MAX
, spritefile
, 0, 0) {
33 // TODO: verify attributes on the pointer in c2e
34 attr
.setInt(256); // camera shy
37 void PointerAgent::finishInit() {
40 // float relative to main camera
41 attr
.setInt(attr
.getInt() & 32);
45 // TODO: this should have a queueScript equiv too
46 void PointerAgent::firePointerScript(unsigned short event
, Agent
*src
) {
47 assert(src
); // TODO: I /think/ this should only be called by the engine..
48 shared_ptr
<script
> s
= src
->findScript(event
);
49 if (!s
&& engine
.version
< 3) { // TODO: are we sure this doesn't apply to c2e?
50 s
= findScript(event
); // TODO: we should make sure this actually belongs to the pointer agent and isn't a fallback, maybe
53 if (!vm
) vm
= world
.getVM(this);
54 if (vm
->fireScript(s
, false, src
)) { // TODO: should FROM be src?
60 void PointerAgent::physicsTick() {
61 // TODO: this is a hack, which does nothing, because we set a velocity in main() but also move the cursor manually
64 void PointerAgent::kill() {
65 // pointer agent isn't killable
68 void PointerAgent::setHotspot(int x
, int y
) {
73 void PointerAgent::handleEvent(SomeEvent
&event
) {
74 int x
= pointerX(), y
= pointerY();
76 if (event
.type
== eventmousemove
) {
77 moveTo(event
.x
+ world
.camera
.getX() - hotspotx
, event
.y
+ world
.camera
.getY() - hotspoty
);
78 velx
.setInt(event
.xrel
* 4);
79 vely
.setInt(event
.yrel
* 4);
81 // middle mouse button scrolling
82 if (event
.button
& buttonmiddle
)
83 world
.camera
.moveTo(world
.camera
.getX() - event
.xrel
, world
.camera
.getY() - event
.yrel
, jump
);
84 } else if (!handle_events
) {
85 /* mouse move events are (apparently - see eg C3 agent help) still handled with handle_events disabled, but nothing else */
87 } else if (event
.type
== eventmousebuttondown
) {
88 // do our custom handling
89 if (event
.button
== buttonleft
) {
90 CompoundPart
*a
= world
.partAt(x
, y
);
91 if (a
/* && a->canActivate() */) { // TODO
92 Agent
* parent
= a
->getParent();
96 bool foundport
= false;
97 if (engine
.version
> 2) {
98 for (std::map
<unsigned int, boost::shared_ptr
<OutputPort
> >::iterator i
= parent
->outports
.begin();
99 i
!= parent
->outports
.end(); i
++) {
100 // TODO: 4 is a magic number i pulled out of nooooowhere
101 if (abs(i
->second
->x
+ parent
->x
- x
) < 4 && abs(i
->second
->y
+ parent
->y
- y
) < 4) {
103 if (holdingWire
== 2) {
104 parent
->join(i
->first
, wireOriginAgent
, wireOriginID
);
107 } else if (holdingWire
== 0) {
110 wireOriginAgent
= parent
;
111 wireOriginID
= i
->first
;
117 for (std::map
<unsigned int, boost::shared_ptr
<InputPort
> >::iterator i
= parent
->inports
.begin();
118 i
!= parent
->inports
.end(); i
++) {
119 // TODO: 4 is a magic number i pulled out of nooooowhere
120 if (abs(i
->second
->x
+ parent
->x
- x
) < 4 && abs(i
->second
->y
+ parent
->y
- y
) < 4) {
122 if (holdingWire
== 1) {
123 if (i
->second
->source
) {
126 wireOriginAgent
->join(wireOriginID
, parent
, i
->first
);
130 } else if (holdingWire
== 0) {
131 if (i
->second
->source
) {
134 wireOriginAgent
= i
->second
->source
;
135 wireOriginID
= i
->second
->sourceid
;
136 i
->second
->source
->outports
[i
->second
->sourceid
]->dests
.remove(std::pair
<AgentRef
, unsigned int>(parent
, i
->first
));
137 i
->second
->source
.clear();
141 wireOriginAgent
= parent
;
142 wireOriginID
= i
->first
;
156 // if the agent isn't paused, tell it to handle a click
157 int scriptid
= a
->handleClick(x
- a
->x
- parent
->x
, y
- a
->y
- parent
->y
);
158 if (scriptid
!= -1) {
160 // _p1_ is id of part for button clicks, according to Edynn code
161 // TODO: should _p1_ always be set? :)
162 if (!parent
->paused
) parent
->queueScript(scriptid
, world
.hand(), (int)a
->id
);
164 // annoyingly queueScript doesn't reliably tell us if it did anything useful.
165 // TODO: work out the mess which is queueScript's return values etc
166 if (!parent
->findScript(scriptid
)) return;
168 // fire the associated pointer script too, if necessary
169 // TODO: fuzzie has no idea if this code is remotely correct
170 if (engine
.version
< 3) {
173 eve
= 101; // Pointer Activate 1
176 case 0: eve
+= 2; break; // deactivate
177 case 1: break; // activate 1
178 case 2: eve
+= 1; break; // activate 2
185 if (eve
!= -1) firePointerScript(eve
, a
->getParent());
186 } else if (engine
.version
> 2) {
191 queueScript(116, 0); // Pointer Clicked Background
194 } else if (event
.button
== buttonright
) {
195 if (world
.paused
) return; // TODO: wrong?
197 // picking up and dropping are implictly handled by the scripts (well,
198 // messages) 4 and 5 TODO: check if this is correct behaviour, one issue
199 // is that this isn't instant, another is the messages might only be
200 // fired in c2e when you use MESG WRIT, in which case we'll need to
201 // manually set carrying to NULL and a here, respectively - fuzzie
203 // TODO: c1 support - these attributes are invalid for c1
204 if (!carrying
->suffercollisions() || (carrying
->validInRoomSystem() || engine
.version
== 1)) {
205 carrying
->queueScript(5, this); // drop
207 int eve
; if (engine
.version
< 3) eve
= 54; else eve
= 105;
208 firePointerScript(eve
, carrying
); // Pointer Drop
210 // TODO: is this the correct check?
211 if (carrying
->sufferphysics() && carrying
->suffercollisions()) {
212 // TODO: do this in the pointer agent?
213 carrying
->velx
.setFloat(velx
.getFloat());
214 carrying
->vely
.setFloat(vely
.getFloat());
217 // TODO: some kind of "fail to drop" animation/sound?
220 Agent
*a
= world
.agentAt(x
, y
, false, true);
222 a
->queueScript(4, this); // pickup
224 int eve
; if (engine
.version
< 3) eve
= 53; else eve
= 104;
225 firePointerScript(eve
, a
); // Pointer Pickup
228 } else if (event
.button
== buttonmiddle
) {
229 std::vector
<shared_ptr
<Room
> > rooms
= world
.map
.roomsAt(x
, y
);
230 if (rooms
.size() > 0) std::cout
<< "Room at cursor is " << rooms
[0]->id
<< std::endl
;
231 Agent
*a
= world
.agentAt(x
, y
, true);
233 std::cout
<< "Agent under mouse is " << a
->identify();
235 std::cout
<< "No agent under cursor";
236 std::cout
<< std::endl
;