5 * Created by Alyssa Milburn on Tue May 25 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.
20 #include "CompoundAgent.h"
23 #include "Engine.h" // version
24 #include <algorithm> // sort
25 #include <functional> // binary_function
26 #include "caosVM.h" // calculateScriptId
28 // the list of parts is a list of pointers to CompoundPart, so we need a custom sort
29 struct less_part
: public std::binary_function
<CompoundPart
*, CompoundPart
*, bool> {
30 bool operator()(CompoundPart
*x
, CompoundPart
*y
) { return *x
< *y
; }
33 void CompoundAgent::addPart(CompoundPart
*p
) {
35 assert(!part(p
->id
)); // todo: handle better
37 // TODO: we should prbly insert at the right place, not call sort
39 std::sort(parts
.begin(), parts
.end(), less_part());
41 if (engine
.version
< 3 && parts
.size() == 1) { // adding the first part in c1/c2
42 // TODO: this is zorder hackery - probably the right thing to do, but needs thinking about more
43 unsigned int z
= p
->zorder
;
49 void CompoundAgent::delPart(unsigned int id
) {
52 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
53 if ((*x
)->id
== id
) { delete *x
; parts
.erase(x
); return; }
56 throw caosException("delPart got a bad id"); // TODO: handle this exception properly
59 CompoundPart
*CompoundAgent::part(unsigned int id
) {
60 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
61 if ((*x
)->id
== id
) return *x
;
66 CompoundAgent::CompoundAgent(unsigned char _family
, unsigned char _genus
, unsigned short _species
, unsigned int plane
,
67 std::string spritefile
, unsigned int firstimage
, unsigned int imagecount
) :
68 Agent(_family
, _genus
, _species
, plane
) {
69 // TODO: we ignore image count acos it sucks
70 CompoundPart
*p
= new DullPart(this, 0, spritefile
, firstimage
, 0, 0, 0);
74 for (unsigned int i
= 0; i
< 6; i
++) {
75 hotspots
[i
].left
= -1; hotspots
[i
].right
= -1; hotspots
[i
].top
= -1;
76 hotspots
[i
].bottom
= -1;
77 hotspotfunctions
[i
].hotspot
= -1;
81 CompoundAgent::CompoundAgent(std::string _spritefile
, unsigned int _firstimage
, unsigned int _imagecount
) : Agent(0, 0, 0, 0) {
82 // TODO: think about plane
84 spritefile
= _spritefile
;
85 firstimage
= _firstimage
;
86 imagecount
= _imagecount
;
88 for (unsigned int i
= 0; i
< 6; i
++) {
89 hotspots
[i
].left
= -1; hotspots
[i
].right
= -1; hotspots
[i
].top
= -1;
90 hotspots
[i
].bottom
= -1;
91 hotspotfunctions
[i
].hotspot
= -1;
95 CompoundAgent::~CompoundAgent() {
96 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
101 void CompoundAgent::setZOrder(unsigned int plane
) {
102 Agent::setZOrder(plane
);
103 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) (*x
)->zapZOrder();
104 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) (*x
)->addZOrder();
107 void CompoundAgent::tick() {
109 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
117 int CompoundAgent::handleClick(float clickx
, float clicky
) {
118 if (!activateable()) return -1;
120 if (engine
.version
> 2) {
121 return Agent::handleClick(clickx
, clicky
);
124 // the hotspots are relative to us
125 clickx
-= x
; clicky
-= y
;
127 // TODO: this whole thing needs more thought/work
130 if (engine
.version
== 1) i
= 3; // skip C1 creature-only points
132 if (hotspotfunctions
[i
].hotspot
< 0) continue;
133 if (hotspotfunctions
[i
].hotspot
>= 6) continue;
135 if (engine
.version
== 1) {
136 // C1: we only check 3/4/5
137 func
= calculateScriptId(i
- 3);
139 if (hotspotfunctions
[i
].mask
== 1) continue; // creature only
140 func
= calculateScriptId(hotspotfunctions
[i
].message
);
143 int j
= hotspotfunctions
[i
].hotspot
;
145 if (hotspots
[j
].left
== -1) continue;
146 // TODO: check other items for being -1?
148 if ((clickx
>= hotspots
[j
].left
&& clickx
<= hotspots
[j
].right
) &&
149 (clicky
>= hotspots
[j
].top
&& clicky
<= hotspots
[j
].bottom
)) {
157 bool CompoundAgent::fireScript(unsigned short event
, Agent
*from
, caosVar one
, caosVar two
) {
158 // TODO: this is a hack to deal with ACTV on compound agents in c1/c2
159 if (engine
.version
< 3 && actv
.getInt() == event
) return false;
161 return Agent::fireScript(event
, from
, one
, two
);
164 void CompoundAgent::setHotspotLoc(unsigned int id
, int l
, int t
, int r
, int b
) {
167 hotspots
[id
].left
= l
;
168 hotspots
[id
].top
= t
;
169 hotspots
[id
].right
= r
;
170 hotspots
[id
].bottom
= b
;
173 void CompoundAgent::setHotspotFunc(unsigned int id
, unsigned int f
) {
176 hotspotfunctions
[id
].hotspot
= f
;
178 // TODO: this tries to make c2 work nicely, necessary?
179 hotspotfunctions
[id
].mask
= 3;
181 hotspotfunctions
[id
].message
= calculateScriptId(id
);
183 hotspotfunctions
[id
].message
= calculateScriptId(id
- 3);
186 void CompoundAgent::setHotspotFuncDetails(unsigned int id
, uint16 m
, uint8 f
) {
189 hotspotfunctions
[id
].message
= m
;
190 hotspotfunctions
[id
].mask
= f
;