234 |
|
|
235 |
namespace |
namespace |
236 |
{ |
{ |
|
ForceList forces; |
|
237 |
MouseForce *mouseforce; |
MouseForce *mouseforce; |
238 |
|
|
|
ActorList actorlist; // list of movable, dynamic objects |
|
|
|
|
239 |
class Level { |
class Level { |
240 |
public: |
public: |
241 |
Level(int ww, int hh) : fields(ww,hh) { |
Level(int ww, int hh) : fields(ww,hh) { |
242 |
w = ww; |
w = ww; |
243 |
h = hh; |
h = hh; |
244 |
} |
} |
245 |
|
~Level() { |
246 |
|
fields = FieldArray(0,0); |
247 |
|
for_each(actorlist.begin(), actorlist.end(), mem_fun(&Actor::dispose)); |
248 |
|
} |
249 |
|
|
250 |
bool contains (GridPos p) { |
bool contains (GridPos p) { |
251 |
return (p.x>=0 && p.y>=0 && p.x<w && p.y<h); |
return (p.x>=0 && p.y>=0 && p.x<w && p.y<h); |
260 |
|
|
261 |
|
|
262 |
// Variables. |
// Variables. |
263 |
FieldArray fields; // Contains floors, items, etc. |
FieldArray fields; // Contains floors, items, etc. |
264 |
int w, h; // Width and height of the level |
int w, h; // Width and height of the level |
265 |
|
ForceList forces; |
266 |
|
ActorList actorlist; // List of movable, dynamic objects |
267 |
}; |
}; |
268 |
|
|
269 |
Level *level; |
Level *level; |
319 |
} |
} |
320 |
|
|
321 |
// all other force fields |
// all other force fields |
322 |
for (ForceList::iterator i=forces.begin(); i != forces.end(); ++i) |
for (ForceList::iterator i=level->forces.begin(); |
323 |
|
i != level->forces.end(); ++i) |
324 |
|
{ |
325 |
f += (*i)->get_force(a, x, v, time); |
f += (*i)->get_force(a, x, v, time); |
326 |
|
} |
327 |
|
|
328 |
ActorInfo *ai = a->get_actorinfo(); |
ActorInfo *ai = a->get_actorinfo(); |
329 |
f += ai->forceacc2; |
f += ai->forceacc2; |
500 |
|
|
501 |
|
|
502 |
/* |
/* |
503 |
This function is called for every contact between an actor and a |
This function is called for every contact between an actor and a |
504 |
stone. It is here that the stones are informed about that event. Note |
stone. It is here that the stones are informed about contacts. |
505 |
that a stone may kill itself during a call to actor_hit() or |
Note that a stone may kill itself during a call to actor_hit() or |
506 |
actor_contact() so we must not refer to it after having called these |
actor_contact() so we must not refer to it after having called |
507 |
functions. (Incidentally, this is why StoneContact only contains a |
these functions. (Incidentally, this is why StoneContact only |
508 |
'stonepos' and no 'stone' entry. |
contains a 'stonepos' and no 'stone' entry.) |
509 |
*/ |
*/ |
510 |
static V3 |
static V3 |
511 |
handle_stone_contact(V3 normal, StoneContact &sc) |
handle_stone_contact(V3 normal, StoneContact &sc) |
522 |
|
|
523 |
if (length(ai->vel) > 0.1) { |
if (length(ai->vel) > 0.1) { |
524 |
AddSprite(display::SPRITE_EFFECT, sc.contact_point, "ring-anim"); |
AddSprite(display::SPRITE_EFFECT, sc.contact_point, "ring-anim"); |
525 |
sound::PlaySound(sc.sound.c_str()); |
sound::PlaySound(sc.sound.c_str(), px::V2(sc.contact_point[0], |
526 |
|
sc.contact_point[1])); |
527 |
} |
} |
528 |
} |
} |
529 |
} |
} |
556 |
ai.vel = reflect(ai.vel, normal); |
ai.vel = reflect(ai.vel, normal); |
557 |
|
|
558 |
// Contacts with other actors |
// Contacts with other actors |
559 |
unsigned s=actorlist.size(); |
unsigned s=level->actorlist.size(); |
560 |
unsigned i; |
unsigned i; |
561 |
for (i=0; i<s && actorlist[i] != a; ++i) |
for (i=0; i<s && level->actorlist[i] != a; ++i) |
562 |
; |
; |
563 |
for (unsigned j=i+1; j<s; ++j) |
for (unsigned j=i+1; j<s; ++j) |
564 |
{ |
{ |
565 |
ActorInfo &v = *actorlist[i]->get_actorinfo(); |
ActorInfo &v = *level->actorlist[i]->get_actorinfo(); |
566 |
ActorInfo &w = *actorlist[j]->get_actorinfo(); |
ActorInfo &w = *level->actorlist[j]->get_actorinfo(); |
567 |
|
|
568 |
V3 p1 = v.pos; |
V3 p1 = v.pos; |
569 |
V3 p2 = w.pos; |
V3 p2 = w.pos; |
648 |
level = 0; |
level = 0; |
649 |
delete mouseforce; |
delete mouseforce; |
650 |
mouseforce=0; |
mouseforce=0; |
|
px::delete_sequence(forces.begin(), forces.end()); |
|
|
forces.clear(); |
|
|
|
|
|
for_each(actorlist.begin(), actorlist.end(), mem_fun(&Actor::dispose)); |
|
|
actorlist.clear(); |
|
651 |
} |
} |
652 |
|
|
653 |
void |
void |
682 |
laser::RecalcLight(); |
laser::RecalcLight(); |
683 |
laser::RecalcLightNow(); // recalculate laser beams if necessary |
laser::RecalcLightNow(); // recalculate laser beams if necessary |
684 |
|
|
685 |
for (ActorList::iterator i=actorlist.begin(); |
for (ActorList::iterator i=level->actorlist.begin(); |
686 |
i!=actorlist.end(); ++i) |
i!=level->actorlist.end(); ++i) |
687 |
{ |
{ |
688 |
int iplayer=-1; |
int iplayer=-1; |
689 |
Actor *a=*i; |
Actor *a=*i; |
730 |
void |
void |
731 |
world::AddForceField(ForceField *ff) |
world::AddForceField(ForceField *ff) |
732 |
{ |
{ |
733 |
forces.push_back(ff); |
level->forces.push_back(ff); |
734 |
} |
} |
735 |
|
|
736 |
void |
void |
737 |
world::RemoveForceField(ForceField *ff) |
world::RemoveForceField(ForceField *ff) |
738 |
{ |
{ |
739 |
ForceList::iterator i=find(forces.begin(), forces.end(), ff); |
ForceList::iterator i=find(level->forces.begin(), level->forces.end(), ff); |
740 |
if (i != forces.end()) |
if (i != level->forces.end()) |
741 |
forces.erase(i); |
level->forces.erase(i); |
742 |
} |
} |
743 |
|
|
744 |
//---------------------------------------- |
//---------------------------------------- |
886 |
Stone *st = GetStone(p); |
Stone *st = GetStone(p); |
887 |
if (st && st->is_movable()) |
if (st && st->is_movable()) |
888 |
{ |
{ |
889 |
sound::PlaySound("st-move"); |
st->play_sound ("st-move"); |
890 |
SetStone(newp, YieldStone(p)); |
SetStone(newp, YieldStone(p)); |
891 |
st->on_move(); |
st->on_move(); |
892 |
return true; |
return true; |
900 |
{ |
{ |
901 |
Stone *tmp = st_layer.yield(newp); |
Stone *tmp = st_layer.yield(newp); |
902 |
if (0 != strcmp(tmp->get_kind(), "borderstone")) { |
if (0 != strcmp(tmp->get_kind(), "borderstone")) { |
903 |
sound::PlaySound("st-move"); |
tmp->play_sound ("st-move"); |
904 |
SetStone(newp, st_layer.yield(p)); |
SetStone(newp, st_layer.yield(p)); |
905 |
SetStone(p, tmp); |
SetStone(p, tmp); |
906 |
} |
} |
936 |
world::AddActor(double x, double y, Actor* a) |
world::AddActor(double x, double y, Actor* a) |
937 |
{ |
{ |
938 |
V3 pos(x,y,0); |
V3 pos(x,y,0); |
939 |
actorlist.push_back(a); |
level->actorlist.push_back(a); |
940 |
a->get_actorinfo()->pos = pos; |
a->get_actorinfo()->pos = pos; |
941 |
a->on_creation(pos); |
a->on_creation(pos); |
942 |
ReleaseActor(a); |
ReleaseActor(a); |
945 |
Actor * |
Actor * |
946 |
world::YieldActor(Actor *a) |
world::YieldActor(Actor *a) |
947 |
{ |
{ |
948 |
ActorList::iterator i=find(actorlist.begin(), actorlist.end(), a); |
ActorList::iterator i=find(level->actorlist.begin(), level->actorlist.end(), a); |
949 |
if (i!=actorlist.end()) { |
if (i!=level->actorlist.end()) { |
950 |
actorlist.erase(i); |
level->actorlist.erase(i); |
951 |
GrabActor(a); |
GrabActor(a); |
952 |
return a; |
return a; |
953 |
} |
} |
990 |
timeaccu += dtime; |
timeaccu += dtime; |
991 |
|
|
992 |
while (timeaccu >= timestep) { |
while (timeaccu >= timestep) { |
993 |
for (ActorList::iterator i=actorlist.begin(); i!=actorlist.end(); ++i) { |
for (ActorList::iterator i=level->actorlist.begin(); i!=level->actorlist.end(); ++i) { |
994 |
ActorInfo *ai = (*i)->get_actorinfo(); |
ActorInfo *ai = (*i)->get_actorinfo(); |
995 |
if (!ai->grabbed && !(*i)->is_dead()) |
if (!ai->grabbed && !(*i)->is_dead()) |
996 |
{ |
{ |
1006 |
|
|
1007 |
|
|
1008 |
mouseforce->tick(timestep); |
mouseforce->tick(timestep); |
1009 |
for_each(forces.begin(), forces.end(), |
for_each(level->forces.begin(), level->forces.end(), |
1010 |
bind2nd(mem_fun(&ForceField::tick), timestep)); |
bind2nd(mem_fun(&ForceField::tick), timestep)); |
1011 |
|
|
1012 |
g_timer.tick(timestep); |
g_timer.tick(timestep); |