cyphesis/rulesets/Stackable.cpp
Al Riddoch 8915b80e5d 2002-12-23 Al Riddoch <alriddoch@zepler.org>
* common/BaseEntity.h, common/BaseWorld.cpp, common/BaseWorld.h,
	  common/OOGThing.h, rulesets/Area.cpp, rulesets/Area.h,
	  rulesets/BaseMind.cpp, rulesets/Character.cpp,
	  rulesets/Character.h, rulesets/Creator.cpp, rulesets/Creator.h,
	  rulesets/Entity.cpp, rulesets/Entity.h, rulesets/Food.cpp,
	  rulesets/Food.h, rulesets/Line.cpp, rulesets/Line.h,
	  rulesets/MemMap.cpp, rulesets/Plant.cpp, rulesets/Plant.h,
	  rulesets/Stackable.cpp, rulesets/Stackable.h,
	  rulesets/Structure.h, rulesets/Thing.cpp, rulesets/Thing.h,
	  rulesets/World.cpp, rulesets/World.h, server/Account.cpp,
	  server/CommClient.cpp, server/CommClient.h,
	  server/Connection.cpp, server/Connection.h,
	  server/EntityFactory.cpp, server/Lobby.cpp, server/Lobby.h,
	  server/PersistantThingFactory.h,
	  server/PersistantThingFactory_impl.h,
	  server/Restorer.cpp, server/Restorer_impl.h, server/ServerRouting.cpp,
	  server/WorldRouter.cpp: Assign ID at entity construction time,
	  and make it constant, and thus unmodifiable.
2002-12-23 23:22:25 +00:00

108 lines
3.1 KiB
C++

// This file may be redistributed and modified only under the terms of
// the GNU General Public License (See COPYING for details).
// Copyright (C) 2000,2001 Alistair Riddoch
// A stackable object, ie one which can represent multiple object of the
// same type. Used for things like coins.
#include "Stackable.h"
#include "Script.h"
#include <Atlas/Objects/Operation/Combine.h>
#include <Atlas/Objects/Operation/Divide.h>
#include <Atlas/Objects/Operation/Delete.h>
Stackable::Stackable(const std::string & id) : Thing(id), num(1)
{
subscribe("combine", OP_COMBINE);
subscribe("divide", OP_DIVIDE);
}
Stackable::~Stackable()
{
}
const Fragment Stackable::get(const std::string & aname) const
{
if (aname == "num") {
return Fragment(num);
}
return Thing::get(aname);
}
void Stackable::set(const std::string & aname, const Fragment & attr)
{
if ((aname == "num") && attr.IsInt()) {
num = attr.AsInt();
} else {
Thing::set(aname, attr);
}
}
void Stackable::addToObject(Fragment::MapType & omap) const
{
if (num != 1) {
omap["num"] = Fragment(num);
}
Entity::addToObject(omap);
}
OpVector Stackable::CombineOperation(const Combine & op)
{
OpVector res;
if (script->Operation("combine", op, res) != 0) {
return res;
}
const Fragment::ListType & args = op.GetArgs();
for(Fragment::ListType::const_iterator I = args.begin(); I!= args.end(); I++) {
const std::string & id = I->AsMap().find("id")->second.AsString();
if (id == getId()) { continue; }
Entity * ent = world->getObject(id);
if (ent == NULL) { continue; }
Stackable * obj = dynamic_cast<Stackable *>(ent);
if (obj == NULL) { continue; }
if (obj->type != type) { continue; }
num = num + obj->num;
Delete * d = new Delete(Delete::Instantiate());
Fragment::MapType dent;
dent["id"] = id;
d->SetTo(id);
d->SetArgs(Fragment::ListType(1,dent));
res.push_back(d);
}
return res;
// Currently does not send sight ops, as the Sight ops for this type of
// thing have not been discussed
}
OpVector Stackable::DivideOperation(const Divide & op)
{
OpVector res;
if (script->Operation("divide", op, res) != 0) {
return res;
}
const Fragment::ListType & args = op.GetArgs();
for(Fragment::ListType::const_iterator I = args.begin(); I!=args.end(); I++) {
const Fragment::MapType & ent = I->AsMap();
int new_num = 1;
Fragment::MapType::const_iterator J = ent.find("num");
if (J != ent.end()) {
if (J->second.IsInt()) { new_num = J->second.AsInt(); }
}
if (num <= new_num) { continue; }
Fragment::MapType new_ent;
Fragment::ListType parents(1,type);
new_ent["parents"] = parents;
new_ent["num"] = new_num;
Create * c = new Create( Create::Instantiate());
c->SetArgs(Fragment::ListType(1,new_ent));
c->SetTo(getId());
res.push_back(c);
}
return res;
// Currently does not send sight ops, as the Sight ops for this type of
// thing have not been discussed
}