From 43a28f04fa3ddf4b612f58c25a896293a01567e3 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 15 Oct 2011 02:28:57 +0300 Subject: mobv2 --- src/content_sao.cpp | 513 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 495 insertions(+), 18 deletions(-) (limited to 'src/content_sao.cpp') diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 0bb518c16..8c9761740 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -20,9 +20,29 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_sao.h" #include "collision.h" #include "environment.h" +#include "settings.h" core::map ServerActiveObject::m_types; +/* Some helper functions */ + +// Y is copied, X and Z change is limited +void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase) +{ + v3f d_wanted = target_speed - speed; + d_wanted.Y = 0; + f32 dl_wanted = d_wanted.getLength(); + f32 dl = dl_wanted; + if(dl > max_increase) + dl = max_increase; + + v3f d = d_wanted.normalize() * dl; + + speed.X += d.X; + speed.Z += d.Z; + speed.Y = target_speed.Y; +} + /* TestSAO */ @@ -422,23 +442,6 @@ InventoryItem* RatSAO::createPickedUpItem() Oerkki1SAO */ -// Y is copied, X and Z change is limited -void accelerate_xz(v3f &speed, v3f target_speed, f32 max_increase) -{ - v3f d_wanted = target_speed - speed; - d_wanted.Y = 0; - f32 dl_wanted = d_wanted.getLength(); - f32 dl = dl_wanted; - if(dl > max_increase) - dl = max_increase; - - v3f d = d_wanted.normalize() * dl; - - speed.X += d.X; - speed.Z += d.Z; - speed.Y = target_speed.Y; -} - // Prototype Oerkki1SAO proto_Oerkki1SAO(NULL, 0, v3f(0,0,0)); @@ -617,7 +620,7 @@ void Oerkki1SAO::step(float dtime, bool send_recommended) m_touching_ground = moveresult.touching_ground; // Do collision damage - float tolerance = BS*12; + float tolerance = BS*30; float factor = BS*0.5; v3f speed_diff = old_speed - m_speed_f; // Increase effect in X and Z @@ -886,3 +889,477 @@ InventoryItem* FireflySAO::createPickedUpItem() InventoryItem *item = InventoryItem::deSerialize(is); return item; } + +/* + MobV2SAO +*/ + +// Prototype +MobV2SAO proto_MobV2SAO(NULL, 0, v3f(0,0,0), NULL); + +MobV2SAO::MobV2SAO(ServerEnvironment *env, u16 id, v3f pos, + Settings *init_properties): + ServerActiveObject(env, id, pos), + m_move_type("ground_nodes"), + m_speed(0,0,0), + m_last_sent_position(0,0,0), + m_oldpos(0,0,0), + m_yaw(0), + m_counter1(0), + m_counter2(0), + m_age(0), + m_touching_ground(false), + m_hp(10), + m_walk_around(false), + m_walk_around_timer(0), + m_next_pos_exists(false), + m_shoot_reload_timer(0), + m_shooting(false), + m_shooting_timer(0), + m_falling(false) +{ + ServerActiveObject::registerType(getType(), create); + + m_properties = new Settings(); + if(init_properties) + m_properties->update(*init_properties); + + m_properties->setV3F("pos", pos); + + setPropertyDefaults(); + readProperties(); +} + +MobV2SAO::~MobV2SAO() +{ + delete m_properties; +} + +ServerActiveObject* MobV2SAO::create(ServerEnvironment *env, u16 id, v3f pos, + const std::string &data) +{ + std::istringstream is(data, std::ios::binary); + Settings properties; + properties.parseConfigLines(is, "MobArgsEnd"); + MobV2SAO *o = new MobV2SAO(env, id, pos, &properties); + return o; +} + +std::string MobV2SAO::getStaticData() +{ + updateProperties(); + + std::ostringstream os(std::ios::binary); + m_properties->writeLines(os); + return os.str(); +} + +std::string MobV2SAO::getClientInitializationData() +{ + //dstream<<__FUNCTION_NAME<getNodeNoEx(p); + if(n.getContent() != CONTENT_AIR) + return false; + } + return true; +} + +bool checkWalkablePosition(Map *map, v3s16 p0) +{ + v3s16 p = p0 + v3s16(0,-1,0); + MapNode n = map->getNodeNoEx(p); + if(n.getContent() != CONTENT_AIR) + return true; + return false; +} + +bool checkFreeAndWalkablePosition(Map *map, v3s16 p0, v3s16 size) +{ + if(!checkFreePosition(map, p0, size)) + return false; + if(!checkWalkablePosition(map, p0)) + return false; + return true; +} + +static void get_random_u32_array(u32 a[], u32 len) +{ + u32 i, n; + for(i=0; i 1){ + u32 k = myrand() % n; + n--; + u32 temp = a[n]; + a[n] = a[k]; + a[k] = temp; + } +} + +#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" + +static void explodeSquare(Map *map, v3s16 p0, v3s16 size) +{ + core::map modified_blocks; + + for(int dx=0; dxgetNodeNoEx(p); + if(n.getContent() == CONTENT_IGNORE) + continue; + //map->removeNodeWithEvent(p); + map->removeNodeAndUpdate(p, modified_blocks); + } + + // Send a MEET_OTHER event + MapEditEvent event; + event.type = MEET_OTHER; + for(core::map::Iterator + i = modified_blocks.getIterator(); + i.atEnd() == false; i++) + { + v3s16 p = i.getNode()->getKey(); + event.modified_blocks.insert(p, true); + } + map->dispatchEvent(&event); +} + +void MobV2SAO::step(float dtime, bool send_recommended) +{ + assert(m_env); + Map *map = &m_env->getMap(); + + m_age += dtime; + + if(m_die_age >= 0.0 && m_age >= m_die_age){ + m_removed = true; + return; + } + + if(!m_falling) + { + m_shooting_timer -= dtime; + if(m_shooting_timer <= 0.0 && m_shooting){ + m_shooting = false; + + std::string shoot_type = m_properties->get("shoot_type"); + v3f shoot_pos(0,0,0); + shoot_pos.Y += m_properties->getFloat("shoot_y") * BS; + if(shoot_type == "fireball"){ + v3f dir(cos(m_yaw/180*PI),0,sin(m_yaw/180*PI)); + v3f speed = dir * BS * 10.0; + v3f pos = m_base_position + shoot_pos; + dstream<<__FUNCTION_NAME<<": Shooting fireball from "<addActiveObjectAsStatic(obj); + m_env->addActiveObject(obj); + } else { + dstream<<__FUNCTION_NAME<<": Unknown shoot_type="<= 5.0 && !m_next_pos_exists) + { + m_shoot_reload_timer = 0.0; + m_shooting = true; + m_shooting_timer = 1.5; + { + std::ostringstream os(std::ios::binary); + // command (2 = shooting) + writeU8(os, 2); + // time + writeF1000(os, m_shooting_timer + 0.1); + // bright? + writeU8(os, true); + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + m_messages_out.push_back(aom); + } + } + } + + if(m_move_type == "ground_nodes") + { + if(!m_shooting){ + m_walk_around_timer -= dtime; + if(m_walk_around_timer <= 0.0){ + m_walk_around = !m_walk_around; + if(m_walk_around) + m_walk_around_timer = 0.1*myrand_range(10,50); + else + m_walk_around_timer = 0.1*myrand_range(30,70); + } + } + + /* Move */ + if(m_next_pos_exists){ + v3f pos_f = m_base_position; + v3f next_pos_f = intToFloat(m_next_pos_i, BS); + + v3f v = next_pos_f - pos_f; + m_yaw = atan2(v.Z, v.X) / M_PI * 180; + + v3f diff = next_pos_f - pos_f; + v3f dir = diff; + dir.normalize(); + float speed = BS * 0.5; + if(m_falling) + speed = BS * 3.0; + dir *= dtime * speed; + bool arrived = false; + if(dir.getLength() > diff.getLength()){ + dir = diff; + arrived = true; + } + pos_f += dir; + m_base_position = pos_f; + + if((pos_f - next_pos_f).getLength() < 0.1 || arrived){ + //dstream<<"id="<= 2.5){ + pos_size_off.X = -1; + pos_size_off.Y = -1; + } + + if(!m_next_pos_exists){ + /* Check whether to drop down */ + if(checkFreePosition(map, + pos_i + pos_size_off + v3s16(0,-1,0), size_blocks)){ + m_next_pos_i = pos_i + v3s16(0,-1,0); + m_next_pos_exists = true; + m_falling = true; + } else { + m_falling = false; + } + } + + if(m_walk_around) + { + if(!m_next_pos_exists){ + /* Find some position where to go next */ + v3s16 dps[3*3*3]; + int num_dps = 0; + for(int dx=-1; dx<=1; dx++) + for(int dy=-1; dy<=1; dy++) + for(int dz=-1; dz<=1; dz++){ + if(dx == 0 && dy == 0) + continue; + if(dx != 0 && dz != 0 && dy != 0) + continue; + dps[num_dps++] = v3s16(dx,dy,dz); + } + u32 order[3*3*3]; + get_random_u32_array(order, num_dps); + /*dstream<<"At pos "<= 2.5){ + pos_size_off.X = -1; + pos_size_off.Y = -1; + } + bool free = checkFreePosition(map, pos_i + pos_size_off, size_blocks); + if(!free){ + explodeSquare(map, pos_i, v3s16(3,3,3)); + m_removed = true; + return; + } + } + else + { + dstream<<"MobV2SAO::step(): id="< 0.05*BS) + { + m_last_sent_position = m_base_position; + + std::ostringstream os(std::ios::binary); + // command (0 = update position) + writeU8(os, 0); + // pos + writeV3F1000(os, m_base_position); + // yaw + writeF1000(os, m_yaw); + // create message and add to list + ActiveObjectMessage aom(getId(), false, os.str()); + m_messages_out.push_back(aom); + } +} + +u16 MobV2SAO::punch(const std::string &toolname, v3f dir) +{ + u16 amount = 2; + dstream<<"id="<setDefault("move_type", "ground_nodes"); + m_properties->setDefault("speed", "(0,0,0)"); + m_properties->setDefault("age", "0"); + m_properties->setDefault("yaw", "0"); + m_properties->setDefault("pos", "(0,0,0)"); + m_properties->setDefault("hp", "0"); + m_properties->setDefault("die_age", "-1"); + m_properties->setDefault("size", "(1,2)"); + m_properties->setDefault("shoot_type", "fireball"); + m_properties->setDefault("shoot_y", "0"); +} +void MobV2SAO::readProperties() +{ + m_move_type = m_properties->get("move_type"); + m_speed = m_properties->getV3F("speed"); + m_age = m_properties->getFloat("age"); + m_yaw = m_properties->getFloat("yaw"); + m_base_position = m_properties->getV3F("pos"); + m_hp = m_properties->getS32("hp"); + m_die_age = m_properties->getFloat("die_age"); + m_size = m_properties->getV2F("size"); +} +void MobV2SAO::updateProperties() +{ + m_properties->set("move_type", m_move_type); + m_properties->setV3F("speed", m_speed); + m_properties->setFloat("age", m_age); + m_properties->setFloat("yaw", m_yaw); + m_properties->setV3F("pos", m_base_position); + m_properties->setS32("hp", m_hp); + m_properties->setFloat("die_age", m_die_age); + m_properties->setV2F("size", m_size); + + m_properties->setS32("version", 0); +} + +void MobV2SAO::doDamage(u16 d) +{ + dstream<<"MobV2 hp="<