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::handleEvent(SomeEvent
&event
) {
69 if (event
.type
== eventmousemove
) {
70 moveTo(event
.x
+ world
.camera
.getX(), event
.y
+ world
.camera
.getY());
71 velx
.setInt(event
.xrel
* 4);
72 vely
.setInt(event
.yrel
* 4);
74 // middle mouse button scrolling
75 if (event
.button
& buttonmiddle
)
76 world
.camera
.moveTo(world
.camera
.getX() - event
.xrel
, world
.camera
.getY() - event
.yrel
, jump
);
77 } else if (!handle_events
) {
78 /* mouse move events are (apparently - see eg C3 agent help) still handled with handle_events disabled, but nothing else */
80 } else if (event
.type
== eventmousebuttondown
) {
81 // do our custom handling
82 if (event
.button
== buttonleft
) {
83 CompoundPart
*a
= world
.partAt(x
, y
);
84 if (a
/* && a->canActivate() */) { // TODO
85 Agent
* parent
= a
->getParent();
89 bool foundport
= false;
90 if (engine
.version
> 2) {
91 for (std::map
<unsigned int, boost::shared_ptr
<OutputPort
> >::iterator i
= parent
->outports
.begin();
92 i
!= parent
->outports
.end(); i
++) {
93 // TODO: 4 is a magic number i pulled out of nooooowhere
94 if (abs(i
->second
->x
+ parent
->x
- x
) < 4 && abs(i
->second
->y
+ parent
->y
- y
) < 4) {
96 if (holdingWire
== 2) {
97 parent
->join(i
->first
, wireOriginAgent
, wireOriginID
);
100 } else if (holdingWire
== 0) {
103 wireOriginAgent
= parent
;
104 wireOriginID
= i
->first
;
110 for (std::map
<unsigned int, boost::shared_ptr
<InputPort
> >::iterator i
= parent
->inports
.begin();
111 i
!= parent
->inports
.end(); i
++) {
112 // TODO: 4 is a magic number i pulled out of nooooowhere
113 if (abs(i
->second
->x
+ parent
->x
- x
) < 4 && abs(i
->second
->y
+ parent
->y
- y
) < 4) {
115 if (holdingWire
== 1) {
116 if (i
->second
->source
) {
119 wireOriginAgent
->join(wireOriginID
, parent
, i
->first
);
123 } else if (holdingWire
== 0) {
124 if (i
->second
->source
) {
127 wireOriginAgent
= i
->second
->source
;
128 wireOriginID
= i
->second
->sourceid
;
129 i
->second
->source
->outports
[i
->second
->sourceid
]->dests
.remove(std::pair
<AgentRef
, unsigned int>(parent
, i
->first
));
130 i
->second
->source
.clear();
134 wireOriginAgent
= parent
;
135 wireOriginID
= i
->first
;
149 // if the agent isn't paused, tell it to handle a click
150 int scriptid
= a
->handleClick(x
- a
->x
- parent
->x
, y
- a
->y
- parent
->y
);
151 if (scriptid
!= -1) {
153 // _p1_ is id of part for button clicks, according to Edynn code
154 // TODO: should _p1_ always be set? :)
155 if (!parent
->paused
) parent
->queueScript(scriptid
, world
.hand(), (int)a
->id
);
157 // annoyingly queueScript doesn't reliably tell us if it did anything useful.
158 // TODO: work out the mess which is queueScript's return values etc
159 if (!parent
->findScript(scriptid
)) return;
161 // fire the associated pointer script too, if necessary
162 // TODO: fuzzie has no idea if this code is remotely correct
163 if (engine
.version
< 3) {
166 eve
= 101; // Pointer Activate 1
169 case 0: eve
+= 2; break; // deactivate
170 case 1: break; // activate 1
171 case 2: eve
+= 1; break; // activate 2
178 if (eve
!= -1) firePointerScript(eve
, a
->getParent());
179 } else if (engine
.version
> 2) {
184 queueScript(116, 0); // Pointer Clicked Background
187 } else if (event
.button
== buttonright
) {
188 if (world
.paused
) return; // TODO: wrong?
190 // picking up and dropping are implictly handled by the scripts (well,
191 // messages) 4 and 5 TODO: check if this is correct behaviour, one issue
192 // is that this isn't instant, another is the messages might only be
193 // fired in c2e when you use MESG WRIT, in which case we'll need to
194 // manually set carrying to NULL and a here, respectively - fuzzie
196 // TODO: c1 support - these attributes are invalid for c1
197 if (!carrying
->suffercollisions() || (carrying
->validInRoomSystem() || engine
.version
== 1)) {
198 carrying
->queueScript(5, this); // drop
200 int eve
; if (engine
.version
< 3) eve
= 54; else eve
= 105;
201 firePointerScript(eve
, carrying
); // Pointer Drop
203 // TODO: is this the correct check?
204 if (carrying
->sufferphysics() && carrying
->suffercollisions()) {
205 // TODO: do this in the pointer agent?
206 carrying
->velx
.setFloat(velx
.getFloat());
207 carrying
->vely
.setFloat(vely
.getFloat());
210 // TODO: some kind of "fail to drop" animation/sound?
213 Agent
*a
= world
.agentAt(x
, y
, false, true);
215 a
->queueScript(4, this); // pickup
217 int eve
; if (engine
.version
< 3) eve
= 53; else eve
= 104;
218 firePointerScript(eve
, a
); // Pointer Pickup
221 } else if (event
.button
== buttonmiddle
) {
222 std::vector
<shared_ptr
<Room
> > rooms
= world
.map
.roomsAt(event
.x
+ world
.camera
.getX(), event
.y
+ world
.camera
.getY());
223 if (rooms
.size() > 0) std::cout
<< "Room at cursor is " << rooms
[0]->id
<< std::endl
;
224 Agent
*a
= world
.agentAt(event
.x
+ world
.camera
.getX(), event
.y
+ world
.camera
.getY(), true);
226 std::cout
<< "Agent under mouse is " << a
->identify();
228 std::cout
<< "No agent under cursor";
229 std::cout
<< std::endl
;