Jump to content

VicToMeyeZR

Members
  • Posts

    570
  • Joined

  • Last visited

Posts posted by VicToMeyeZR

  1. ahh. ok.

     

     

    Thats it. I just needed to look a little deeper. I was trying modelreference but couldn't get anything from it, but class is the table I needed.

     

    local test = string.lower(StripExt(class.modelreference.path))

     

     

     

    Thanks Rick

  2. ok. I had to add a little to the class.lua file to get this to work.

     

    Name the XML file the same as your GMF model file.

     

    change to Class.lua

    --Creates a class from a model reference object
    function CreateClass(modelreference)
    local class={}
    local super={}
    class.instances={}
    classtable[modelreference]=class
    class.modelreference=modelreference
    class.name=string.lower(StripAll(modelreference.path))
    classnametable[class.name]=class
    Print("Creating class "..class.name)
    super.class=class
    

    CHANGE TO:

    --Creates a class from a model reference object
    function CreateClass(modelreference)
    local class={}
    local super={}
    class.instances={}
    classtable[modelreference]=class
    class.modelreference=modelreference
    class.name=string.lower(StripAll(modelreference.path))
    class.path=string.lower(StripExt(modelreference.path))
    classnametable[class.name]=class
    classnametable[class.path]=class.path
    Print("Creating class "..class.name)
    super.class=class
    

     

    Then change the top of my file from :

     

    local obj,err = XmlParser:ParseXmlFile("Models/characters/Cyber/character_visor_full.xml")
    

     

    CHANGE TO:

    local obj,err = XmlParser:ParseXmlFile(class.path..".xml")
    

  3. hmm, I think the issue is that the settings dialog will be the same for them all though. The InitDialog() runs the same for all instances. So if you wanted to have a character that had a different animation name than another character you couldn't.

     

    I guess I was thinking that the xml file would describe animations for that given instance of the character thingoid instead of being a file that describes how the settings dialog box should look. In this case I get the fact that it wouldn't be the easiest because instead of settings in the dialog box they need to edit an xml file, BUT, follow me on my journey of thinking just now, I wonder if we could have the properties from the editor shell out to a custom exe that we create that makes editing the xml file easier. It could be a small little properties window that is more flexible in adding animations to the xml file. The result would be the xml file that the user selects into the editor settings dialog.

     

     

    [edit]

    Then in the setkey method, when the xml file gets selected, you parse it out and store the information in a lua table variable to that object.

     

     

    I'm curious to hear where you are going with this more though.

     

    Yeah, my thinking in this, and of course it will progress, is that no matter WHAT animations the character has, this character file will work for EVERY character/NPC.

     

    You make the XML file based of that model, and as soon as you post each one in the editor, the properties fields are set.

     

    If I could find out how to automatically pull the XML file name based off the model instance, then the file WOULD be fully automated.

     

    the model lua file, and the model file name match, so if there was a way to tell the script the the XML file is the same, sure would help out a bunch. (*hint)

     

    I will post a video, so you can see.

  4. ok. My character script. This way I won't have to change much with it.

     

    XML FILE:

    <?xml version="1.0" encoding="utf-8"?>
    <animations>
    <start>
    	<idle value="Idle Start Frame">460</idle> 
    	<run value="Run Start Frame">1155</run>
    </start>
    <end>
    	<idle value="Idle End Frame">850</idle>
    	<run value="Run End Frame">1195</run>
    </end>
    </animations>
    

     

    MODEL LUA FILE:

    require("scripts/class")
    require("scripts/XML/XML")
    
    local class=CreateClass(...)
    
    local obj,err = XmlParser:ParseXmlFile("Models/characters/Cyber/character_visor_full.xml")
    
    function class:InitDialog(grid)
    
    self.super:InitDialog(grid)
    group = grid:AddGroup("Animations")
    //This adds a property field based off the XML file data structure.  This file MUST meet the data structure set by my post, or you will have to modify this script
    if (not err) then
    	for i,xmlNode in pairs(obj.ChildNodes) do
    		if(xmlNode.Name=="start") then
    			for i,subXmlNode in pairs(xmlNode.ChildNodes) do
    				if(subXmlNode.Name) then
    					group:AddProperty(subXmlNode.Name.."_start", PROPERTY_INTEGER, "", ""..subXmlNode.Attributes.value.."")
    				end
    			end
    		end
    	end
    	for i,xmlNode in pairs(obj.ChildNodes) do
    		if(xmlNode.Name=="end") then
    			for i,subXmlNode in pairs(xmlNode.ChildNodes) do
    				if(subXmlNode.Name) then
    					group:AddProperty(subXmlNode.Name.."_end", PROPERTY_INTEGER, "", ""..subXmlNode.Attributes.value.."")
    				end
    			end
    		end
    	end
    end
    
    group:Expand(1)
    end
    

  5. Here is a Lua only Parser.

     

    test.xml

    <?xml version="1.0" encoding="utf-8"?>
    <animations>
    <start>
    	<idle value="infiltrator">460</idle> 
    	<run value="infiltrator">1155</run>
    </start>
    <end>
    	<idle value="infiltrator">850</idle>
    	<run value="infiltrator">1195</run>
    </end>
    </animations>
    

     

    xml.lua

     

    XmlParser = {};
    
    function XmlParser:ToXmlString(value)
    value = string.gsub (value, "&", "&");		-- '&' -> "&"
    value = string.gsub (value, "<", "<");		-- '<' -> "<"
    value = string.gsub (value, ">", ">");		-- '>' -> ">"
    --value = string.gsub (value, "'", "'");	-- '\'' -> "'"
    value = string.gsub (value, "\"", """);	-- '"' -> """
    -- replace non printable char -> "
    "
      	value = string.gsub(value, "([^%w%&%;%p%\t% ])",
          	function (c) 
          		return string.format("%X;", string.byte(c)) 
          		--return string.format("%02X;", string.byte(c)) 
          		--return string.format("%02d;", string.byte(c)) 
          	end);
    return value;
    end
    
    function XmlParser:FromXmlString(value)
     	value = string.gsub(value, "([%x]+)%;",
         	function(h) 
         		return string.char(tonumber(h,16)) 
         	end);
     	value = string.gsub(value, "([0-9]+)%;",
         	function(h) 
         		return string.char(tonumber(h,10)) 
         	end);
    value = string.gsub (value, """, "\"");
    value = string.gsub (value, "'", "'");
    value = string.gsub (value, ">", ">");
    value = string.gsub (value, "<", "<");
    value = string.gsub (value, "&", "&");
    return value;
    end
    
    function XmlParser:ParseArgs(s)
     local arg = {}
     string.gsub(s, "(%w+)=([\"'])(.-)%2", function (w, _, a)
       	arg[w] = self:FromXmlString(a);
     	end)
     return arg
    end
    
    function XmlParser:ParseXmlText(xmlText)
     local stack = {}
     local top = {Name=nil,Value=nil,Attributes={},ChildNodes={}}
     table.insert(stack, top)
     local ni,c,label,xarg, empty
     local i, j = 1, 1
     while true do
       ni,j,c,label,xarg, empty = string.find(xmlText, "<(%/?)([%w:]+)(.-)(%/?)>", i)
       if not ni then break end
       local text = string.sub(xmlText, i, ni-1);
       if not string.find(text, "^%s*$") then
         top.Value=(top.Value or "")..self:FromXmlString(text);
       end
       if empty == "/" then  -- empty element tag
         table.insert(top.ChildNodes, {Name=label,Value=nil,Attributes=self:ParseArgs(xarg),ChildNodes={}})
       elseif c == "" then   -- start tag
         top = {Name=label, Value=nil, Attributes=self:ParseArgs(xarg), ChildNodes={}}
         table.insert(stack, top)   -- new level
         --log("openTag ="..top.Name);
       else  -- end tag
         local toclose = table.remove(stack)  -- remove top
         --log("closeTag="..toclose.Name);
         top = stack[#stack]
         if #stack < 1 then
           error("XmlParser: nothing to close with "..label)
         end
         if toclose.Name ~= label then
           error("XmlParser: trying to close "..toclose.Name.." with "..label)
         end
         table.insert(top.ChildNodes, toclose)
       end
       i = j+1
     end
     local text = string.sub(xmlText, i);
     if not string.find(text, "^%s*$") then
         stack[#stack].Value=(stack[#stack].Value or "")..self:FromXmlString(text);
     end
     if #stack > 1 then
       error("XmlParser: unclosed "..stack[stack.n].Name)
     end
     return stack[1].ChildNodes[1];
    end
    
    function XmlParser:ParseXmlFile(xmlFileName)
    local hFile,err = io.open(xmlFileName,"r");
    if (not err) then
    	local xmlText=hFile:read("*a"); -- read file content
    	io.close(hFile);
           return self:ParseXmlText(xmlText),nil;
    else
    	return nil,err;
    end
    end
    

     

    Run this file:

    require("Scripts/XML/xml")
    
    local obj,err = XmlParser:ParseXmlFile("Scripts/test.xml")
    
    if(not err) then
    for i,xmlNode in pairs(obj.ChildNodes) do
    if(xmlNode.Name=="start") then
    	for i,subXmlNode in pairs(xmlNode.ChildNodes) do
    		if(subXmlNode.Name) then
    			Notify(subXmlNode.Name.." value=\""..subXmlNode.Attributes.value.."\"");
    			if(subXmlNode.Value) then
    				Notify("   Content=\""..subXmlNode.Value.."\"");
    			end
    		end
    	end
    end
    end	
    else
    Notify("ERROR: "..err);		
    end
    

     

    It will return:

    idle value="infiltrator"
    content="460"
    run value="infiltrator"
    content="1155"
    

     

    With this I can have it run a dynamic menu for the object, as well as pass the deafult values based on the XML file information.

     

    I will post the scrip to run this part as soon as I have it.

  6. File Name: LuaXML.zip

    File Submitter: VicToMeyeZR

    File Submitted: 18 Jan 2010

    File Category: Lua Scripts

     

    Place to 2 DLL files in your root SDK folder. Place the core LUA file anywhere you want in the scripts folder.

     

    Go to town. :)

    LuaXML

     

    - a module that maps between Lua and XML without much ado

    version 1.7.2, 2009-09-06 by Gerald Franz, www.viremo.de

     

    LuaXML provides a minimal set of functions for the processing of XML data in Lua. It offers a

    very simple and natural mapping between the XML data format and Lua tables, which

    allows one to parse XML data just using Lua's normal table access and iteration

    methods: Substatements and text content is represented as array data having

    numerical keys, attributes and tags use string keys. This representation makes

    sure that the structure of XML data is exactly preserved in a read/write cycle.

    Since version 1.7, LuaXML consists of a well-optimized portable ISO-standard C file

    and a small Lua file. It is published under the same liberal licensing conditions as Lua

    itself (see below). It has been successfully compiled and used under Linux, various

    flavours of MS Windows, and MacOS X.

     

     

     

    Example

     

    -- import the LuaXML module

    require("LuaXML")

    -- load XML data from file "test.xml" into local table xfile

    local xfile = xml.load("test.xml")

    -- search for substatement having the tag "scene"

    local xscene = xfile:find("scene")

    -- if this substatement is found...

    if xscene ~= nil then

    -- ...print it to screen

    print(xscene)

    -- print attribute id and first substatement

    print( xscene.id, xscene[1] )

    -- set attribute id

    xscene["id"] = "newId"

    end

     

    -- create a new XML object and set its tag to "root"

    local x = xml.new("root")

    -- append a new subordinate XML object, set its tag to "child", and its content to 123

    x:append("child")[1] = 123

    print(x)

     

     

     

    Documentation

     

    LuaXML consists of the following functions:

     

    require("LuaXML")

    imports the LuaXML module.

    LuaXML consists of a lua file (LuaXML.lua) and normally a shared library (.dll/.so), although a static linking is possible as well. Both parts are imported by this call provided that they are found in Lua's package search path.

     

    function xml.new(arg)

    creates a new LuaXML object.

    * param arg (optional), (1) a table to be converted to be converted to a LuaXML object, or (2) the tag of the new LuaXML object

    Note that it is not mandatory to use this function in order to treat a Lua table as LuaXML object. Setting the metatable just allows the usage of a more object-oriented syntax (e.g., xmlvar:str() instead of xml.str(xmlvar) ). XML objects created by xml.load() or xml.eval() automatically offer the object-oriented syntax.

    * Returns new LuaXML object

     

    function xml.append(var,tag)

    appends a new subordinate LuaXML object to an existing one, optionally sets tag.

    * param var the parent LuaXML object

    * param tag (optional) the tag of the appended LuaXML object

    * Returns appended LuaXML object or nil in case of error

     

    function xml.load(filename)

    loads XML data from a file and returns it as table

     

    * param filename the name and path of the file to be loaded

    * Returns a Lua table containing the xml data in case of success or nil.

     

    function xml.save(var,filename)

    saves a Lua var as XML file.

     

    * param var, the variable to be saved, normally a table

    * param filename the filename to be used. An existing file of the same name gets overwritten.

     

    function xml.eval(xmlstring)

    converts an XML string to a Lua table

     

    * param xmlstring the string to be converted

    * Returns a Lua table containing the xml data in case of success or nil.

     

    function xml.tag(var, tag)

    sets or returns tag of a LuaXML object. This method is just "syntactic sugar" (using a typical Lua term)

    that allows the writing of clearer code. LuaXML stores the tag value of an XML statement at table

    index 0, hence it can be simply accessed or altered by var[0] or var[xml.TAG] (the latter is just a

    symbolic name for the value 0). However, writing var:tag() for access or var:tag("newTag") for altering

    may be more self explanatory.

     

    * param var, the variable whose tag should be accessed, a LuaXML object

    * param tag (optional) the new tag to be set.

    * Returns the current tag as string

     

    function xml.str(var, indent, tag)

    converts any Lua var to an xml string.

     

    * param var, the variable to be converted, normally a table

    * param indent (optional) the current level of indentation for pretty output. Mainly for internal use.

    * param tag (optional) the tag to be used for a table without tag. Mainly for internal use.

    * Returns an XML string in case of success or nil.

     

    function xml.find(var, tag, attributeKey,attributeValue)

    recursively parses a Lua table for a substatement fitting to the provided tag and attribute

     

    * param var, the table to be searched in.

    * param tag (optional) the xml tag to be found.

    * param attributeKey (optional) the exact attribute to be found.

    * param attributeValue (optional) the attribute value to be found.

    * Returns the first (sub-)table which matches the search condition or nil.

     

    function xml.registerCode(decoded,encoded)

    registers a custom code for the conversion between non-standard characters and XML character entities

     

    * param decoded the character (sequence) to be used within Lua.

    * param encoded the character entity to be used in XML.

    * By default, only the most basic entities are known to LuaXML (” & < > ').

    ANSI codes above 127 are directly converted to the XML character codes

    of the same number. If more character codes are needed, they can be

    registered using this function.

     

     

    Click here to download this file

  7. I am wondering about the controller you use Rick..

     

    (specifically the height and such)

     

    Do you really have he have the controller move the model?

     

    Can you pull the model height in real time, and move it with out a controller?

     

    specifically this line:

    object.controller:SetPosition(Vec3(pos.x, pos.y + (object.height/2), pos.z))
    

     

    Your moving the controller by half the distance of the height. Can you pull the model height in real time and move it with out the controller by half its real height?

     

    hope that makes sense.

  8.  

     

    The longer one gives an error (I fixed what was wrong with it as suggested). An empty box pops up and wants me to hit OK. I'll have to dissect that and see if I can make it work.

     

    That was a debug so I could see if my value of framestart or frameend was being set...

     

    I you find the Notify() and put a -- in front of it, and change this line:

     

        function object:GetKey(key,value)
                   if key=="idle_start" then
                           return self.idle_start
                   elseif key=="idle_end" then
                           return self.idle_start
    

     

    to :

        function object:GetKey(key,value)
                   if key=="idle_start" then
                           return self.idle_start
                   elseif key=="idle_end" then
                           return self.idle_end
    

     

    It will work.

     

    Then you can double click in the character in the objects window, and set your frame start and ends for each function.

     

    Right now, all the guy does is idle animate, and yes its a dexsoft model, so theirs do work, just requires little fix with the textures.

     

    When I get the controller to work with this, I will post it again for everyone to play with if they want.

  9. Can someone give me an idea what I got wrong here.

     

    I can put the model in the editor, but as soon as I set the values for the idle animation I get Exception violation, and it crashes.

     

    Thanks

    require("scripts/class")
    
    local class=CreateClass(...)
    
    
    function class:InitDialog(grid)
    self.super:InitDialog(grid)
    group = grid:AddGroup("Animations")
    group:AddProperty("idle_start", PROPERTY_INTEGER, "Idle Start Frame")
    group:AddProperty("idle_end", PROPERTY_INTEGER, "Idle End Frame")
    group:AddProperty("walk_start", PROPERTY_INTEGER, "Walk Start Frame")
    group:AddProperty("walk_end", PROPERTY_INTEGER, "Walk End Frame")
    group:AddProperty("run_start", PROPERTY_INTEGER, "Run Start Frame")
    group:AddProperty("run_end", PROPERTY_INTEGER, "Run End Frame")
    group:AddProperty("jump_start", PROPERTY_INTEGER, "Jump Start Frame")
    group:AddProperty("jump_end", PROPERTY_INTEGER, "Jump End Frame")
    group:AddProperty("crouch_start", PROPERTY_INTEGER, "Crouch Start Frame")
    group:AddProperty("crouch_start", PROPERTY_INTEGER, "Crouch End Frame")
    group:AddProperty("strafeleft_begin", PROPERTY_INTEGER, "Left Start Frame")
    group:AddProperty("strafeleft_end", PROPERTY_INTEGER, "Left End Frame")
    group:AddProperty("straferight_begin", PROPERTY_INTEGER, "Right Start Frame")
    group:AddProperty("straferight_end", PROPERTY_INTEGER, "Right End Frame")
    group:Expand(1)
    end
    
    function class:CreateObject(model)
    
    local object = self.super:CreateObject(model)
    object.model = model
    object.framestart = tonumber(object:GetKey("idle_start"))
    object.frameend = tonumber(object:GetKey("idle_end"))
    
    Notify(object.framestart)
    
    function object:SetKey(key,value)
    	if key=="idle_start" then
    		self.idle_start = tonumber(value)
    	elseif key=="idle_end" then
    		self.idle_end = tonumber(value)
    	elseif key=="walk_start" then
    		self.walk_start = tonumber(value)
    	elseif key=="walk_end" then
    		self.walk_end = tonumber(value)
    	elseif key=="run_start" then
    		self.run_start = tonumber(value)
    	elseif key=="run_end" then
    		self.run_end = tonumber(value)
    	elseif key=="jump_start" then
    		self.jump_start = tonumber(value)
    	elseif key=="jump_end" then
    		self.jump_end = tonumber(value)
    	elseif key=="crouch_start" then
    		self.crouch_start = tonumber(value)
    	elseif key=="crouch_end" then
    		self.crouch_end = tonumber(value)
    	elseif key=="strafeleft_start" then
    		self.strafeleft_start = tonumber(value)
    	elseif key=="strafeleft_end" then
    		self.strafeleft_end = tonumber(value)
    	elseif key=="straferight_start" then
    		self.straferight_start = tonumber(value)
    	elseif key=="straferight_end" then
    		self.straferight_end = tonumber(value)
    	else
    		return self.super:SetKey(key,value)
    	end
    	return 1
    end
    
    function object:GetKey(key,value)
    	if key=="idle_start" then
    		return self.idle_start
    	elseif key=="idle_end" then
    		return self.idle_start
    	elseif key=="walk_start" then
    		return self.walk_start
    	elseif key=="walk_end" then
    		return self.walk_end
    	elseif key=="run_start" then
    		return self.run_start
    	elseif key=="run_end" then
    		return self.run_end
    	elseif key=="jump_start" then
    		return self.jump_start
    	elseif key=="jump_end" then
    		return self.jump_end
    	elseif key=="crouch_start" then
    		return self.crouch_start
    	elseif key=="crouch_end" then
    		return self.crouch_end
    	elseif key=="strafeleft_start" then
    		return self.strafeleft_start
    	elseif key=="strafeleft_end" then
    		return self.strafeleft_end
    	elseif key=="straferight_start" then
    		return self.straferight_start
    	elseif key=="straferight_end" then
    		return self.straferight_end
    	else
    		return self.super:GetKey(key,value)
    	end
    	return value
    end
    
           function object:StartAnimations(movement)
                   object.framestart = object:GetKey(movement .. "_start")
                   return object.framestart
           end
    
           function object:EndAnimations(movement)
                   object.frameend = object:GetKey(movement .. "_end")
                   return object.frameend
           end
    
    function object:LockKeys(model)
    
    	self.super:LockKeys()
    end
    
    function object:UnlockKeys(model)
    
    	self.super:UnlockKeys()
    end
    
    function object:UpdateMatrix()
    
    end
    
    function object:Reset()
    
    end
    
    function object:SetTarget(target,index)
    
    end
    
    function object:Collision(entity,position,normal,force,speed)
    
    end
    
    function object:ReceiveMessage(message,extra)
    	if message=="forward" then
    --[[		elseif message=="reverse" then
    	elseif message=="mleft" then
    	elseif message=="mright" then
    	elseif message=="tleft" then
    	elseif message=="tright" then
    	elseif message=="crouch" then
    	elseif message=="jump" then
    	elseif message=="attack" then ]]--
    	else
    		self.super:ReceiveMessage(message,extra)
    	end
    end
    
    function object:Render()
    
    	object.framestart = object:StartAnimations("idle")
    	object.frameend = object:EndAnimations("idle")
    
    	if object.frameend ~= nil and object.frameend ~= 0 or object.framestart ~= nil then
    		object.frame = math.fmod(AppTime()/35, object.framestart - object.frameend) + object.framestart
    		Animate(object.model, object.frame, 0.5, 0, true)
    	end
    
    end
    
    function object:Free(model)
    
    	self.super:Free()
    end
    
    end
    
    function class:Free()
    
    self.super:Free()
    end
    
    

  10. ok. revised for your next version.

     

    require("scripts/class")
    require("Scripts/hooks")
    
    
    local class=CreateClass(...)
    
    
    function class:InitDialog(grid)
    self.super:InitDialog(grid)
    
    group = grid:AddGroup("Character")
    group:AddProperty("model", PROPERTY_FILE, "GMF Files (*.gmf):gmf", "", "Model Files")
    group:AddProperty("controller_height", PROPERTY_FLOAT, "Controller Height")
    group:AddProperty("controller_radius", PROPERTY_FLOAT, "Controller Radius")
    group:AddProperty("controller_step_height", PROPERTY_FLOAT, "Controller Step Height")
    group:AddProperty("controller_max_slope", PROPERTY_FLOAT,  "Controller Max Slope")
    group = grid:AddGroup("Animations")
    group:AddProperty("idle_start", PROPERTY_INTEGER, "Idle Start Frame")
    group:AddProperty("idle_end", PROPERTY_INTEGER, "Idle End Frame")
    group:AddProperty("walk_start", PROPERTY_INTEGER, "Walk Start Frame")
    group:AddProperty("walk_end", PROPERTY_INTEGER, "Walk End Frame")
    group:AddProperty("run_start", PROPERTY_INTEGER, "Run Start Frame")
    group:AddProperty("run_end", PROPERTY_INTEGER, "Run End Frame")
    group:AddProperty("jump_start", PROPERTY_INTEGER, "Jump Start Frame")
    group:AddProperty("jump_end", PROPERTY_INTEGER, "Jump End Frame")
    group:AddProperty("crouch_start", PROPERTY_INTEGER, "Crouch Start Frame")
    group:AddProperty("crouch_start", PROPERTY_INTEGER, "Crouch End Frame")
    
    group:Expand(1)
    end
    
    function class:CreateObject(model)
    local object=self.super:CreateObject(model)
    
    object.model = model
    object.height = tonumber(object:GetKey("controller_height", "1.8"))
    local radius = tonumber(object:GetKey("controller_radius", "0.4"))
    local step = tonumber(object:GetKey("controller_step_height", "0.5"))
    local slope = tonumber(object:GetKey("controller_max_slope", "45.0"))
    
    object.oneTime = false
    object.controller = CreateController(object.height, radius, step, slope)
    object.controller:SetMass(1.0)
    EntityType(object.controller, 1)
    
    -- set the position of the controller to the editor object
    local pos = object.model:GetPosition()
    object.controller:SetPosition(Vec3(pos.x, pos.y + (object.height/2), pos.z))
    object.characterModel = nil
    
    object.move = 0
    object.strafe = 0
    object.rotate = 0
    object.jump = 0
    object.moveSpeed = 2
    object.strafeSpeed = 2
    object.framestart = 0
    object.frameend = 0
    
    function object:StartAnimations(movement)
    	object.framestart = self.model:GetKey(movement .. "_start")
    	return object.framestart
    end
    
    function object:EndAnimations(movement)
    	object.frameend = self.model:GetKey(movement .. "_end")
    	return object.frameend
    end
    
    function object:SetKey(key,value)
    	if key=="model" then
    		local pos = self.model:GetPosition()
    		self.characterModel = LoadModel("abstract::"..value)
    		self.characterModel:SetPosition(Vec3(pos.x, pos.y, pos.z))
    	else
    		return self.super:SetKey(key,value)
    	end
    	return 1
    end
    
    function object:GetKey(key,value)
    	if key=="" then
    	else
    		return self.super:GetKey(key,value)
    	end
    	return value
    end
    
    function object:Update()
    
    	if object.move == 0 then
    		if object.frameend ~= 0 then
    			object:StartAnimations("idle")
    			object:EndAnimations("idle")
    		else
    			object.framestart = 0
    			object.frameend = 100
    		end
    	end
    
    	if self.characterModel ~= nil then
    		if object.frameend ~= 0 then
    			object.frame = math.fmod(AppTime()/35, object.frameend-object.framestart)+object.framestart
    			Animate(self.characterModel, object.frame, 1.0, 0, true)
    		end
    	end
    
    	if GetGlobalString("mode") == "GAME_MODE" then
    		if self.characterModel ~= nil then
    			if object.oneTime == false then
    				object.oneTime = true
    
    				object.controller:SetPosition(object.model:GetPosition())
    			end
    
    			self.controller:Update(self.rotation, self.move, self.strafe, self.jump, 5000, 10)
    			self.jump = 0		-- reset
    
    			-- the character model must follow the controller
    			-- for the 3rd person camera to work we must also move the object model, which is stupid
    			self.model:SetPosition(Vec3(object.controller.position.x, object.controller.position.y - (object.height/2), object.controller.position.z))
    			self.characterModel:SetPosition(Vec3(object.controller.position.x, object.controller.position.y - (object.height/2), object.controller.position.z))
    		end
    	else
    		-- constantly update the controller to the object in the editor
    		local pos = object.model:GetPosition()
    		object.controller:SetPosition(Vec3(pos.x, pos.y + (object.height/2), pos.z))
    
    
    		-- make the model follow
    		if self.characterModel ~= nil then
    			self.characterModel:SetPosition(Vec3(pos.x, pos.y, pos.z))
    		end
    	end
    
    end
    
    function object:UpdateMatrix()
    
    end
    
    --[[
    function object:LockKeys(model)
    
    	self.super:LockKeys()
    end
    ]]--
    
    --[[
    function object:UnlockKeys(model)
    
    	self.super:UnlockKeys()
    end
    ]]--
    
    --[[
    function object:UpdateMatrix()
    
    end
    ]]--
    
    --[[
    function object:Reset()
    
    end
    ]]--
    
    --[[
    function object:SetTarget(target,index)
    
    end
    ]]--
    
    --[[
    function object:Collision(entity,position,normasl,force,speed)
    
    end
    ]]--
    function object:ReceiveMessage(message,extra)
    	if message == "move" then
    		object.move = tonumber(extra) * self.moveSpeed
    		object:StartAnimations("walk")
    		object:EndAnimations("walk")
    	elseif message == "jump" and object.controller:IsAirborne() == 0 then
    		object.jump = tonumber(extra)
    	elseif message == "strafe" then
    		object.strafe = tonumber(extra) * self.strafeSpeed
    	else
    		self.super:ReceiveMessage(message,extra)
    	end
    
    end
    
    
    function object:Free(model)
    	object.controller:Free()
    
    	if object.characterModel ~= nil then
    		object.characterModel:Free()
    	end
    
    	--Notify("Inside free")
    	self.super:Free()
    end
    
    end
    
    --[[
    function class:Free()
    
    self.super:Free()
    end
    ]]--
    

     

    Checked Animations per movement, and they do work.

     

    BUG:

    Animation frames for idle, MUST be set prior to loading the character mesh.

  11. I haven't tested that part yet...

     

    I am trying to debug it so it won't crash all the time, so it means adding alot of if then checks, because if the start frame and end frame ever end up both being 0, it will crash the editor

×
×
  • Create New...