|
| Character Creation Options | |
| | |
Author | Message |
---|
Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Character Creation Options Wed 22 Feb - 18:56 | |
| EDIT: I think I've worked out the problem, so I'm locking it whilst I test my theory so that someone doesn't point it out! -> My potential solution didn't work, so the thread is now unlocked! So, I'm trying to add the option to choose between different models during the Character Creation phase. I've tried to copy and modify the code from the Fantasy World character_factory.py file, but it doesn't seem to be working. Here are the lines that I have changed in character_factory.py: - Code:
-
meshInfo = { "female_1" : [ "human_female.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_01_clothed_mat" ], [ "human_female_head_01-mesh.0", "human_female_fantasy.head_01_mat" ], [ "human_female_head_01_hair-mesh.0", "human_female_fantasy.head_01_hair_01_mat" ], ] ], "female_2" : [ "human_female.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_02_clothed_mat" ], [ "human_female_head_02-mesh.0", "human_female_fantasy.head_02_mat" ], [ "human_female_head_02_hair_01-mesh.0", "human_female_fantasy.head_02_hair_01_mat" ], ] ], "male_1" : [ "human_male.mesh" , [ "bodyShape-lib.0", "human_male.skin_material" ], [ "head_aShape-lib.0", "human_male.head_a_material" ] ] }, "male_2" : [ "human_male.mesh" , [ "bodyShape-lib.0", "human_male.skin_material" ], [ "head_bShape-lib.0", "human_male.head_b_material" ] ] }
# Add clothing meshes. These should really be done as inventory items, # but as a quick fix, we put it in the base display context of the object. meshInfo["human_male.mesh"].extend([[ "leather_b_bootsShape-lib.0", "human_male.leather_b_material" ], [ "leather_b_tunicShape-lib.0", "human_male.leather_b_material" ], [ "leather_b_pantsShape-lib.0", "human_male.leather_b_material" ]]) meshInfo["human_female.mesh"].extend([[ "leather_a_beltShape-lib.0", "human_female.leather_a_material" ], [ "leather_a_pantsShape-lib.0", "human_female.leather_a_material" ], [ "leather_a_bootsShape-lib.0", "human_female.leather_a_material" ], [ "leather_a_tunicShape-lib.0", "human_female.leather_a_material" ]])
# set up the default display context displayContext = DisplayContext("human_female.mesh", True) for entry in meshInfo["human_female.mesh"]: displayContext.addSubmesh(DisplayContext.Submesh(entry[0], entry[1]))
When I get to the creation screen in the client, there are no options for other models, jsut the default male and female one. When I then click 'Create' it comes up with an internal error. I checked the character_creation.out file, and the resultant error is as follows: - Code:
-
ERROR [2012-02-22 07:33:51,991] main ScriptManager.runPYFile: file=..\config\earth2.0\character_factory.py Traceback (innermost last): (no code object) at line 0 SyntaxError: ('invalid syntax', ('..\\config\\earth2.0\\character_factory.py', 32, 14, ' "male_2" : [ "human_male.mesh" ,')) Traceback (innermost last): (no code object) at line 0 SyntaxError: ('invalid syntax', ('..\\config\\earth2.0\\character_factory.py', 32, 14, ' "male_2" : [ "human_male.mesh" ,'))
at org.python.core.parser.fixParseError(Unknown Source) at org.python.core.parser.parse(Unknown Source) at org.python.core.Py.compile_flags(Unknown Source) at multiverse.server.engine.ScriptManager.runPYFile(ScriptManager.java:181) at multiverse.server.engine.ScriptManager.runFile(ScriptManager.java:94) at multiverse.server.engine.Engine.processPostScripts(Engine.java:541) at multiverse.server.engine.Engine.main(Engine.java:396) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at multiverse.server.marshalling.Trampoline.main(Trampoline.java:150)
.....
ERROR [2012-02-22 07:46:50,678] LoginConnection-1 Caught exception in character factory: Traceback (innermost last): File "..\config\common\character_factory.py", line 66, in createCharacter NameError: overrideTempate Traceback (innermost last): File "..\config\common\character_factory.py", line 66, in createCharacter NameError: overrideTempate
at org.python.core.Py.NameError(Unknown Source) at org.python.core.PyFrame.getglobal(Unknown Source) at org.python.pycode._pyx4.createCharacter$2(..\config\common\character_factory.py:66) at org.python.pycode._pyx4.call_function(..\config\common\character_factory.py) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyFunction.__call__(Unknown Source) at org.python.core.PyMethod.__call__(Unknown Source) at org.python.core.PyObject.__call__(Unknown Source) at org.python.core.PyObject._jcallexc(Unknown Source) at org.python.core.PyObject._jcall(Unknown Source) at org.python.proxies.mvmodule$SampleFactory$0.createCharacter(Unknown Source) at multiverse.mars.plugins.MarsLoginPlugin.handleCharacterCreateMessage(MarsLoginPlugin.java:262) at multiverse.server.worldmgr.LoginPlugin$SocketHandler.dispatchMessage(LoginPlugin.java:281) at multiverse.server.worldmgr.LoginPlugin$SocketHandler.run(LoginPlugin.java:208) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)
Any idea what's going on? ~Tristan | |
| | | zoot686 Foundation Donor
Posts : 78 Join date : 2012-02-15 Location : USA
| Subject: Re: Character Creation Options Fri 24 Feb - 12:26 | |
| Check the last line in the "male_1" section...............you have a closing } instead of a closing ]
(edited in later) and both male_1 and male_2 sections should end with a ], followed by a } to close the entire code block
Last edited by zoot686 on Fri 24 Feb - 12:29; edited 1 time in total (Reason for editing : noticed another little syntax error) | |
| | | zoot686 Foundation Donor
Posts : 78 Join date : 2012-02-15 Location : USA
| Subject: Re: Character Creation Options Fri 24 Feb - 12:51 | |
| - Code:
-
meshInfo = { "female_1" : [ "human_female.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_01_clothed_mat" ], [ "human_female_head_01-mesh.0", "human_female_fantasy.head_01_mat" ], [ "human_female_head_01_hair-mesh.0", "human_female_fantasy.head_01_hair_01_mat" ], ] ], "female_2" : [ "human_female.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_02_clothed_mat" ], [ "human_female_head_02-mesh.0", "human_female_fantasy.head_02_mat" ], [ "human_female_head_02_hair_01-mesh.0", "human_female_fantasy.head_02_hair_01_mat" ], ] ], "male_1" : [ "human_male.mesh" , [ [ "bodyShape-lib.0", "human_male.skin_material" ], [ "head_aShape-lib.0", "human_male.head_a_material" ] ] ], "male_2" : [ "human_male.mesh" , [ [ "bodyShape-lib.0", "human_male.skin_material" ], [ "head_bShape-lib.0", "human_male.head_b_material" ] ] ] }
But why didn't you just use the raw code as is and just change the materials/textures? - Code:
-
meshInfo = { "female_1" : [ "human_female.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_01_clothed_mat" ], [ "human_female_head_01-mesh.0", "human_female_fantasy.head_01_mat" ], [ "human_female_head_01_hair-mesh.0", "human_female_fantasy.head_01_hair_01_mat" ], ] ], "female_2" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_02_clothed_mat" ], [ "human_female_head_02-mesh.0", "human_female_fantasy.head_02_mat" ], [ "human_female_head_02_hair_01-mesh.0", "human_female_fantasy.head_02_hair_01_mat" ], ] ], "male_1" : [ "human_male.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_01" ], [ "human_male_head_01-mesh.0", "human_male_fantasy.human_male_head_01" ], [ "male_head_01_hair_01-mesh.0", "human_male_fantasy.human_male_head_01_hair_01" ], ] ], "male_2" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_02" ], [ "human_male_head_02-mesh.0", "human_male_fantasy.human_male_head_02" ], [ "human_male_02_hair_01-mesh.0", "human_male_fantasy.human_male_head_02_hair_01" ], ] ] }
look at the differences between the two..........in particular the "male" section where meshes are defined rather than libraries as in your modified codeblock | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Fri 24 Feb - 13:49 | |
| Ok, good point. So, I've changed that, and it keeps throwiing errors as it goes further down the script. I keep changing things, and then it finds something else wrong further down lol. However now, I'm stuck! Here's my character_factory.py file: - Code:
-
from multiverse.mars import * from multiverse.mars.objects import * from multiverse.mars.core import * from multiverse.mars.events import * from multiverse.mars.util import * from multiverse.mars.plugins import * from multiverse.server.plugins import * from multiverse.server.math import * from multiverse.server.events import * from multiverse.server.objects import * from multiverse.server.engine import * from java.lang import * from java.util import LinkedList
meshInfo = { "female_1" : [ "human_female.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_01_clothed_mat" ], [ "human_female_head_01-mesh.0", "human_female_fantasy.head_01_mat" ], [ "human_female_head_01_hair-mesh.0", "human_female_fantasy.head_01_hair_01_mat" ], ] ], "female_2" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_02_clothed_mat" ], [ "human_female_head_02-mesh.0", "human_female_fantasy.head_02_mat" ], [ "human_female_head_02_hair_01-mesh.0", "human_female_fantasy.head_02_hair_01_mat" ], ] ], "male_1" : [ "human_male.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_01" ], [ "human_male_head_01-mesh.0", "human_male_fantasy.human_male_head_01" ], [ "male_head_01_hair_01-mesh.0", "human_male_fantasy.human_male_head_01_hair_01" ], ] ], "male_2" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_02" ], [ "human_male_head_02-mesh.0", "human_male_fantasy.human_male_head_02" ], [ "human_male_02_hair_01-mesh.0", "human_male_fantasy.human_male_head_02_hair_01" ], ] ] }
# Add clothing meshes. These should really be done as inventory items, # but as a quick fix, we put it in the base display context of the object. #meshInfo["human_male.mesh"].extend([[ "leather_b_bootsShape-lib.0", "human_male.leather_b_material" ], # [ "leather_b_tunicShape-lib.0", "human_male.leather_b_material" ], # [ "leather_a_pantsShape-lib.0", "human_male.cloth_a_material" ]]) #meshInfo["human_female.mesh"].extend([[ "leather_a_beltShape-lib.0", "human_female.leather_a_material" ], # [ "leather_a_pantsShape-lib.0", "human_female.leather_a_material" ], # [ "leather_a_bootsShape-lib.0", "human_female.leather_a_material" ], # [ "leather_a_tunicShape-lib.0", "human_female.leather_a_material" ]])
# set up the default display context #displayContext = DisplayContext("human_female.mesh", True) #for entry in meshInfo["human_female.mesh"]: # displayContext.addSubmesh(DisplayContext.Submesh(entry[0], entry[1])) displayContext = DisplayContext("human_female_ruth.mesh", True) displayContext.addSubmesh(DisplayContext.Submesh("human_female_body_ruth-mesh.0", "human_female_ruth.ruth_body_clothed_mat")) displayContext.addSubmesh(DisplayContext.Submesh("human_female_head_ruth-mesh.0", "human_female_ruth.ruth_head_mat")) displayContext.addSubmesh(DisplayContext.Submesh("human_female_head_ruth_hair-mesh.0", "human_female_ruth.ruth_hair_mat"))
# default player template player = Template("DefaultPlayer")
player.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, displayContext) player.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_OBJECT_TYPE, ObjectTypes.player) player.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_RUN_THRESHOLD, Float(5000))
player.put(CombatClient.NAMESPACE, "combat.userflag", Boolean(True)) player.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_DEADSTATE, Boolean(False)) player.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_REGEN_EFFECT, "regen effect") player.put(InventoryClient.NAMESPACE, InventoryClient.TEMPL_ITEMS, "settlerpistol; Leather Tunic; Leather Pants") player.put(CombatClient.NAMESPACE, "health-max", MarsStat("health-max", 100)) player.put(CombatClient.NAMESPACE, "health", MarsStat("health", 100)) player.put(CombatClient.NAMESPACE, "mana-max", MarsStat("mana-max", 100)) player.put(CombatClient.NAMESPACE, "mana", MarsStat("mana", 100)) player.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_AUTOATTACK_ABILITY, "player attack ability")
ObjectManagerClient.registerTemplate(player)
# character factory class SampleFactory (CharacterFactory): def createCharacter(self, worldName, uid, properties): name = properties.get("characterName")
# check to see that the name is valid # we may also want to check for uniqueness and reject bad words here if not name or name == "": properties.put("errorMessage", "Invalid name") return 0
meshName = properties.get("model") gender = properties.get("sex") if meshName: displayContext = DisplayContext(meshName, True) submeshInfo = meshInfo[meshName] for entry in submeshInfo: displayContext.addSubmesh(DisplayContext.Submesh(entry[0], entry[1])) ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, displayContext)
statProperties = ["strength","dexterity","wisdom","intelligence","class"] for statProp in statProperties: if (not properties.get(statProp)): properties.put("errorMessage", "Missing property "+statProp) return 0
# get combat settings strength = int(properties.get("strength")) dexterity = int(properties.get("dexterity")) wisdom = int(properties.get("wisdom")) intelligence = int(properties.get("intelligence")) player_class = str(properties.get("class"))
# get default instance oid instanceOid = InstanceClient.getInstanceOid("default") if not instanceOid: Log.error("SampleFactory: no 'default' instance") properties.put("errorMessage", "No default instance") return 0
# set the spawn location spawnMarker = InstanceClient.getMarker(instanceOid, "spawn") spawnMarker.getPoint().setY(0)
# override template ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_NAME, name) ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_INSTANCE, Long(instanceOid)) ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_LOC, spawnMarker.getPoint()) ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_ORIENT, spawnMarker.getOrientation())
restorePoint = InstanceRestorePoint("default", spawnMarker.getPoint()) restorePoint.setFallbackFlag(True) restoreStack = LinkedList() restoreStack.add(restorePoint) ot.put(Namespace.OBJECT_MANAGER, ObjectManagerClient.TEMPL_INSTANCE_RESTORE_STACK, restoreStack) ot.put(Namespace.OBJECT_MANAGER, ObjectManagerClient.TEMPL_CURRENT_INSTANCE_NAME, "default")
ot.put(Namespace.OBJECT_MANAGER, ObjectManagerClient.TEMPL_PERSISTENT, Boolean(True))
ot.put(ClassAbilityClient.NAMESPACE, "class", player_class) ot.put(CombatClient.NAMESPACE, "strength", MarsStat("strength", strength)) ot.put(CombatClient.NAMESPACE, "dexterity", MarsStat("dexterity", dexterity)) ot.put(CombatClient.NAMESPACE, "wisdom", MarsStat("wisdom", wisdom)) ot.put(CombatClient.NAMESPACE, "intelligence", MarsStat("intelligence", intelligence)) ot.put(CombatClient.NAMESPACE, "stamina", MarsStat("stamina", int(int(strength)*1.5))) ot.put(CombatClient.NAMESPACE, "stamina-max", MarsStat("stamina-max", int(int(strength)*1.5))) ot.put(CombatClient.NAMESPACE, "mana", MarsStat("mana", int(intelligence)*2)) ot.put(CombatClient.NAMESPACE, "mana-max", MarsStat("mana-max", int(intelligence)* 2)) ot.put(CombatClient.NAMESPACE, "health", MarsStat("health", int(strength) * 2)) ot.put(CombatClient.NAMESPACE, "health-max", MarsStat("health-max", int(strength)*2)) ot.put(CombatClient.NAMESPACE, "experience", MarsStat("experience", 0, 100)) ot.put(CombatClient.NAMESPACE, "level", MarsStat("level", 1, 100))
# generate the object objOid = ObjectManagerClient.generateObject("DefaultPlayer", ot) Log.debug("SampleFactory: generated obj oid=" + str(objOid)) return objOid
sampleFactory = SampleFactory() LoginPlugin.getCharacterGenerator().setCharacterFactory(sampleFactory)
Any idea what's wrong with it? Tristan | |
| | | zoot686 Foundation Donor
Posts : 78 Join date : 2012-02-15 Location : USA
| Subject: Re: Character Creation Options Fri 24 Feb - 21:50 | |
| What's the error message in the log file..........it'll give the line number and the character number | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Sat 25 Feb - 4:48 | |
| oops, forgot about that. - Code:
-
ERROR [2012-02-24 17:45:59,347] LoginConnection-1 Caught exception in character factory: Traceback (innermost last): File "..\config\earth2.0\character_factory.py", line 99, in createCharacter KeyError: human_male.mesh Traceback (innermost last): File "..\config\earth2.0\character_factory.py", line 99, in createCharacter KeyError: human_male.mesh
at org.python.core.Py.KeyError(Unknown Source) at org.python.core.PyObject.__getitem__(Unknown Source) at org.python.pycode._pyx5.createCharacter$2(..\config\earth2.0\character_factory.py:99) at org.python.pycode._pyx5.call_function(..\config\earth2.0\character_factory.py) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyFunction.__call__(Unknown Source) at org.python.core.PyMethod.__call__(Unknown Source) at org.python.core.PyObject.__call__(Unknown Source) at org.python.core.PyObject._jcallexc(Unknown Source) at org.python.core.PyObject._jcall(Unknown Source) at org.python.proxies.mvmodule$SampleFactory$1.createCharacter(Unknown Source) at multiverse.mars.plugins.MarsLoginPlugin.handleCharacterCreateMessage(MarsLoginPlugin.java:262) at multiverse.server.worldmgr.LoginPlugin$SocketHandler.dispatchMessage(LoginPlugin.java:281) at multiverse.server.worldmgr.LoginPlugin$SocketHandler.run(LoginPlugin.java:208) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) ERROR [2012-02-24 17:45:59,348] LoginConnection-1 Character factory returned null OID ERROR [2012-02-24 17:45:59,348] LoginConnection-1 MarsLoginPlugin: character creation failed, uid=-582039 errorMessage=Internal error
Thanks for your help | |
| | | Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: Character Creation Options Sat 25 Feb - 5:46 | |
| I think your problem is with your client file. it looks like it is sending human_male.mesh instead of male_1. Make sure that the meshInfo map on the client is the same as the one on the server.
EDIT It appears that what is happening is that the client is sending the actual meshName while the server is expecting an identifier (male_1) you could switch it so that the entries in the map are stored by the meshName but then you would only be able to have one costume for each mesh or you can modify the client to send the identifier instead of the meshName. Look at FantasyCharacterCreation.py instead of SampleCharacterCreation.py to see an example | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Sat 25 Feb - 5:55 | |
| EDIT: Just saw your Edit, I'll try that
How do I go about doing that? | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Sat 25 Feb - 6:23 | |
| Ok, so I replicated the code from the FantasyWorld character_factory.py file, and here's what I have for the actual Character Factory section: - Code:
-
# character factory class SampleFactory (CharacterFactory): def createCharacter(self, worldName, uid, properties): name = properties.get("characterName")
# check to see that the name is valid # we may also want to check for uniqueness and reject bad words here if not name or name == "": properties.put("errorMessage", "Invalid name") return 0
modelName = properties.get("model") meshName = meshInfo[modelName][0] submeshes = meshInfo[modelName][1] override = Template() if meshName: displayContext = DisplayContext(meshName, True) for entry in submeshes: displayContext.addSubmesh(DisplayContext.Submesh(entry[0], entry[1])) override.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, displayContext)
statProperties = ["strength","dexterity","wisdom","intelligence","class"] for statProp in statProperties: if (not properties.get(statProp)): properties.put("errorMessage", "Missing property "+statProp) return 0
When I try to create a character, there are no extra models (just the basic male and female), and an error pops up saying 'Exception thrown in createcharacter'. At the moment, I can't seem to isolate the problem... However, I am still getting this in the login_manager.out, but I don't see why a new error was thrown up for what seems to be the same problem. - Code:
-
ERROR [2012-02-24 19:08:14,327] LoginConnection-2 Caught exception in character factory: Traceback (innermost last): File "..\config\earth2.0\character_factory.py", line 95, in createCharacter KeyError: human_male.mesh Traceback (innermost last): File "..\config\earth2.0\character_factory.py", line 95, in createCharacter KeyError: human_male.mesh
at org.python.core.Py.KeyError(Unknown Source) at org.python.core.PyObject.__getitem__(Unknown Source) at org.python.pycode._pyx5.createCharacter$2(..\config\earth2.0\character_factory.py:95) at org.python.pycode._pyx5.call_function(..\config\earth2.0\character_factory.py) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyFunction.__call__(Unknown Source) at org.python.core.PyMethod.__call__(Unknown Source) at org.python.core.PyObject.__call__(Unknown Source) at org.python.core.PyObject._jcallexc(Unknown Source) at org.python.core.PyObject._jcall(Unknown Source) at org.python.proxies.mvmodule$SampleFactory$1.createCharacter(Unknown Source) at multiverse.mars.plugins.MarsLoginPlugin.handleCharacterCreateMessage(MarsLoginPlugin.java:262) at multiverse.server.worldmgr.LoginPlugin$SocketHandler.dispatchMessage(LoginPlugin.java:281) at multiverse.server.worldmgr.LoginPlugin$SocketHandler.run(LoginPlugin.java:208) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) ERROR [2012-02-24 19:08:14,327] LoginConnection-2 Character factory returned null OID ERROR [2012-02-24 19:08:14,327] LoginConnection-2 MarsLoginPlugin: character creation failed, uid=-582039 errorMessage=Internal error
Thanks... | |
| | | Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: Character Creation Options Sat 25 Feb - 6:33 | |
| You need to do the same on the client side (incidently I was refering to the FantasyCharacterCreation.py on the client not on the server) but it looks like you might need to use both | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Sat 25 Feb - 6:36 | |
| Hmm, I didn't even know they existed!
I'll have a flick through now. | |
| | | Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: Character Creation Options Sat 25 Feb - 6:52 | |
| Yes there is a server side character_factory.py that creates the character and a client side (in the scripts folder) SampleCharacterCreation.py or FantasyCharacterCreation.py that allow the player to make selections and choose what to create. | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Sat 25 Feb - 16:08 | |
| Right, I've sorted it now, as per Delurin's instruction. Cheers guys | |
| | | zoot686 Foundation Donor
Posts : 78 Join date : 2012-02-15 Location : USA
| Subject: Re: Character Creation Options Sat 25 Feb - 23:25 | |
| So, are you going to throw some working scripts our way and document it on the wiki, or are you going to let other folks reinvent the wheel too? | |
| | | Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: Character Creation Options Sun 26 Feb - 2:16 | |
| The scripts work but it can be confusing since there are two versions there is the sample world script which client side uses the SampleCharacterCreation.py and server side uses the sample world's character_factory.py and the fantasy world script which client side uses the FantasyCharacterCreation.py and server side uses the mv_fantasy world's character_factory. As long as you follow the layout of one of those you should be fine. The problem comes if you try to mismatch between them, then you get the problem that tristan got. | |
| | | zoot686 Foundation Donor
Posts : 78 Join date : 2012-02-15 Location : USA
| Subject: Re: Character Creation Options Sun 26 Feb - 6:38 | |
| Well, I'm still several pages behind, and just figured out how to import assets, so in the fairly near future I'll be working getting character creation choices going, and clear docs make things an awful lot easier. | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Sun 26 Feb - 9:03 | |
| - zoot686 wrote:
- So, are you going to throw some working scripts our way and document it on the wiki, or are you going to let other folks reinvent the wheel too?
Ha, I thought I had it sorted, but it threw some more errors. For now, I'm going to concentrate on the more important stuff, like the actual world layout. However, I will be going back to it again sometime tonight. | |
| | | zoot686 Foundation Donor
Posts : 78 Join date : 2012-02-15 Location : USA
| Subject: Re: Character Creation Options Sun 26 Feb - 13:32 | |
| well that sux rox*grumbles* I hope you have great luck and fortune because "I'm" right behind you. | |
| | | Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: Character Creation Options Sun 26 Feb - 13:53 | |
| What I did was use the SampleWorld character_factory and SampleCharacterCreation which has you just store the mesh by name in the map rather than a reference. Then I had the player select different costumes separate from the model. But it really shouldnt be hard to use a reference from what it looks like (just by the code you posted) there is a map with each a value , the name i.e. male_1, and a list which is actually the model name followed by another list of submeshes and materials. It is important to understand this type of data structure because it is reused a lot of places. They probably used it a lot because it seems to be the easiest way to send data between all four of the different programming languages (Java -> Jython -> Ironpython -> C#) So they generally they 'serialize' the items by putting them into list and putting those lists into more lists and then into maps. | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Sun 26 Feb - 15:34 | |
| - delurin wrote:
- What I did was use the SampleWorld character_factory and SampleCharacterCreation which has you just store the mesh by name in the map rather than a reference. Then I had the player select different costumes separate from the model. But it really shouldnt be hard to use a reference from what it looks like (just by the code you posted) there is a map with each a value , the name i.e. male_1, and a list which is actually the model name followed by another list of submeshes and materials. It is important to understand this type of data structure because it is reused a lot of places. They probably used it a lot because it seems to be the easiest way to send data between all four of the different programming languages (Java -> Jython -> Ironpython -> C#) So they generally they 'serialize' the items by putting them into list and putting those lists into more lists and then into maps.
I'll certainly take that into consideration. Once I actually get this working, I'm going to write a concise and simple tutorial for it. This is pretty important, after all! | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Sun 26 Feb - 17:18 | |
| So, I've got back to work on the Character Creation screen, and I've still got the original problem. I copied the FantasyCharacterCreation.py script over to SampleCharacterCreation.py in the client scripts folder, and made the appropriate changes (factory names etc). I also copied the character_factory.py from the fantasy world config folder over to my own, and again made the necessary changes. Here's my client-side SampleCharacterCreation.py code: - Code:
-
from System.Math import PI from Axiom.Core import ColorEx from Axiom.Graphics import LightType from Axiom.MathLib import * from Multiverse.Base import Client
import ClientAPI import CharacterCreation import WorldObject import Animation import Light
meshInfo = { "female_1" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_01_clothed_mat" ], [ "human_female_head_01-mesh.0", "human_female_fantasy.head_01_mat" ], [ "human_female_head_01_hair-mesh.0", "human_female_fantasy.head_01_hair_01_mat" ], [ "leather_armor_chest-mesh.0", "human_female_fantasy.leather_armor_mat" ], [ "leather_armor_jewels-mesh.0", "human_female_fantasy.leather_armor_mat" ], [ "leather_armor_legs-mesh.0", "human_female_fantasy.leather_armor_mat" ], [ "leather_armor_belt-mesh.0", "human_female_fantasy.leather_armor_mat" ] ] ], "female_2" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_02_clothed_mat" ], [ "human_female_head_02-mesh.0", "human_female_fantasy.head_02_mat" ], [ "human_female_head_02_hair_01-mesh.0", "human_female_fantasy.head_02_hair_01_mat" ], [ "leather_armor_chest-mesh.0", "human_female_fantasy.leather_armor_mat" ], [ "leather_armor_jewels-mesh.0", "human_female_fantasy.leather_armor_mat" ], [ "leather_armor_legs-mesh.0", "human_female_fantasy.leather_armor_mat" ], [ "leather_armor_belt-mesh.0", "human_female_fantasy.leather_armor_mat" ] ] ], "male_1" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_01" ], [ "human_male_head_01-mesh.0", "human_male_fantasy.human_male_head_01" ], [ "male_head_01_hair_01-mesh.0", "human_male_fantasy.human_male_head_01_hair_01" ], [ "male_leather_b_chest-mesh.0", "human_male_fantasy.human_male_armor_leather_b" ], [ "male_leather_b_legs-mesh.0", "human_male_fantasy.human_male_armor_leather_b" ] ] ], "male_2" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_02" ], [ "human_male_head_02-mesh.0", "human_male_fantasy.human_male_head_02" ], [ "human_male_02_hair_01-mesh.0", "human_male_fantasy.human_male_head_02_hair_01" ], [ "male_leather_b_chest-mesh.0", "human_male_fantasy.human_male_armor_leather_b" ], [ "male_leather_b_legs-mesh.0", "human_male_fantasy.human_male_armor_leather_b" ] ] ] }
class SampleCharacterCreationContext(CharacterCreation.CharacterCreationContext): # # Constructor # def __init__(self): CharacterCreation.CharacterCreationContext.__init__(self) # set up some fields for convenience in later methods self._male_models = [ 'male_1', 'male_2' ] self._female_models = [ 'female_1', 'female_2' ] # put some initial data in the create context, so that when we change attributes, we have a valid starting point self.SetAttributes("characterName", {"characterName":"", "model":"male_1", "sex":"male"})
# # Methods # def GetValidAttributeValues(self, attr): """Get the possible attribute values for attr, given the state of the other attributes in the _attrs dictionary""" print "In GetValidAttributeValues('%s')" % attr if attr == 'sex': rv = [] if self._listContains(self._male_models, self._attrs['model']): rv.append('male') if self._listContains(self._female_models, self._attrs['model']): rv.append('female') return rv elif attr == 'model': rv = [] if self._attrs['sex'] == 'male': rv.extend(self._male_models) elif self._attrs['sex'] == 'female': rv.extend(self._female_models) return rv else: raise "Invalid attribute %s" % attr return None
def _setAttributes(self, primaryAttr, attrs): """This method requires primaryAttr to be a valid attribute name, and requires the entry for primaryAttr in the attrs dictionary to be valid. There must be a legitimate value for each other attribute. There must be an entry for each attribute in the attrs dictionary."""
# we can always copy the name, since there are no real limitations on that if attrs.has_key('characterName'): self._attrs['characterName'] = attrs['characterName']
if primaryAttr == 'sex': # setting the sex requires us to check the model self._attrs['sex'] = attrs['sex'] possibleVals = self.GetValidAttributeValues('model') if attrs.has_key('model') and self._listContains(possibleVals, attrs['model']): self._attrs['model'] = attrs['model'] # the combination of attributes is legal return True # the combination of attributes is illegal # if we don't have any possible values, throwing is fine self._attrs['model'] = possibleVals[0] return False else: # either the model was the primary attribute, or # some other non-sex attribute was. Treat both # cases the same self._attrs['model'] = attrs['model'] possibleVals = self.GetValidAttributeValues('sex') if attrs.has_key('sex') and self._listContains(possibleVals, attrs['sex']): self._attrs['sex'] = attrs['sex'] # the combination of attributes is legal return True # the combination of attributes is illegal # if we don't have any possible values, throwing is fine self._attrs['sex'] = possibleVals[0] return False
def OnAttributesUpdated(self): # Destroy the old model avatar = ClientAPI.World.GetObjectByName("avatar") if not avatar is None: avatar.Dispose() # Set up the new avatar model modelName = self._attrs['model'] global meshInfo meshName = meshInfo[modelName][0] submeshInfo = meshInfo[modelName][1] avatar = WorldObject.WorldObject(-10, "avatar", meshName, Vector3(0, 23000, 0), False) for submeshName in avatar.Model.SubMeshNames: avatar.Model.HideSubMesh(submeshName) for i in range(0, len(submeshInfo)): ClientAPI.Log('Submesh name and material: %s, %s' % (submeshInfo[i][0], submeshInfo[i][1])) avatar.Model.SetSubMeshMaterial(submeshInfo[i][0], submeshInfo[i][1]) avatar.Model.ShowSubMesh(submeshInfo[i][0]) avatar.QueueAnimation("idle")
class sampleCharacterSelectionContext(CharacterCreation.CharacterSelectionContext): def __init__(self): self.selectedCharacterId = None
def SetAvatarDisplayContext(self, displayContextString): meshEntries = displayContextString.split('') submeshEntries = meshEntries[0].split('') ClientAPI.Log('Display Context contains %s submesh entries' % len(submeshEntries)) meshName = submeshEntries[0] submeshNames = [] materialNames = [] submeshEntries = submeshEntries[1:] for j in range(0, len(submeshEntries) / 2): submeshNames.append(submeshEntries[2 * j]) materialNames.append(submeshEntries[2 * j + 1])
attachedEntries = meshEntries[1:] for i in range(0, len(attachedEntries)): submeshEntries = attachedEntries[i].split('') attachPoint = submeshEntries[0] attachedMeshName = submeshEntries[1] print ' Attachment Point: %s' % attachPoint print ' Mesh: %s' % attachedMeshName submeshEntries = submeshEntries[2:] for j in range(0, len(submeshEntries) / 2): print ' Submesh: %s' % submeshEntries[2 * j] print ' Material: %s' % submeshEntries[2 * j + 1]
# Destroy the old model avatar = ClientAPI.World.GetObjectByName("avatar") if not avatar is None: avatar.Dispose() # Set up the new avatar model avatar = WorldObject.WorldObject(-10, "avatar", meshName, Vector3(0, 23000, 0), False) # Special handling for the case where we don't have any submesh info # This will just show all the meshes if len(submeshNames) == 0: avatar.QueueAnimation("idle") return for submeshName in avatar.Model.SubMeshNames: avatar.Model.HideSubMesh(submeshName) for i in range(0, len(submeshNames)): ClientAPI.Log('Submesh name and material: %s, %s' % (submeshNames[i], materialNames[i])) avatar.Model.SetSubMeshMaterial(submeshNames[i], materialNames[i]) avatar.Model.ShowSubMesh(submeshNames[i]) avatar.QueueAnimation("idle")
def OnSelectionUpdated(self, characterId): displayContext = self.GetCharacterAttribute(characterId, 'displayContext') self.SetAvatarDisplayContext(displayContext) self.selectedCharacterId = characterId def DeleteSelectedCharacter(self): self.Delete(self.selectedCharacterId)
def CreateSpinAnimation(obj): """This is a utility method that produce a one second animation on the given object to rotate it.""" animation = Animation.Animation("spinning", 1.0) animation_nodetrack = animation.CreateNodeTrack(obj.SceneNode) animation_nodetrack_kf0 = animation_nodetrack.CreateKeyFrame(0) animation_nodetrack_kf0.Translate = obj.Position animation_nodetrack_kf0.Orientation = obj.Orientation animation_nodetrack_kf1 = animation_nodetrack.CreateKeyFrame(.25) animation_nodetrack_kf1.Translate = obj.Position animation_nodetrack_kf1.Orientation = Quaternion.FromAngleAxis(.5 * PI, Vector3.UnitY) * obj.Orientation animation_nodetrack_kf2 = animation_nodetrack.CreateKeyFrame(.5) animation_nodetrack_kf2.Translate = obj.Position animation_nodetrack_kf2.Orientation = Quaternion.FromAngleAxis(PI, Vector3.UnitY) * obj.Orientation animation_nodetrack_kf3 = animation_nodetrack.CreateKeyFrame(.75) animation_nodetrack_kf3.Translate = obj.Position animation_nodetrack_kf3.Orientation = Quaternion.FromAngleAxis(1.5 * PI, Vector3.UnitY) * obj.Orientation animation_nodetrack_kf4 = animation_nodetrack.CreateKeyFrame(1) animation_nodetrack_kf4.Translate = obj.Position animation_nodetrack_kf4.Orientation = Quaternion.FromAngleAxis(2 * PI, Vector3.UnitY) * obj.Orientation return animation
def BuildInitialScene(): """This method sets up the world objects for the character creation and character selection interface. We aren't talking to the world server yet, so we can't get the information from there.""" # Set up the ambient light color ClientAPI.AmbientLight.Color = ColorEx(0.2156863, 0.2588235, 0.2588235) # Throw in a directional light as well dirlight = Light.Light("dirlight") dirlight.Type = LightType.Directional dirlight.Direction = Vector3(.9100, 0, .4147) dirlight.Diffuse = ColorEx(0.7098039, 0.3568628, 0.654902) dirlight.Specular = ColorEx(0.6745098, 0.2431373, 0.6352941) # Put in a point light pointlight = Light.Light("pointlight") pointlight.Type = LightType.Point pointlight.Position = Vector3(100, 25300, 2200) pointlight.Diffuse = ColorEx(0.8117647, 0.7882353, 0.8705882) pointlight.Specular = ColorEx(0.8431373, 0.9058824, 0.9254902) pointlight.AttenuationRange = 5500 # Set up the Gazebo platform = WorldObject.WorldObject(-1, "creation_gazebo_platform", "creation_gazebo.mesh", Vector3(0, 23000, 0), False) # Set up the sky cylinder skycyl = WorldObject.WorldObject(-2, "creation_skycyl", "creation_gazebo_skycyl.mesh", Vector3(0, 23000, 0), False) skycyl_anim = CreateSpinAnimation(skycyl) skycyl_anim.Play(.003, True) # For our startup world, we want to set the camera in a specific spot camera = ClientAPI.GetPlayerCamera() camera.Position = Vector3(0, 24500, 3000) camera.Orientation = Quaternion.FromAngleAxis(-.15, Vector3.UnitX) # Now set up the avatar model avatar = WorldObject.WorldObject(-10, "avatar", "tiny_cube.mesh", Vector3(0, 23000, 0), False)
# This function is an event handler that runs when the world has been initialized. def WorldInitHandler(sender, args): """This method is intended to be called when the world is initialized. At that point, the world is fully prepared, and has the player object and terrain initialized.""" if ClientAPI.World.IsWorldLocal: BuildInitialScene()
def WorldConnectHandler(sender, args): """This is intended to be called when we connect to a world. This happens before the world is initialized.""" if ClientAPI.World.IsWorldLocal: ClientAPI.Log("Connected to character selection world") # We skipped the rdp world connection, so inject the messages # we need to create the world CharacterCreation.InitializeStartupWorld() # Use our custom input handler that will handle gui events, # but doesn't control the camera or character. ClientAPI.InputHandler = ClientAPI.Input.GuiInputHandler() else: # This time we are really connected to the world ClientAPI.Log("Connected to real world") # Use the standard game input handler that will handle gui events, # as well as move the camera and character. ClientAPI.InputHandler = ClientAPI.Input.DefaultInputHandler() # Register an event handler that will run when the world has been initialized. ClientAPI.RegisterEventHandler('WorldConnect', WorldConnectHandler)
# Register an event handler that will run when the world has been initialized. ClientAPI.World.RegisterEventHandler('WorldInitialized', WorldInitHandler)
# When the client connects to the world, skip the rdp world connection. # When they click on the login widget, I will set this flag back to # false, and send a portal message, which will initiate this connection # again. ClientAPI.World.IsWorldLocal = True
And this is my server-side character_factory.py from the config folder: - Code:
-
from multiverse.mars import * from multiverse.mars.objects import * from multiverse.mars.core import * from multiverse.mars.events import * from multiverse.mars.util import * from multiverse.mars.plugins import * from multiverse.server.plugins import * from multiverse.server.math import * from multiverse.server.events import * from multiverse.server.objects import * from multiverse.server.engine import * from java.lang import *
displayContext = DisplayContext("human_female_ruth.mesh", True) displayContext.addSubmesh(DisplayContext.Submesh("human_female_body_ruth-mesh.0", "human_female_ruth.ruth_body_clothed_mat")) displayContext.addSubmesh(DisplayContext.Submesh("human_female_head_ruth-mesh.0", "human_female_ruth.ruth_head_mat")) displayContext.addSubmesh(DisplayContext.Submesh("human_female_head_ruth_hair-mesh.0", "human_female_ruth.ruth_hair_mat"))
# default player template player = Template("DefaultPlayer")
player.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, displayContext) player.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_OBJECT_TYPE, ObjectTypes.player) player.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_RUN_THRESHOLD, Float(5000))
player.put(CombatClient.NAMESPACE, "combat.userflag", Boolean(True)) player.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_DEADSTATE, Boolean(False)) player.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_REGEN_EFFECT, "regen effect") player.put(InventoryClient.NAMESPACE, InventoryClient.TEMPL_ITEMS, "Leather Tunic; Leather Pants") player.put(CombatClient.NAMESPACE, "health-max", MarsStat("health-max", 100)) player.put(CombatClient.NAMESPACE, "health", MarsStat("health", 100)) player.put(CombatClient.NAMESPACE, "mana-max", MarsStat("mana-max", 100)) player.put(CombatClient.NAMESPACE, "mana", MarsStat("mana", 100)) player.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_AUTOATTACK_ABILITY, "player attack ability")
ObjectManagerClient.registerTemplate(player)
meshInfo = { "female_1" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_01_clothed_mat" ], [ "human_female_head_01-mesh.0", "human_female_fantasy.head_01_mat" ], [ "human_female_head_01_hair-mesh.0", "human_female_fantasy.head_01_hair_01_mat" ], ] ], "female_2" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_02_clothed_mat" ], [ "human_female_head_02-mesh.0", "human_female_fantasy.head_02_mat" ], [ "human_female_head_02_hair_01-mesh.0", "human_female_fantasy.head_02_hair_01_mat" ], ] ], "male_1" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_01" ], [ "human_male_head_01-mesh.0", "human_male_fantasy.human_male_head_01" ], [ "male_head_01_hair_01-mesh.0", "human_male_fantasy.human_male_head_01_hair_01" ], ] ], "male_2" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_02" ], [ "human_male_head_02-mesh.0", "human_male_fantasy.human_male_head_02" ], [ "human_male_02_hair_01-mesh.0", "human_male_fantasy.human_male_head_02_hair_01" ], ] ] }
# character factory class SampleFactory (CharacterFactory): def createCharacter(self, worldName, uid, properties): name = properties.get("characterName")
# check to see that the name is valid # we may also want to check for uniqueness and reject bad words here if not name or name == "": properties.put("errorMessage", "Invalid name") return 0
modelName = properties.get("model") meshName = meshInfo[modelName][0] submeshes = meshInfo[modelName][1] override = Template() if meshName: displayContext = DisplayContext(meshName, True) for entry in submeshes: displayContext.addSubmesh(DisplayContext.Submesh(entry[0], entry[1])) override.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, displayContext)
# get default instance oid instanceOid = InstanceClient.getInstanceOid("default") if not instanceOid: Log.error("SampleFactory: no 'default' instance") properties.put("errorMessage", "No default instance") return 0
spawnMarker = InstanceClient.getMarker(instanceOid, "spawn") spawnMarker.getPoint().setY(0)
override.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_NAME, name) override.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_INSTANCE, Long(instanceOid)) override.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_LOC, spawnMarker.getPoint()) override.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_ORIENT, spawnMarker.getOrientation()) override.put(Namespace.OBJECT_MANAGER, ObjectManagerClient.TEMPL_PERSISTENT, Boolean(True))
restorePoint = InstanceRestorePoint("default", spawnMarker.getPoint()) restorePoint.setFallbackFlag(True) restoreStack = LinkedList() restoreStack.add(restorePoint) override.put(Namespace.OBJECT_MANAGER, ObjectManagerClient.TEMPL_INSTANCE_RESTORE_STACK, restoreStack) override.put(Namespace.OBJECT_MANAGER, ObjectManagerClient.TEMPL_CURRENT_INSTANCE_NAME, "default")
objOid = ObjectManagerClient.generateObject("DefaultPlayer", override) Log.debug("SampleFactory: generated obj oid=" + str(objOid))
return objOid
sampleFactory = sampleFactory() LoginPlugin.getCharacterGenerator().setCharacterFactory(sampleFactory)
I also found this error in login_manager.out: - Code:
-
DEBUG [2012-02-26 06:00:12,116] main ObjectManagerClient: registered template: [Template: name=DefaultPlayer (ns=NS.inv, key=:inv_items, val=Leather Tunic; Leather Pants)(ns=NS.wmgr, key=:objType, val=[PLAYER,3])(ns=NS.wmgr, key=runThreshold, val=5000.0)(ns=NS.wmgr, key=:displayContext, val=[DisplayContext: meshFile=human_female_ruth.mesh, attachableFlag=false, castShadow=true, receiveShadow=false, numSubmeshes=3, submesh=[Submesh: name=human_female_body_ruth-mesh.0, material=human_female_ruth.ruth_body_clothed_mat], submesh=[Submesh: name=human_female_head_ruth_hair-mesh.0, material=human_female_ruth.ruth_hair_mat], submesh=[Submesh: name=human_female_head_ruth-mesh.0, material=human_female_ruth.ruth_head_mat]])(ns=NS.combat, key=combat.autoability, val=player attack ability)(ns=NS.combat, key=combat.regeneffect, val=regen effect)(ns=NS.combat, key=combat.userflag, val=true)(ns=NS.combat, key=mana, val=multiverse.mars.objects.MarsStat@59cc014)(ns=NS.combat, key=health-max, val=multiverse.mars.objects.MarsStat@760663ec)(ns=NS.combat, key=health, val=multiverse.mars.objects.MarsStat@1d8a577d)(ns=NS.combat, key=mana-max, val=multiverse.mars.objects.MarsStat@6575deb1)(ns=NS.combat, key=deadstate, val=false) ERROR [2012-02-26 06:00:12,121] main ScriptManager.runPYFile: file=..\config\earth2.0\character_factory.py Traceback (innermost last): File "..\config\earth2.0\character_factory.py", line 126, in ? AttributeError: 'instance' object has no attribute '__call__' Traceback (innermost last): File "..\config\earth2.0\character_factory.py", line 126, in ? AttributeError: 'instance' object has no attribute '__call__'
at org.python.core.Py.AttributeError(Unknown Source) at org.python.core.PyObject.noAttributeError(Unknown Source) at org.python.core.PyObject.__getattr__(Unknown Source) at org.python.core.PyObject.invoke(Unknown Source) at org.python.core.PyInstance.__call__(Unknown Source) at org.python.core.PyObject.__call__(Unknown Source) at org.python.pycode._pyx5.f$0(..\config\earth2.0\character_factory.py:126) at org.python.pycode._pyx5.call_function(..\config\earth2.0\character_factory.py) at org.python.core.PyTableCode.call(Unknown Source) at org.python.core.PyCode.call(Unknown Source) at org.python.core.Py.runCode(Unknown Source) at multiverse.server.engine.ScriptManager.runPYFile(ScriptManager.java:181) at multiverse.server.engine.ScriptManager.runFile(ScriptManager.java:94) at multiverse.server.engine.Engine.processPostScripts(Engine.java:541) at multiverse.server.engine.Engine.main(Engine.java:396) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at multiverse.server.marshalling.Trampoline.main(Trampoline.java:150) DEBUG [2012-02-26 06:00:12,121] main Engine, script completed DEBUG [2012-02-26 06:00:12,121] main Engine, Executing script file: ..\config\earth2.0\extensions_login.py DEBUG [2012-02-26 06:00:12,121] main runPYFile: file=..\config\earth2.0\extensions_login.py WARN [2012-02-26 06:00:12,122] main ScriptManager.runPYFile: file not found: ..\config\earth2.0\extensions_login.py DEBUG [2012-02-26 06:00:12,122] main Engine, script completed
I can see that there was an issue with the extensions_login.py file, so I've copied that across at the time of writing this post - surely that's not the cause of the problem? All the extensions_login.py file contains is: - Code:
-
from java.util import * from java.lang import * from multiverse.mars import * from multiverse.mars.core import * from multiverse.mars.objects import * from multiverse.mars.util import * from multiverse.mars.plugins import * from multiverse.msgsys import * from multiverse.server.math import * from multiverse.server.plugins import * from multiverse.server.events import * from multiverse.server.objects import * from multiverse.server.engine import * from multiverse.server.util import * from multiverse.server.worldmgr import *
LoginPlugin.SecureToken = 1
What am I doing wrong/not doing? Thanks | |
| | | Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: Character Creation Options Tue 28 Feb - 1:55 | |
| I may be wrong...the fantasy scripts might not work with the current version of mars. I am pretty sure that you are supposed to have attributes set in the character_factory which it doesnt look like it is doing. I would use the sampleworld scripts but wherever it asks for meshName/ submeshInfo have it pull the model (i.e. male_1 from the meshInfo map) and then split the entry so meshName = meshInfo[modelName][0] and submeshInfo = meshInfo[modelName][1] and update the meshInfo to what you wanted it to be. do that for both the client and server | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Tue 28 Feb - 5:51 | |
| Ok, so would I just replace: - Code:
-
meshName = None gender = properties.get("sex") if gender == "female": meshName = "human_female.mesh" elif gender == "male": meshName = "human_male.mesh"
if meshName: displayContext = DisplayContext(meshName, True) submeshInfo = meshInfo[meshName] for entry in submeshInfo: displayContext.addSubmesh(DisplayContext.Submesh(entry[0], entry[1])) ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, displayContext)
with - Code:
-
modelName = properties.get("model") meshName = meshInfo[modelName][0] submeshes = meshInfo[modelName][1] override = Template() if meshName: displayContext = DisplayContext(meshName, True) for entry in submeshes: displayContext.addSubmesh(DisplayContext.Submesh(entry[0], entry[1])) override.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, displayContext)
? Or is it not that simple? (just for the server-side character_factory.py, of course) | |
| | | Delurin Head of Platform Development
Posts : 424 Join date : 2011-08-03
| Subject: Re: Character Creation Options Tue 28 Feb - 5:55 | |
| | |
| | | Tristan Administrator
Posts : 306 Join date : 2011-08-03 Location : Liverpool, UK
| Subject: Re: Character Creation Options Tue 28 Feb - 6:22 | |
| Ok, so I gave it a shot, and the Client gave me a Script error on startup... Problem is, I can't find any errors in the logs.. Anything blindingly obvious in the scripts? character_factory.py - Code:
-
from multiverse.mars import * from multiverse.mars.objects import * from multiverse.mars.core import * from multiverse.mars.events import * from multiverse.mars.util import * from multiverse.mars.plugins import * from multiverse.server.plugins import * from multiverse.server.math import * from multiverse.server.events import * from multiverse.server.objects import * from multiverse.server.engine import * from java.lang import * from java.util import LinkedList
meshInfo = { "female_1" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_01_clothed_mat" ], [ "human_female_head_01-mesh.0", "human_female_fantasy.head_01_mat" ], [ "human_female_head_01_hair-mesh.0", "human_female_fantasy.head_01_hair_01_mat" ], ] ], "female_2" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_02_clothed_mat" ], [ "human_female_head_02-mesh.0", "human_female_fantasy.head_02_mat" ], [ "human_female_head_02_hair_01-mesh.0", "human_female_fantasy.head_02_hair_01_mat" ], ] ], "male_1" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_01" ], [ "human_male_head_01-mesh.0", "human_male_fantasy.human_male_head_01" ], [ "male_head_01_hair_01-mesh.0", "human_male_fantasy.human_male_head_01_hair_01" ], ] ], "male_2" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_02" ], [ "human_male_head_02-mesh.0", "human_male_fantasy.human_male_head_02" ], [ "human_male_02_hair_01-mesh.0", "human_male_fantasy.human_male_head_02_hair_01" ], ] ] }
# Add clothing meshes. These should really be done as inventory items, # but as a quick fix, we put it in the base display context of the object. meshInfo["human_male_fantasy.mesh"].extend([[ "cloth_a_bootsShape-lib.0", "human_male.cloth_a_material" ], [ "cloth_a_shirtShape-lib.0", "human_male.cloth_a_material" ], [ "cloth_a_pantsShape-lib.0", "human_male.cloth_a_material" ]]) meshInfo["human_female_fantasy.mesh"].extend([[ "leather_a_beltShape-lib.0", "human_female.leather_a_material" ], [ "leather_a_pantsShape-lib.0", "human_female.leather_a_material" ], [ "leather_a_bootsShape-lib.0", "human_female.leather_a_material" ], [ "leather_a_tunicShape-lib.0", "human_female.leather_a_material" ]])
# set up the default display context displayContext = DisplayContext("human_female_fantasy.mesh", True) for entry in meshInfo["human_female_fantasy.mesh"]: displayContext.addSubmesh(DisplayContext.Submesh(entry[0], entry[1]))
# default player template player = Template("DefaultPlayer")
player.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, displayContext) player.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_OBJECT_TYPE, ObjectTypes.player) player.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_RUN_THRESHOLD, Float(5000))
player.put(CombatClient.NAMESPACE, "combat.userflag", Boolean(True)) player.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_DEADSTATE, Boolean(False)) player.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_REGEN_EFFECT, "regen effect") player.put(InventoryClient.NAMESPACE, InventoryClient.TEMPL_ITEMS, "Leather Tunic; Leather Pants") player.put(CombatClient.NAMESPACE, "health-max", MarsStat("health-max", 100)) player.put(CombatClient.NAMESPACE, "health", MarsStat("health", 100)) player.put(CombatClient.NAMESPACE, "mana-max", MarsStat("mana-max", 100)) player.put(CombatClient.NAMESPACE, "mana", MarsStat("mana", 100)) player.put(CombatClient.NAMESPACE, CombatInfo.COMBAT_PROP_AUTOATTACK_ABILITY, "player attack ability")
ObjectManagerClient.registerTemplate(player)
# character factory class SampleFactory (CharacterFactory): def createCharacter(self, worldName, uid, properties): ot = Template()
name = properties.get("characterName") # check to see that the name is valid # we may also want to check for uniqueness and reject bad words here if not name or name == "": properties.put("errorMessage", "Invalid name") return 0 modelName = properties.get("model") meshName = meshInfo[modelName][0] submeshes = meshInfo[modelName][1] override = Template() if meshName: displayContext = DisplayContext(meshName, True) for entry in submeshes: displayContext.addSubmesh(DisplayContext.Submesh(entry[0], entry[1])) override.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_DISPLAY_CONTEXT, displayContext)
statProperties = ["strength","dexterity","wisdom","intelligence", "class"] for statProp in statProperties: if (not properties.get(statProp)): properties.put("errorMessage", "Missing property "+statProp) return 0
# get combat settings strength = int(properties.get("strength")) dexterity = int(properties.get("dexterity")) wisdom = int(properties.get("wisdom")) intelligence = int(properties.get("intelligence")) player_class = str(properties.get("class"))
# get default instance oid instanceOid = InstanceClient.getInstanceOid("default") if not instanceOid: Log.error("SampleFactory: no 'default' instance") properties.put("errorMessage", "No default instance") return 0
# set the spawn location spawnMarker = InstanceClient.getMarker(instanceOid, "spawn") spawnMarker.getPoint().setY(0)
# override template ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_NAME, name) ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_INSTANCE, Long(instanceOid)) ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_LOC, spawnMarker.getPoint()) ot.put(WorldManagerClient.NAMESPACE, WorldManagerClient.TEMPL_ORIENT, spawnMarker.getOrientation())
restorePoint = InstanceRestorePoint("default", spawnMarker.getPoint()) restorePoint.setFallbackFlag(True) restoreStack = LinkedList() restoreStack.add(restorePoint) ot.put(Namespace.OBJECT_MANAGER, ObjectManagerClient.TEMPL_INSTANCE_RESTORE_STACK, restoreStack) ot.put(Namespace.OBJECT_MANAGER, ObjectManagerClient.TEMPL_CURRENT_INSTANCE_NAME, "default")
ot.put(Namespace.OBJECT_MANAGER, ObjectManagerClient.TEMPL_PERSISTENT, Boolean(True))
ot.put(ClassAbilityClient.NAMESPACE, "class", player_class) ot.put(CombatClient.NAMESPACE, "strength", MarsStat("strength", strength)) ot.put(CombatClient.NAMESPACE, "dexterity", MarsStat("dexterity", dexterity)) ot.put(CombatClient.NAMESPACE, "wisdom", MarsStat("wisdom", wisdom)) ot.put(CombatClient.NAMESPACE, "intelligence", MarsStat("intelligence", intelligence)) ot.put(CombatClient.NAMESPACE, "stamina", MarsStat("stamina", int(int(strength)*1.5))) ot.put(CombatClient.NAMESPACE, "stamina-max", MarsStat("stamina-max", int(int(strength)*1.5))) ot.put(CombatClient.NAMESPACE, "mana", MarsStat("mana", int(intelligence)*2)) ot.put(CombatClient.NAMESPACE, "mana-max", MarsStat("mana-max", int(intelligence)* 2)) ot.put(CombatClient.NAMESPACE, "health", MarsStat("health", int(strength) * 2)) ot.put(CombatClient.NAMESPACE, "health-max", MarsStat("health-max", int(strength)*2)) ot.put(CombatClient.NAMESPACE, "experience", MarsStat("experience", 0, 100)) ot.put(CombatClient.NAMESPACE, "level", MarsStat("level", 1, 100))
# generate the object objOid = ObjectManagerClient.generateObject("DefaultPlayer", ot) Log.debug("SampleFactory: generated obj oid=" + str(objOid)) return objOid
sampleFactory = SampleFactory() LoginPlugin.getCharacterGenerator().setCharacterFactory(sampleFactory)
SampleCharacterCreation.py - Code:
-
from System.Math import PI from Axiom.Core import ColorEx from Axiom.Graphics import LightType from Axiom.MathLib import * from Multiverse.Base import Client
import ClientAPI import CharacterCreation import Input import WorldObject import Animation import Light
meshInfo = { "female_1" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_01_clothed_mat" ], [ "human_female_head_01-mesh.0", "human_female_fantasy.head_01_mat" ], [ "human_female_head_01_hair-mesh.0", "human_female_fantasy.head_01_hair_01_mat" ], ] ], "female_2" : [ "human_female_fantasy.mesh" , [ [ "human_female_body-mesh.0", "human_female_fantasy.body_02_clothed_mat" ], [ "human_female_head_02-mesh.0", "human_female_fantasy.head_02_mat" ], [ "human_female_head_02_hair_01-mesh.0", "human_female_fantasy.head_02_hair_01_mat" ], ] ], "male_1" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_01" ], [ "human_male_head_01-mesh.0", "human_male_fantasy.human_male_head_01" ], [ "male_head_01_hair_01-mesh.0", "human_male_fantasy.human_male_head_01_hair_01" ], ] ], "male_2" : [ "human_male_fantasy.mesh" , [ [ "human_male_body-mesh.0", "human_male_fantasy.human_male_body_02" ], [ "human_male_head_02-mesh.0", "human_male_fantasy.human_male_head_02" ], [ "human_male_02_hair_01-mesh.0", "human_male_fantasy.human_male_head_02_hair_01" ], ] ] }
# Add clothing meshes for the client - on the server this should be done with # the inventory system, but that is not available here. meshInfo["human_male_fantasy.mesh"].extend([[ "cloth_a_bootsShape-lib.0", "human_male.cloth_a_material" ], [ "cloth_a_shirtShape-lib.0", "human_male.cloth_a_material" ], [ "cloth_a_pantsShape-lib.0", "human_male.cloth_a_material" ]]) meshInfo["human_female_fantasy.mesh"].extend([[ "leather_a_beltShape-lib.0", "human_female.leather_a_material" ], [ "leather_a_pantsShape-lib.0", "human_female.leather_a_material" ], [ "leather_a_bootsShape-lib.0", "human_female.leather_a_material" ], [ "leather_a_tunicShape-lib.0", "human_female.leather_a_material" ]])
class SampleCharacterCreationContext(CharacterCreation.CharacterCreationContext): # # Constructor # def __init__(self): CharacterCreation.CharacterCreationContext.__init__(self) # set up some fields for convenience in later methods self._male_models = [ 'male_1', 'male_2' ] self._female_models = [ 'female_1', 'female_2' ] # put some initial data in the create context, so that when we change attributes, we have a valid starting point self.SetAttributes("characterName", {"characterName":"", "model":"male_1", "sex":"male"}) # # Methods # def GetValidAttributeValues(self, attr): """Get the possible attribute values for attr, given the state of the other attributes in the _attrs dictionary""" print "In GetValidAttributeValues('%s')" % attr if attr == 'sex': rv = [] if self._listContains(self._male_models, self._attrs['model']): rv.append('male') if self._listContains(self._female_models, self._attrs['model']): rv.append('female') return rv elif attr == 'model': rv = [] if self._attrs['sex'] == 'male': rv.extend(self._male_models) elif self._attrs['sex'] == 'female': rv.extend(self._female_models) return rv else: raise "Invalid attribute %s" % attr return None
def _setAttributes(self, primaryAttr, attrs): """This method requires primaryAttr to be a valid attribute name, and requires the entry for primaryAttr in the attrs dictionary to be valid. There must be a legitimate value for each other attribute. There must be an entry for each attribute in the attrs dictionary."""
# we can always copy the name, since there are no real limitations on that if attrs.has_key('characterName'): self._attrs['characterName'] = attrs['characterName']
if primaryAttr == 'sex': # setting the sex requires us to check the model self._attrs['sex'] = attrs['sex'] possibleVals = self.GetValidAttributeValues('model') if attrs.has_key('model') and self._listContains(possibleVals, attrs['model']): self._attrs['model'] = attrs['model'] # the combination of attributes is legal return True # the combination of attributes is illegal # if we don't have any possible values, throwing is fine self._attrs['model'] = possibleVals[0] return False else: # either the model was the primary attribute, or # some other non-sex attribute was. Treat both # cases the same self._attrs['model'] = attrs['model'] self._attrs['strength'] = attrs['strength'] self._attrs['dexterity'] = attrs['dexterity'] self._attrs['wisdom'] = attrs['wisdom'] self._attrs['intelligence'] = attrs['intelligence'] self._attrs['level'] = attrs['level'] self._attrs['class'] = attrs['class'] possibleVals = self.GetValidAttributeValues('sex') if attrs.has_key('sex') and self._listContains(possibleVals, attrs['sex']): self._attrs['sex'] = attrs['sex'] # the combination of attributes is legal return True # the combination of attributes is illegal # if we don't have any possible values, throwing is fine self._attrs['sex'] = possibleVals[0] return False
def OnAttributesUpdated(self): # Destroy the old model avatar = ClientAPI.World.GetObjectByName("avatar") if not avatar is None: avatar.Dispose() # Set up the new avatar model meshName = self._attrs['model'] global meshInfo meshName = meshInfo[modelName][0] submeshInfo = meshInfo[modelName][1] avatar = WorldObject.WorldObject(-10, "avatar", meshName, Vector3(0, 23000, 0), False) for submeshName in avatar.Model.SubMeshNames: avatar.Model.HideSubMesh(submeshName) for i in range(0, len(submeshInfo)): ClientAPI.Log('Submesh name and material: %s, %s' % (submeshInfo[i][0], submeshInfo[i][1])) avatar.Model.SetSubMeshMaterial(submeshInfo[i][0], submeshInfo[i][1]) avatar.Model.ShowSubMesh(submeshInfo[i][0]) avatar.QueueAnimation("idle")
class SampleCharacterSelectionContext(CharacterCreation.CharacterSelectionContext): def __init__(self): self.selectedCharacterId = None
def SetAvatarDisplayContext(self, displayContextString): meshEntries = displayContextString.split('') submeshEntries = meshEntries[0].split('') ClientAPI.Log('Display Context contains %s submesh entries' % len(submeshEntries)) meshName = submeshEntries[0] submeshNames = [] materialNames = [] submeshEntries = submeshEntries[1:] for j in range(0, len(submeshEntries) / 2): submeshNames.append(submeshEntries[2 * j]) materialNames.append(submeshEntries[2 * j + 1])
attachedEntries = meshEntries[1:] for i in range(0, len(attachedEntries)): submeshEntries = attachedEntries[i].split('') attachPoint = submeshEntries[0] attachedMeshName = submeshEntries[1] print ' Attachment Point: %s' % attachPoint print ' Mesh: %s' % attachedMeshName submeshEntries = submeshEntries[2:] for j in range(0, len(submeshEntries) / 2): print ' Submesh: %s' % submeshEntries[2 * j] print ' Material: %s' % submeshEntries[2 * j + 1]
# Destroy the old model avatar = ClientAPI.World.GetObjectByName("avatar") if not avatar is None: avatar.Dispose() # Set up the new avatar model avatar = WorldObject.WorldObject(-10, "avatar", meshName, Vector3(0, 23000, 0), False) # Special handling for the case where we don't have any submesh info # This will just show all the meshes if len(submeshNames) == 0: avatar.QueueAnimation("idle") return for submeshName in avatar.Model.SubMeshNames: avatar.Model.HideSubMesh(submeshName) for i in range(0, len(submeshNames)): ClientAPI.Log('Submesh name and material: %s, %s' % (submeshNames[i], materialNames[i])) avatar.Model.SetSubMeshMaterial(submeshNames[i], materialNames[i]) avatar.Model.ShowSubMesh(submeshNames[i]) avatar.QueueAnimation("idle")
def OnSelectionUpdated(self, characterId): displayContext = self.GetCharacterAttribute(characterId, 'displayContext') self.SetAvatarDisplayContext(displayContext) self.selectedCharacterId = characterId def DeleteSelectedCharacter(self): self.Delete(self.selectedCharacterId)
def CreateSpinAnimation(obj): """This is a utility method that produce a one second animation on the given object to rotate it.""" animation = Animation.Animation("spinning", 1.0) animation_nodetrack = animation.CreateNodeTrack(obj.SceneNode) animation_nodetrack_kf0 = animation_nodetrack.CreateKeyFrame(0) animation_nodetrack_kf0.Translate = obj.Position animation_nodetrack_kf0.Orientation = obj.Orientation animation_nodetrack_kf1 = animation_nodetrack.CreateKeyFrame(.25) animation_nodetrack_kf1.Translate = obj.Position animation_nodetrack_kf1.Orientation = Quaternion.FromAngleAxis(.5 * PI, Vector3.UnitY) * obj.Orientation animation_nodetrack_kf2 = animation_nodetrack.CreateKeyFrame(.5) animation_nodetrack_kf2.Translate = obj.Position animation_nodetrack_kf2.Orientation = Quaternion.FromAngleAxis(PI, Vector3.UnitY) * obj.Orientation animation_nodetrack_kf3 = animation_nodetrack.CreateKeyFrame(.75) animation_nodetrack_kf3.Translate = obj.Position animation_nodetrack_kf3.Orientation = Quaternion.FromAngleAxis(1.5 * PI, Vector3.UnitY) * obj.Orientation animation_nodetrack_kf4 = animation_nodetrack.CreateKeyFrame(1) animation_nodetrack_kf4.Translate = obj.Position animation_nodetrack_kf4.Orientation = Quaternion.FromAngleAxis(2 * PI, Vector3.UnitY) * obj.Orientation return animation
def BuildInitialScene(): """This method sets up the world objects for the character creation and character selection interface. We aren't talking to the world server yet, so we can't get the information from there.""" # Set up the ambient light color ClientAPI.AmbientLight.Color = ColorEx(0.2156863, 0.2588235, 0.2588235) # Throw in a directional light as well dirlight = Light.Light("dirlight") dirlight.Type = LightType.Directional dirlight.Direction = Vector3(.9100, 0, .4147) dirlight.Diffuse = ColorEx(0.7098039, 0.3568628, 0.654902) dirlight.Specular = ColorEx(0.6745098, 0.2431373, 0.6352941) # Put in a point light pointlight = Light.Light("pointlight") pointlight.Type = LightType.Point pointlight.Position = Vector3(100, 25300, 2200) pointlight.Diffuse = ColorEx(0.8117647, 0.7882353, 0.8705882) pointlight.Specular = ColorEx(0.8431373, 0.9058824, 0.9254902) pointlight.AttenuationRange = 5500 # Set up the Gazebo platform = WorldObject.WorldObject(-1, "creation_gazebo_platform", "creation_gazebo.mesh", Vector3(0, 23000, 0), False) # Set up the sky cylinder skycyl = WorldObject.WorldObject(-2, "creation_skycyl", "creation_gazebo_skycyl.mesh", Vector3(0, 23000, 0), False) skycyl_anim = CreateSpinAnimation(skycyl) skycyl_anim.Play(.003, True) # For our startup world, we want to set the camera in a specific spot camera = ClientAPI.GetPlayerCamera() camera.Position = Vector3(0, 24500, 3000) camera.Orientation = Quaternion.FromAngleAxis(-.15, Vector3.UnitX) # Now set up the avatar model avatar = WorldObject.WorldObject(-10, "avatar", "tiny_cube.mesh", Vector3(0, 23000, 0), False)
# This function is an event handler that runs when the world has been initialized. def WorldInitHandler(sender, args): """This method is intended to be called when the world is initialized. At that point, the world is fully prepared, and has the player object and terrain initialized.""" if ClientAPI.World.IsWorldLocal: BuildInitialScene()
def WorldConnectHandler(sender, args): """This is intended to be called when we connect to a world. This happens before the world is initialized.""" if ClientAPI.World.IsWorldLocal: ClientAPI.Log("Connected to character selection world") # We skipped the rdp world connection, so inject the messages # we need to create the world CharacterCreation.InitializeStartupWorld() # Use our custom input handler that will handle gui events, # but doesn't control the camera or character. ClientAPI.InputHandler = ClientAPI.Input.GuiInputHandler() else: # This time we are really connected to the world ClientAPI.Log("Connected to real world") # Use the standard game input handler that will handle gui events, # as well as move the camera and character. ClientAPI.InputHandler = ClientAPI.Input.DefaultInputHandler() # Register an event handler that will run when the world has been initialized. ClientAPI.RegisterEventHandler('WorldConnect', WorldConnectHandler)
# Register an event handler that will run when the world has been initialized. ClientAPI.World.RegisterEventHandler('WorldInitialized', WorldInitHandler)
# When the client connects to the world, skip the rdp world connection. # When they click on the login widget, I will set this flag back to # false, and send a portal message, which will initiate this connection # again. if ClientAPI.World.WorldName != "standalone": ClientAPI.World.IsWorldLocal = True
Cheers | |
| | | Sponsored content
| Subject: Re: Character Creation Options | |
| |
| | | | Character Creation Options | |
|
Similar topics | |
|
| Permissions in this forum: | You cannot reply to topics in this forum
| |
| |
| |