5 * Created by Alyssa Milburn on Tue Jun 01 2004.
6 * Copyright (c) 2004 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.
25 #include "Engine.h" // version
27 #include <boost/format.hpp>
31 ELAS (command) elas (integer)
34 Sets the elasticity (in other words, bounciness) of the TARG agent.
36 void caosVM::c_ELAS() {
38 VM_PARAM_INTEGER(elas
)
48 Returns the elasticity of the TARG agent.
50 void caosVM::v_ELAS() {
54 result
.setInt(targ
->elas
);
58 MVTO (command) x (float) y (float)
60 %pragma variants c1 c2 cv c3 sm
63 Places the TARG agent at the given x/y position in the world (using the upper left hand corner of the agent).
65 void caosVM::c_MVTO() {
74 MVBY (command) x (float) y (float)
76 %pragma variants c1 c2 cv c3 sm
79 Changes the TARG agent's position by the given relative distances.
81 void caosVM::c_MVBY() {
86 targ
->moveTo(targ
->x
+ x
, targ
->y
+ y
);
92 %pragma variants c2 cv c3 sm
94 Returns the current horizontal velocity, in pixels/tick, of the TARG agent.
96 void caosVM::v_VELX() {
98 valueStack
.push_back(targ
->velx
);
100 void caosVM::s_VELX() {
101 VM_PARAM_VALUE(newvalue
)
102 caos_assert(newvalue
.hasDecimal());
105 targ
->velx
= newvalue
;
111 %pragma variants c2 cv c3 sm
113 Returns the current vertical velocity, in pixels/tick, of the TARG agent.
115 void caosVM::v_VELY() {
117 valueStack
.push_back(targ
->vely
);
119 void caosVM::s_VELY() {
120 VM_PARAM_VALUE(newvalue
)
121 caos_assert(newvalue
.hasDecimal());
124 targ
->vely
= newvalue
;
126 // a whole bunch of Creatures 2 scripts/COBs depend on this ('setv vely 0' to activate gravity)
127 if (engine
.version
== 2) targ
->grav
.setInt(1);
131 OBST (float) direction (integer)
133 %pragma variants cv c3 sm
135 Returns the distance from the TARG agent to the nearest wall that it might collide with in the given direction.
136 (except right now it just gives the direction to the nearest wall at world edge - fuzzie)
138 void caosVM::v_OBST() {
140 VM_PARAM_INTEGER(direction
) caos_assert(direction
>= 0); caos_assert(direction
<= 3);
143 * TODO: CL's docs say to return "a very large number" if distance is greater than rnge - if (!collided)?
144 * TODO: c2 docs say "from the centre point of TARG".. same in c2e? or do we need a separate function?
145 * also, this code is untested :) - fuzzie
150 Point src
= targ
->boundingBoxPoint(direction
);
155 dest
.x
-= targ
->range
.getFloat(); break;
157 dest
.x
+= targ
->range
.getFloat(); break;
159 dest
.y
-= targ
->range
.getFloat(); break;
161 dest
.y
+= targ
->range
.getFloat(); break;
164 shared_ptr
<Room
> ourRoom
= world
.map
.roomAt(src
.x
, src
.y
);
166 // TODO: is this correct behaviour?
167 result
.setFloat(0.0f
);
171 unsigned int dummy1
; Line dummy2
; Point point
;
172 bool collided
= world
.map
.collideLineWithRoomSystem(src
, dest
, ourRoom
, point
, dummy2
, dummy1
, targ
->perm
);
175 case 0: result
.setFloat(src
.x
- point
.x
); break;
176 case 1: result
.setFloat(point
.x
- src
.x
); break;
177 case 2: result
.setFloat(src
.y
- point
.y
); break;
178 case 3: result
.setFloat(point
.y
- src
.y
); break;
183 OBST (integer) direction (integer)
186 %pragma implementation caosVM::v_OBST_c2
188 Returns the distance from the TARG agent to the nearest wall that it might collide with in the given direction.
190 void caosVM::v_OBST_c2() {
191 VM_PARAM_INTEGER(direction
)
197 case 0: dx
= -10000; break; // left
198 case 1: dx
= 10000; break; // right
199 case 2: dy
= -10000; break; // up
200 case 3: dy
= 10000; break; // down
201 default: caos_assert(false);
204 Point src
= targ
->boundingBoxPoint(direction
);
207 double delta
= 1000000000;
208 bool collided
= false;
210 targ
->findCollisionInDirection(direction
, src
, dx
, dy
, deltapt
, delta
, collided
, false);
213 result
.setInt(INT_MAX
);
215 result
.setInt(abs(deltapt
.x
+ deltapt
.y
)); // only one will be set
219 TMVB (integer) deltax (float) deltay (float)
222 Returns 1 if the TARG agent could move by (deltax, deltay) and still be in room system, or 0 otherwise.
224 void caosVM::v_TMVB() {
225 VM_PARAM_FLOAT(deltay
)
226 VM_PARAM_FLOAT(deltax
)
230 if (targ
->validInRoomSystem(Point(targ
->x
+ deltax
, targ
->y
+ deltay
), targ
->getWidth(), targ
->getHeight(), targ
->perm
))
237 TMVT (integer) x (float) y (float)
240 Returns 1 if the TARG agent could move to (x, y) and still be in room system, or 0 if otherwise.
242 void caosVM::v_TMVT() {
249 if (targ
->validInRoomSystem(Point(x
, y
), targ
->getWidth(), targ
->getHeight(), targ
->perm
))
256 TMVF (integer) x (float) y (float)
259 Returns 1 if the TARG Creature could move foot to (x, y) and still be in room system, or 0 if otherwise.
261 void caosVM::v_TMVF() {
267 result
.setInt(1); // TODO: don't hardcode
271 ACCG (command) accel (float)
274 Sets the TARG agent's free-fall acceleration, in pixels/tick squared.
276 void caosVM::c_ACCG() {
278 VM_PARAM_FLOAT(accel
)
288 Returns the TARG agent's free-fall acceleration, in pixels/tick squared.
290 void caosVM::v_ACCG() {
294 result
.setFloat(targ
->accg
.getFloat());
301 %pragma implementation caosVM::v_ACCG_c2
302 %pragma saveimpl caosVM::s_ACCG_c2
304 Returns the TARG agent's free-fall acceleration, in pixels/tick squared.
306 CAOS_LVALUE_TARG_SIMPLE(ACCG_c2
, targ
->accg
)
309 AERO (command) aero (float)
312 Sets the aerodynamics of the TARG agent to the given float value.
314 void caosVM::c_AERO() {
326 Returns the aerodynamics of the TARG agent.
328 void caosVM::v_AERO() {
332 result
.setFloat(targ
->aero
.getFloat());
339 %pragma implementation caosVM::v_AERO_c2
340 %pragma saveimpl caosVM::s_AERO_c2
342 Returns the aerodynamics of the TARG agent.
344 CAOS_LVALUE_TARG_SIMPLE(AERO_c2
, targ
->aero
)
347 RELX (float) first (agent) second (agent)
350 Returns the relative horizontal distance between the centers of the two given agents.
352 void caosVM::v_RELX() {
354 VM_PARAM_VALIDAGENT(second
)
355 VM_PARAM_VALIDAGENT(first
)
357 float one
= first
->x
+ (first
->getWidth() / 2.0);
358 float two
= second
->x
+ (second
->getWidth() / 2.0);
360 result
.setFloat(two
- one
);
364 RELY (float) first (agent) second (agent)
367 Returns the relative vertical distance between the centers of the two given agents.
369 void caosVM::v_RELY() {
371 VM_PARAM_VALIDAGENT(second
)
372 VM_PARAM_VALIDAGENT(first
)
374 float one
= first
->y
+ (first
->getHeight() / 2.0);
375 float two
= second
->y
+ (second
->getHeight() / 2.0);
377 result
.setFloat(two
- one
);
384 %pragma implementation caosVM::v_RELX_c2
386 Returns the relative horizontal distance between the script owner and the target agent.
388 void caosVM::v_RELX_c2() {
393 result
.setInt((int)targ
->x
+ (targ
->getWidth() / 2) - ((int)owner
->x
+ (owner
->getWidth() / 2)));
400 %pragma implementation caosVM::v_RELY_c2
402 Returns the relative vertical distance between the script owner and the target agent.
404 void caosVM::v_RELY_c2() {
409 result
.setInt((int)targ
->y
+ (targ
->getHeight() / 2) - ((int)owner
->y
+ (owner
->getHeight() / 2)));
413 VELO (command) xvel (float) yvel (float)
416 Sets the horizontal and vertical velocity of the TARG agent, in pixels/tick.
418 void caosVM::c_VELO() {
425 targ
->velx
.setFloat(velx
);
427 targ
->vely
.setFloat(vely
);
431 MVSF (command) x (float) y (float)
434 Move the target agent to an area inside the room system at about (x, y).
435 This allows 'safe' moves.
437 void caosVM::c_MVSF() {
442 if (!targ
->tryMoveToPlaceAround(x
, y
))
443 throw creaturesException(boost::str(boost::format("MVSF failed to find a safe place around (%d, %d)") % x
% y
));
450 Returns the TARG agent's coefficient of friction as a percentage.
452 void caosVM::v_FRIC() {
456 result
.setFloat(targ
->friction
);
460 FRIC (command) friction (integer)
463 Sets the TARG agent's coefficient of friction, or the percentage of motion that will be lost as it slides on a
466 void caosVM::c_FRIC() {
468 VM_PARAM_INTEGER(friction
) caos_assert(friction
>= 0); caos_assert(friction
<= 100);
471 targ
->friction
= friction
;
478 Returns 1 if the TARG agent is moving due to gravity, or 0 if otherwise.
480 void caosVM::v_FALL() {
484 // XXX: this probably isn't quite correct, but it's close enough for now.
494 %pragma variants c1 c2 cv c3 sm
496 Returns an integer representing the motion status of the TARG agent. 0 is autonomous, 1 is moving by mouse, 2 is
497 floating, 3 is inside a vehicle, and 4 is being carried.
499 void caosVM::v_MOVS() {
500 // TODO: check these values match c1
506 // TODO: agents can possibly have multiple MOVS states right now, we should make sure to avoid that
507 if (targ
->carriedby
) {
508 if (targ
->carriedby
.get() == (Agent
*)world
.hand())
512 } else if (targ
->invehicle
)
514 else if (targ
->floatable()) // TODO: good?
519 valueStack
.push_back(r
);
521 void caosVM::s_MOVS() {
522 VM_PARAM_VALUE(newvalue
)
523 caos_assert(newvalue
.hasInt());
526 // TODO: implement MOVS setting
530 FLTO (command) x (float) y (float)
533 Sets the TARG agent to float its top-left corner (x, y) away from the top-left corner of the FREL agent.
535 void caosVM::c_FLTO() {
544 FREL (command) agent (agent)
547 Sets the agent the TARG agent floats relative to. You must set the 'floatable' attribute for this to work.
548 The default is NULL, which means the target agent floats relative to the main camera.
550 void caosVM::c_FREL() {
551 VM_PARAM_AGENT(agent
)
554 targ
->floatTo(agent
);
561 Returns the x value of the TARG agent's floating vector.
563 void caosVM::v_FLTX() {
566 if (targ
->floatingagent
)
567 result
.setFloat(targ
->floatingagent
->x
- targ
->x
);
569 result
.setFloat(world
.camera
.getX() - targ
->x
);
576 Returns the y value of the TARG agent's floating vector.
578 void caosVM::v_FLTY() {
581 if (targ
->floatingagent
)
582 result
.setFloat(targ
->floatingagent
->x
- targ
->x
);
584 result
.setFloat(world
.camera
.getX() - targ
->x
);
588 MCRT (command) x (integer) y (integer)
590 %pragma variants c1 c2
592 Remove limits from target object and move it to (x, y).
594 void caosVM::c_MCRT() {
603 CAOS_LVALUE_TARG_SIMPLE(REST
, targ
->rest
)