allow objects to damage other objects
This commit is contained in:
parent
f592e2620e
commit
675e9f3aa3
|
@ -73,5 +73,22 @@ protected:
|
|||
u16 m_id; // 0 is invalid, "no id"
|
||||
};
|
||||
|
||||
struct DistanceSortedActiveObject
|
||||
{
|
||||
ActiveObject *obj;
|
||||
f32 d;
|
||||
|
||||
DistanceSortedActiveObject(ActiveObject *a_obj, f32 a_d)
|
||||
{
|
||||
obj = a_obj;
|
||||
d = a_d;
|
||||
}
|
||||
|
||||
bool operator < (DistanceSortedActiveObject &other)
|
||||
{
|
||||
return d < other.d;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2131,7 +2131,7 @@ ClientActiveObject * Client::getSelectedActiveObject(
|
|||
objects.sort();
|
||||
|
||||
for (u32 i=0; i<objects.size(); i++) {
|
||||
ClientActiveObject *obj = objects[i].obj;
|
||||
ClientActiveObject *obj = (ClientActiveObject*)objects[i].obj;
|
||||
|
||||
core::aabbox3d<f32> *selection_box = obj->getSelectionBox();
|
||||
if (selection_box == NULL)
|
||||
|
|
|
@ -94,22 +94,5 @@ private:
|
|||
static core::map<u16, Factory> m_types;
|
||||
};
|
||||
|
||||
struct DistanceSortedActiveObject
|
||||
{
|
||||
ClientActiveObject *obj;
|
||||
f32 d;
|
||||
|
||||
DistanceSortedActiveObject(ClientActiveObject *a_obj, f32 a_d)
|
||||
{
|
||||
obj = a_obj;
|
||||
d = a_d;
|
||||
}
|
||||
|
||||
bool operator < (DistanceSortedActiveObject &other)
|
||||
{
|
||||
return d < other.d;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -105,6 +105,8 @@ bool content_mob_spawn(ServerEnvironment *env, v3s16 pos, u32 active_object_coun
|
|||
if (active_object_count > 20)
|
||||
return false;
|
||||
int rand = myrand();
|
||||
if (pos.Y < 0 && rand%2 == 0)
|
||||
return false;
|
||||
assert(env);
|
||||
Map *map = &env->getMap();
|
||||
|
||||
|
@ -321,7 +323,7 @@ void content_mob_init()
|
|||
f->spawn_on = CONTENT_WILDGRASS_SHORT;
|
||||
f->spawn_in = CONTENT_AIR;
|
||||
f->spawn_min_height = -5;
|
||||
f->spawn_max_height = 30;
|
||||
f->spawn_max_height = 40;
|
||||
f->spawn_min_light = LIGHT_MAX/2;
|
||||
f->spawn_max_nearby_mobs = 3;
|
||||
f->lifetime = 900.0;
|
||||
|
@ -349,7 +351,7 @@ void content_mob_init()
|
|||
f->spawn_on = CONTENT_WILDGRASS_SHORT;
|
||||
f->spawn_in = CONTENT_AIR;
|
||||
f->spawn_min_height = -5;
|
||||
f->spawn_max_height = 30;
|
||||
f->spawn_max_height = 40;
|
||||
f->spawn_min_light = LIGHT_MAX/2;
|
||||
f->spawn_max_nearby_mobs = 3;
|
||||
f->spawn_chance = 2;
|
||||
|
@ -454,7 +456,7 @@ void content_mob_init()
|
|||
f->spawn_on = CONTENT_WILDGRASS_LONG;
|
||||
f->spawn_in = CONTENT_AIR;
|
||||
f->spawn_min_height = 0;
|
||||
f->spawn_max_height = 30;
|
||||
f->spawn_max_height = 40;
|
||||
f->spawn_max_light = LIGHT_MAX/2;
|
||||
f->spawn_max_nearby_mobs = 3;
|
||||
f->notices_player = true;
|
||||
|
@ -481,6 +483,8 @@ void content_mob_init()
|
|||
f->motion = MM_SEEKER;
|
||||
f->motion_type = MMT_WALK;
|
||||
f->notices_player = true;
|
||||
f->attack_mob_damage = 5;
|
||||
f->attack_mob_range = v3f(1,1,1);
|
||||
f->lifetime = 900.0;
|
||||
f->setCollisionBox(aabb3f(-0.5*BS, 0., -0.5*BS, 0.5*BS, 1.*BS, 0.5*BS));
|
||||
|
||||
|
@ -508,7 +512,7 @@ void content_mob_init()
|
|||
f->spawn_on = CONTENT_WILDGRASS_SHORT;
|
||||
f->spawn_in = CONTENT_AIR;
|
||||
f->spawn_min_height = 2;
|
||||
f->spawn_max_height = 20;
|
||||
f->spawn_max_height = 50;
|
||||
f->spawn_min_light = LIGHT_MAX/2;
|
||||
f->spawn_max_nearby_mobs = 3;
|
||||
f->lifetime = 900.0;
|
||||
|
@ -526,6 +530,8 @@ void content_mob_init()
|
|||
f->notices_player = true;
|
||||
f->attack_player_damage = 1;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->attack_mob_damage = 5;
|
||||
f->attack_mob_range = v3f(1,1,1);
|
||||
f->lifetime = 10.0;
|
||||
f->contact_place_node = CONTENT_SNOW;
|
||||
f->contact_drop_item = CONTENT_CRAFTITEM_SNOW_BALL;
|
||||
|
@ -544,6 +550,8 @@ void content_mob_init()
|
|||
f->notices_player = true;
|
||||
f->attack_player_damage = 1;
|
||||
f->attack_player_range = v3f(1,1,1);
|
||||
f->attack_mob_damage = 20;
|
||||
f->attack_mob_range = v3f(1,1,1);
|
||||
f->lifetime = 20.0;
|
||||
f->contact_drop_item = CONTENT_CRAFTITEM_ARROW;
|
||||
f->setCollisionBox(aabb3f(-BS/3.,0.0,-BS/3., BS/3.,BS/2.,BS/3.));
|
||||
|
|
|
@ -118,6 +118,8 @@ struct MobFeatures {
|
|||
v3f attack_throw_offset;
|
||||
u8 attack_player_damage;
|
||||
v3f attack_player_range;
|
||||
u8 attack_mob_damage;
|
||||
v3f attack_mob_range;
|
||||
u8 glow_light;
|
||||
u8 attack_glow_light;
|
||||
u16 hp;
|
||||
|
@ -242,6 +244,8 @@ struct MobFeatures {
|
|||
attack_throw_offset = v3f(0,0,0);
|
||||
attack_player_damage = 0;
|
||||
attack_player_range = v3f(0,0,0);
|
||||
attack_mob_damage = 0;
|
||||
attack_mob_range = v3f(0,0,0);
|
||||
glow_light = 0;
|
||||
attack_glow_light = 0;
|
||||
hp = 20;
|
||||
|
|
|
@ -450,7 +450,7 @@ void MobSAO::step(float dtime, bool send_recommended)
|
|||
v3f playerpos = player->getPosition();
|
||||
f32 dist = m_base_position.getDistanceFrom(playerpos);
|
||||
if (dist < BS*16) {
|
||||
if (dist < BS*3 || myrand_range(0,3) == 0) {
|
||||
if (dist < BS*8 || myrand_range(0,2) == 0) {
|
||||
actionstream<<"Mob id="<<m_id<<" at "
|
||||
<<PP(m_base_position/BS)
|
||||
<<" got randomly disturbed by "
|
||||
|
@ -536,6 +536,32 @@ void MobSAO::step(float dtime, bool send_recommended)
|
|||
}
|
||||
}
|
||||
|
||||
if (m.attack_mob_damage > 0) {
|
||||
core::array<DistanceSortedActiveObject> objects;
|
||||
f32 range = m.attack_mob_range.X;
|
||||
if (m.attack_mob_range.Y > range)
|
||||
range = m.attack_mob_range.Y;
|
||||
if (m.attack_mob_range.Z > range)
|
||||
range = m.attack_mob_range.Z;
|
||||
|
||||
m_env->getActiveObjects(m_base_position, range*BS, objects);
|
||||
|
||||
// Sort them.
|
||||
// After this, the closest object is the first in the array.
|
||||
objects.sort();
|
||||
|
||||
for (u32 i=0; i<objects.size(); i++) {
|
||||
ServerActiveObject *obj = (ServerActiveObject*)objects[i].obj;
|
||||
if (obj->getId() == m_id)
|
||||
continue;
|
||||
if (obj->getType() == ACTIVEOBJECT_TYPE_MOB) {
|
||||
((MobSAO*)obj)->doDamage(m.attack_mob_damage);
|
||||
}else if (obj->getType() == ACTIVEOBJECT_TYPE_ITEM) {
|
||||
((ItemSAO*)obj)->m_removed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MobMotion mot = getMotion();
|
||||
|
||||
if (mot != MM_CONSTANT && mot != MM_STATIC) {
|
||||
|
@ -1188,6 +1214,11 @@ void MobSAO::explodeSquare(v3s16 p0, v3s16 size)
|
|||
Map *map = &m_env->getMap();
|
||||
core::map<v3s16, MapBlock*> modified_blocks;
|
||||
|
||||
if (content_mob_features(m_content).level != MOB_DESTRUCTIVE) {
|
||||
if (m_env->searchNear(p0,size+v3s16(5,5,5),CONTENT_BORDERSTONE,NULL))
|
||||
return;
|
||||
}
|
||||
|
||||
for (int dx=0; dx<size.X; dx++)
|
||||
for (int dy=0; dy<size.Y; dy++)
|
||||
for (int dz=0; dz<size.Z; dz++) {
|
||||
|
|
|
@ -72,9 +72,9 @@ public:
|
|||
u16 punch(content_t punch_item, v3f dir, const std::string &playername);
|
||||
bool rightClick(Player *player);
|
||||
u8 level();
|
||||
void doDamage(u16 d);
|
||||
private:
|
||||
void sendPosition();
|
||||
void doDamage(u16 d);
|
||||
|
||||
MobMotion getMotion()
|
||||
{
|
||||
|
|
|
@ -2824,6 +2824,22 @@ ServerActiveObject* ServerEnvironment::getActiveObject(u16 id)
|
|||
return i->second;
|
||||
}
|
||||
|
||||
void ServerEnvironment::getActiveObjects(v3f origin, f32 max_d, core::array<DistanceSortedActiveObject> &dest)
|
||||
{
|
||||
for (std::map<u16, ServerActiveObject*>::iterator i = m_active_objects.begin(); i != m_active_objects.end(); i++) {
|
||||
ServerActiveObject* obj = i->second;
|
||||
|
||||
f32 d = (obj->getBasePosition() - origin).getLength();
|
||||
|
||||
if (d > max_d)
|
||||
continue;
|
||||
|
||||
DistanceSortedActiveObject dso(obj, d);
|
||||
|
||||
dest.push_back(dso);
|
||||
}
|
||||
}
|
||||
|
||||
bool ServerEnvironment::propogateEnergy(u8 level, v3s16 powersrc, v3s16 signalsrc, v3s16 pos)
|
||||
{
|
||||
MapNode n = m_map->getNodeNoEx(pos);
|
||||
|
|
|
@ -177,6 +177,9 @@ public:
|
|||
|
||||
ServerActiveObject* getActiveObject(u16 id);
|
||||
|
||||
// Get all nearby objects
|
||||
void getActiveObjects(v3f origin, f32 max_d, core::array<DistanceSortedActiveObject> &dest);
|
||||
|
||||
/*
|
||||
Add an active object to the environment.
|
||||
Environment handles deletion of object.
|
||||
|
|
|
@ -312,7 +312,7 @@ void cmd_clearobjects(std::wostringstream &os,
|
|||
|
||||
{
|
||||
std::wstring msg;
|
||||
msg += L"Clearing all objects. This may take long.";
|
||||
msg += L"Clearing all objects. This may take a long time.";
|
||||
msg += L" You may experience a timeout. (by ";
|
||||
msg += narrow_to_wide(ctx->player->getName());
|
||||
msg += L")";
|
||||
|
|
Loading…
Reference in New Issue