]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/object_properties.cpp
Fix hash implementation for SerializedBlockCache
[dragonfireclient.git] / src / object_properties.cpp
index eb26db8d3f5a01fafc067dbbabc29ef05d706a74..c7f6becf0a887b5029929fcb3bed9c3357a6a2a0 100644 (file)
@@ -1,6 +1,6 @@
 /*
-Minetest-c55
-Copyright (C) 2012 celeron55, Perttu Ahola <celeron55@gmail.com>
+Minetest
+Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
@@ -18,160 +18,223 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 */
 
 #include "object_properties.h"
+#include "irrlichttypes_bloated.h"
+#include "exceptions.h"
 #include "util/serialize.h"
+#include "util/basic_macros.h"
 #include <sstream>
-#include <map>
-
-#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
-#define PP2(x) "("<<(x).X<<","<<(x).Y<<")"
-
-ObjectProperties::ObjectProperties():
-       hp_max(1),
-       physical(false),
-       weight(5),
-       collisionbox(-0.5,-0.5,-0.5, 0.5,0.5,0.5),
-       visual("sprite"),
-       mesh(""),
-       animation_frames(1,1),
-       animation_speed(15),
-       animation_blend(0),
-       visual_size(1,1),
-       spritediv(1,1),
-       initial_sprite_basepos(0,0),
-       is_visible(true),
-       makes_footstep_sound(false),
-       automatic_rotate(0)
+
+static const video::SColor NULL_BGCOLOR{0, 1, 1, 1};
+
+ObjectProperties::ObjectProperties()
 {
-       animation_bone_position[""] = v3f(0,0,0);
-       animation_bone_rotation[""] = v3f(0,0,0);
-       textures.push_back("unknown_object.png");
+       textures.emplace_back("no_texture.png");
+       colors.emplace_back(255,255,255,255);
 }
 
 std::string ObjectProperties::dump()
 {
        std::ostringstream os(std::ios::binary);
-       os<<"hp_max="<<hp_max;
-       os<<", physical="<<physical;
-       os<<", weight="<<weight;
-       os<<", collisionbox="<<PP(collisionbox.MinEdge)<<","<<PP(collisionbox.MaxEdge);
-       os<<", visual="<<visual;
-       os<<", mesh="<<mesh;
-       os<<", animation_frames="<<animation_frames.X<<","<<animation_frames.Y;
-       os<<", animation_speed="<<animation_speed;
-       os<<", animation_blend="<<animation_blend;
-       os<<", visual_size="<<PP2(visual_size);
-
-       os<<", animation_bone_position=[";
-       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_position.begin(); ii != animation_bone_position.end(); ++ii){
-               std::string bone_name = (*ii).first;
-               v3f bone_pos = (*ii).second;
-               os<<bone_name<<" "<<bone_pos.X<<","<<bone_pos.Y<<","<<bone_pos.Z<<"\"";
-       }
-       os<<"]";
-       os<<", animation_bone_rotation=[";
-       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_rotation.begin(); ii != animation_bone_rotation.end(); ++ii){
-               std::string bone_name = (*ii).first;
-               v3f bone_rot = (*ii).second;
-               os<<bone_name<<" "<<bone_rot.X<<","<<bone_rot.Y<<","<<bone_rot.Z<<"\"";
+       os << "hp_max=" << hp_max;
+       os << ", breath_max=" << breath_max;
+       os << ", physical=" << physical;
+       os << ", collideWithObjects=" << collideWithObjects;
+       os << ", collisionbox=" << PP(collisionbox.MinEdge) << "," << PP(collisionbox.MaxEdge);
+       os << ", visual=" << visual;
+       os << ", mesh=" << mesh;
+       os << ", visual_size=" << PP(visual_size);
+       os << ", textures=[";
+       for (const std::string &texture : textures) {
+               os << "\"" << texture << "\" ";
        }
-       os<<"]";
-
-       os<<", textures=[";
-       for(u32 i=0; i<textures.size(); i++){
-               os<<"\""<<textures[i]<<"\" ";
+       os << "]";
+       os << ", colors=[";
+       for (const video::SColor &color : colors) {
+               os << "\"" << color.getAlpha() << "," << color.getRed() << ","
+                       << color.getGreen() << "," << color.getBlue() << "\" ";
        }
-       os<<"]";
-       os<<", spritediv="<<PP2(spritediv);
-       os<<", initial_sprite_basepos="<<PP2(initial_sprite_basepos);
-       os<<", is_visible="<<is_visible;
-       os<<", makes_footstep_sound="<<makes_footstep_sound;
-       os<<", automatic_rotate="<<automatic_rotate;
+       os << "]";
+       os << ", spritediv=" << PP2(spritediv);
+       os << ", initial_sprite_basepos=" << PP2(initial_sprite_basepos);
+       os << ", is_visible=" << is_visible;
+       os << ", makes_footstep_sound=" << makes_footstep_sound;
+       os << ", automatic_rotate="<< automatic_rotate;
+       os << ", backface_culling="<< backface_culling;
+       os << ", glow=" << glow;
+       os << ", nametag=" << nametag;
+       os << ", nametag_color=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed()
+                       << "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" ";
+
+       if (nametag_bgcolor)
+               os << ", nametag_bgcolor=" << "\"" << nametag_color.getAlpha() << "," << nametag_color.getRed()
+                  << "," << nametag_color.getGreen() << "," << nametag_color.getBlue() << "\" ";
+       else
+               os << ", nametag_bgcolor=null ";
+
+       os << ", selectionbox=" << PP(selectionbox.MinEdge) << "," << PP(selectionbox.MaxEdge);
+       os << ", pointable=" << pointable;
+       os << ", static_save=" << static_save;
+       os << ", eye_height=" << eye_height;
+       os << ", zoom_fov=" << zoom_fov;
+       os << ", use_texture_alpha=" << use_texture_alpha;
+       os << ", damage_texture_modifier=" << damage_texture_modifier;
+       os << ", shaded=" << shaded;
+       os << ", show_on_minimap=" << show_on_minimap;
        return os.str();
 }
 
-void ObjectProperties::serialize(std::ostream &os) const
+bool ObjectProperties::validate()
 {
-       writeU8(os, 1); // version
-       writeS16(os, hp_max);
-       writeU8(os, physical);
-       writeF1000(os, weight);
-       writeV3F1000(os, collisionbox.MinEdge);
-       writeV3F1000(os, collisionbox.MaxEdge);
-       os<<serializeString(visual);
-       os<<serializeString(mesh);
-       writeF1000(os, animation_frames.X);
-       writeF1000(os, animation_frames.Y);
-       writeF1000(os, animation_speed);
-       writeF1000(os, animation_blend);
-
-       writeU16(os, animation_bone_position.size());
-       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_position.begin(); ii != animation_bone_position.end(); ++ii){
-               os<<serializeString((*ii).first);
-               writeV3F1000(os, (*ii).second);
+       const char *func = "ObjectProperties::validate(): ";
+       bool ret = true;
+
+       // cf. where serializeString16 is used below
+       for (u32 i = 0; i < textures.size(); i++) {
+               if (textures[i].size() > U16_MAX) {
+                       warningstream << func << "texture " << (i+1) << " has excessive length, "
+                               "clearing it." << std::endl;
+                       textures[i].clear();
+                       ret = false;
+               }
        }
-       writeU16(os, animation_bone_rotation.size());
-       for(std::map<std::string, v3f>::const_iterator ii = animation_bone_rotation.begin(); ii != animation_bone_rotation.end(); ++ii){
-               os<<serializeString((*ii).first);
-               writeV3F1000(os, (*ii).second);
+       if (nametag.length() > U16_MAX) {
+               warningstream << func << "nametag has excessive length, clearing it." << std::endl;
+               nametag.clear();
+               ret = false;
        }
+       if (infotext.length() > U16_MAX) {
+               warningstream << func << "infotext has excessive length, clearing it." << std::endl;
+               infotext.clear();
+               ret = false;
+       }
+       if (wield_item.length() > U16_MAX) {
+               warningstream << func << "wield_item has excessive length, clearing it." << std::endl;
+               wield_item.clear();
+               ret = false;
+       }
+
+       return ret;
+}
 
-       writeV2F1000(os, visual_size);
+void ObjectProperties::serialize(std::ostream &os) const
+{
+       writeU8(os, 4); // PROTOCOL_VERSION >= 37
+       writeU16(os, hp_max);
+       writeU8(os, physical);
+       writeF32(os, 0.f); // Removed property (weight)
+       writeV3F32(os, collisionbox.MinEdge);
+       writeV3F32(os, collisionbox.MaxEdge);
+       writeV3F32(os, selectionbox.MinEdge);
+       writeV3F32(os, selectionbox.MaxEdge);
+       writeU8(os, pointable);
+       os << serializeString16(visual);
+       writeV3F32(os, visual_size);
        writeU16(os, textures.size());
-       for(u32 i=0; i<textures.size(); i++){
-               os<<serializeString(textures[i]);
+       for (const std::string &texture : textures) {
+               os << serializeString16(texture);
        }
-
        writeV2S16(os, spritediv);
        writeV2S16(os, initial_sprite_basepos);
        writeU8(os, is_visible);
        writeU8(os, makes_footstep_sound);
-       writeF1000(os, automatic_rotate);
+       writeF32(os, automatic_rotate);
+       os << serializeString16(mesh);
+       writeU16(os, colors.size());
+       for (video::SColor color : colors) {
+               writeARGB8(os, color);
+       }
+       writeU8(os, collideWithObjects);
+       writeF32(os, stepheight);
+       writeU8(os, automatic_face_movement_dir);
+       writeF32(os, automatic_face_movement_dir_offset);
+       writeU8(os, backface_culling);
+       os << serializeString16(nametag);
+       writeARGB8(os, nametag_color);
+       writeF32(os, automatic_face_movement_max_rotation_per_sec);
+       os << serializeString16(infotext);
+       os << serializeString16(wield_item);
+       writeS8(os, glow);
+       writeU16(os, breath_max);
+       writeF32(os, eye_height);
+       writeF32(os, zoom_fov);
+       writeU8(os, use_texture_alpha);
+       os << serializeString16(damage_texture_modifier);
+       writeU8(os, shaded);
+       writeU8(os, show_on_minimap);
+
+       if (!nametag_bgcolor)
+               writeARGB8(os, NULL_BGCOLOR);
+       else if (nametag_bgcolor.value().getAlpha() == 0)
+               writeARGB8(os, video::SColor(0, 0, 0, 0));
+       else
+               writeARGB8(os, nametag_bgcolor.value());
+
+       // Add stuff only at the bottom.
+       // Never remove anything, because we don't want new versions of this
 }
 
 void ObjectProperties::deSerialize(std::istream &is)
 {
        int version = readU8(is);
-       if(version != 1) throw SerializationError(
-                       "unsupported ObjectProperties version");
-       hp_max = readS16(is);
-       physical = readU8(is);
-       weight = readF1000(is);
-       collisionbox.MinEdge = readV3F1000(is);
-       collisionbox.MaxEdge = readV3F1000(is);
-       visual = deSerializeString(is);
-       mesh = deSerializeString(is);
-       animation_frames.X = readF1000(is);
-       animation_frames.Y = readF1000(is);
-       animation_speed = readF1000(is);
-       animation_blend = readF1000(is);
-
-       u32 animation_bone_position_count = readU16(is);
-       for(u32 i=0; i<animation_bone_position_count; i++){
-               std::string bone_name = deSerializeString(is);
-               v3f bone_pos = readV3F1000(is);
-               animation_bone_position[bone_name] = bone_pos;
-       }
-       u32 animation_bone_rotation_count = readU16(is);
-       for(u32 i=0; i<animation_bone_rotation_count; i++){
-               std::string bone_name = deSerializeString(is);
-               v3f bone_rot = readV3F1000(is);
-               animation_bone_rotation[bone_name] = bone_rot;
-       }
+       if (version != 4)
+               throw SerializationError("unsupported ObjectProperties version");
 
-       visual_size = readV2F1000(is);
+       hp_max = readU16(is);
+       physical = readU8(is);
+       readU32(is); // removed property (weight)
+       collisionbox.MinEdge = readV3F32(is);
+       collisionbox.MaxEdge = readV3F32(is);
+       selectionbox.MinEdge = readV3F32(is);
+       selectionbox.MaxEdge = readV3F32(is);
+       pointable = readU8(is);
+       visual = deSerializeString16(is);
+       visual_size = readV3F32(is);
        textures.clear();
        u32 texture_count = readU16(is);
-       for(u32 i=0; i<texture_count; i++){
-               textures.push_back(deSerializeString(is));
+       for (u32 i = 0; i < texture_count; i++){
+               textures.push_back(deSerializeString16(is));
        }
-
        spritediv = readV2S16(is);
        initial_sprite_basepos = readV2S16(is);
        is_visible = readU8(is);
        makes_footstep_sound = readU8(is);
-       try{
-               automatic_rotate = readF1000(is);
-       }catch(SerializationError &e){}
+       automatic_rotate = readF32(is);
+       mesh = deSerializeString16(is);
+       colors.clear();
+       u32 color_count = readU16(is);
+       for (u32 i = 0; i < color_count; i++){
+               colors.push_back(readARGB8(is));
+       }
+       collideWithObjects = readU8(is);
+       stepheight = readF32(is);
+       automatic_face_movement_dir = readU8(is);
+       automatic_face_movement_dir_offset = readF32(is);
+       backface_culling = readU8(is);
+       nametag = deSerializeString16(is);
+       nametag_color = readARGB8(is);
+       automatic_face_movement_max_rotation_per_sec = readF32(is);
+       infotext = deSerializeString16(is);
+       wield_item = deSerializeString16(is);
+       glow = readS8(is);
+       breath_max = readU16(is);
+       eye_height = readF32(is);
+       zoom_fov = readF32(is);
+       use_texture_alpha = readU8(is);
+       try {
+               damage_texture_modifier = deSerializeString16(is);
+               u8 tmp = readU8(is);
+               if (is.eof())
+                       return;
+               shaded = tmp;
+               tmp = readU8(is);
+               if (is.eof())
+                       return;
+               show_on_minimap = tmp;
+
+               auto bgcolor = readARGB8(is);
+               if (bgcolor != NULL_BGCOLOR)
+                       nametag_bgcolor = bgcolor;
+               else
+                       nametag_bgcolor = nullopt;
+       } catch (SerializationError &e) {}
 }
-
-