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"
24 #include "Engine.h" // version
25 #include <algorithm> // sort
26 #include <functional> // binary_function
27 #include "caosVM.h" // calculateScriptId
29 // the list of parts is a list of pointers to CompoundPart, so we need a custom sort
30 struct less_part
: public std::binary_function
<CompoundPart
*, CompoundPart
*, bool> {
31 bool operator()(CompoundPart
*x
, CompoundPart
*y
) { return *x
< *y
; }
34 void CompoundAgent::addPart(CompoundPart
*p
) {
36 assert(!part(p
->id
)); // todo: handle better
38 // todo: we should prbly insert at the right place, not call sort
40 std::sort(parts
.begin(), parts
.end(), less_part());
43 void CompoundAgent::delPart(unsigned int id
) {
46 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
47 if ((*x
)->id
== id
) { delete *x
; parts
.erase(x
); return; }
50 throw caosException("delPart got a bad id"); // TODO: handle this exception properly
53 CompoundPart
*CompoundAgent::part(unsigned int id
) {
54 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
55 if ((*x
)->id
== id
) return *x
;
60 CompoundAgent::CompoundAgent(unsigned char _family
, unsigned char _genus
, unsigned short _species
, unsigned int plane
,
61 std::string spritefile
, unsigned int firstimage
, unsigned int imagecount
) :
62 Agent(_family
, _genus
, _species
, plane
) {
63 // TODO: we ignore image count acos it sucks
64 CompoundPart
*p
= new DullPart(this, 0, spritefile
, firstimage
, 0, 0, 0);
68 for (unsigned int i
= 0; i
< 6; i
++) {
69 hotspots
[i
].left
= -1; hotspots
[i
].right
= -1; hotspots
[i
].top
= -1;
70 hotspots
[i
].bottom
= -1;
71 hotspotfunctions
[i
].hotspot
= -1;
75 CompoundAgent::CompoundAgent(std::string _spritefile
, unsigned int _firstimage
, unsigned int _imagecount
) : Agent(0, 0, 0, 0) {
76 // TODO: think about plane
78 spritefile
= _spritefile
;
79 firstimage
= _firstimage
;
80 imagecount
= _imagecount
;
82 for (unsigned int i
= 0; i
< 6; i
++) {
83 hotspots
[i
].left
= -1; hotspots
[i
].right
= -1; hotspots
[i
].top
= -1;
84 hotspots
[i
].bottom
= -1;
85 hotspotfunctions
[i
].hotspot
= -1;
89 CompoundAgent::~CompoundAgent() {
90 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
95 void CompoundAgent::setZOrder(unsigned int plane
) {
96 Agent::setZOrder(plane
);
97 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) (*x
)->zapZOrder();
98 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) (*x
)->addZOrder();
101 void CompoundAgent::tick() {
103 for (std::vector
<CompoundPart
*>::iterator x
= parts
.begin(); x
!= parts
.end(); x
++) {
111 void CompoundAgent::handleClick(float clickx
, float clicky
) {
112 if (engine
.version
> 2) {
113 Agent::handleClick(clickx
, clicky
);
117 // the hotspots are relative to us
118 clickx
-= x
; clicky
-= y
;
120 // TODO: this whole thing needs more thought/work
123 if (engine
.version
== 1) i
= 3; // skip C1 creature-only points
125 if (hotspotfunctions
[i
].hotspot
< 0) continue;
126 if (hotspotfunctions
[i
].hotspot
>= 6) continue;
128 if (engine
.version
== 1) {
129 // C1: we only check 3/4/5
130 func
= calculateScriptId(i
- 3);
132 if (hotspotfunctions
[i
].mask
== 1) continue; // creature only
133 func
= calculateScriptId(hotspotfunctions
[i
].message
);
136 int j
= hotspotfunctions
[i
].hotspot
;
138 if (hotspots
[j
].left
== -1) continue;
139 // TODO: check other items for being -1?
141 if ((clickx
>= hotspots
[j
].left
&& clickx
<= hotspots
[j
].right
) &&
142 (clicky
>= hotspots
[j
].top
&& clicky
<= hotspots
[j
].bottom
)) {
143 queueScript(func
, (Agent
*)world
.hand());
149 void CompoundAgent::setHotspotLoc(unsigned int id
, int l
, int t
, int r
, int b
) {
152 hotspots
[id
].left
= l
;
153 hotspots
[id
].top
= t
;
154 hotspots
[id
].right
= r
;
155 hotspots
[id
].bottom
= b
;
158 void CompoundAgent::setHotspotFunc(unsigned int id
, unsigned int f
) {
161 hotspotfunctions
[id
].hotspot
= f
;
163 // TODO: this tries to make c2 work nicely, necessary?
164 hotspotfunctions
[id
].mask
= 3;
166 hotspotfunctions
[id
].message
= calculateScriptId(id
);
168 hotspotfunctions
[id
].message
= calculateScriptId(id
- 3);
171 void CompoundAgent::setHotspotFuncDetails(unsigned int id
, uint16 m
, uint8 f
) {
174 hotspotfunctions
[id
].message
= m
;
175 hotspotfunctions
[id
].mask
= f
;