GDScript modularization - godot

Is it possible to modularize in GDScript?
What I have in mind is that I have a player class with variable input, of type IInput, like this:
Player.gd:
extends KinematicBody
var input = load("res://Scripts/Inputs/PlayerInput.gd").new()
func _physics_process(delta):
if input.is_down("left_trigger"): speed = sprintSpeed
else: speed = runSpeed
Where "res://Scripts/Inputs/PlayerInput.gd" would look like this
extends "res://Scripts/Inputs/IInput.gd"
class_name PlayerInput
var controlTranslatinos = {"left_stick_up" : "move_up",
"left_stick_down" : "move_down",
"left_stick_left" : "move_left",
"left_stick_right" : "move_right",
"right_stick_up" : "rotate_up",
"right_stick_down" : "rotate_down",
"right_stick_left" : "rotate_left",
"right_stick_right" : "rotate_right",
"x" : "attack",
"left_trigger" : "defend",
"a" : "jump",
"right_trigger" : "sprint"}
func pressure(controlName):
var translatedControl = controlTranslatinos[controlName]
var preasure = Input.get_action_strength(translatedControl)
return preasure
func is_down(controlName):
return Input.is_action_pressed(controlTranslatinos[controlName])
and where "res://Scripts/Inputs/IInput.gd" would look like this:
extends Node
class_name IInput
const controls = [ "move_up", "move_down", "move_left", "move_right",
"rotate_up", "rotate_down", "rotate_left", "rotate_right",
"attack", "defend", "jump", "sprint" ]
func pressure(controlName):
return 0
func is_down(controlName):
return false
Goal is to change actor's input to AIInput class and back to PlayerInput on demand. This would also be good for other stuff.
Is it possible to implement this in some other way?
Error at `PlayerInput.gd`
There's an error at first line of PlayerInput, saying:
`Script not fully loaded (cyclic preload?): "res://Scripts/Inputs/IInput.gd"
I get what cyclic preload would mean, but I don't get how cyclic loading is happening at this instance. Can you explain how/why this is happening? How can I overcome it?
If this error wouldn't show up I think the modularization would work (the way I imagine it works).

Related

Invalid operands 'Dictionary' and 'Array' in operator '+'.Godot3.5

I am using v3.5.stable.official [991bb6ac7] Godot Engine I was also using version 3.4, that is also the reason I have decided to update, since I can't get passed by that error.
Invalid operands 'Dictionary' and 'Array' in operator '+'
extends Area2D
onready var timer = $Timer
onready var plant = $Sprite
var stage = 0
var PlantNum
func _ready():
PlantNum = Game.Plot.size()
Game.Plot += [{
"Seed": "Corn",
"TimeLeft": timer.time_left,
"Stage": stage,
}]
Utils.save_game()
timer.start()
plant.frame = 1
This piece of code is for my game project that I am trying to make. The code serves for the save and load, so that the plants stage will stay the same as when I join again.
The global script which is connected to the upper one.
extends Node
var Plot = [
{
"Seed":"",
"TimeLeft":0,
"Stage":0,
},
]
Expected output
[{Seed:, Stage:0, TimeLeft:0}, {Seed:Corn ,Stage:0, TimeLeft:0}]
Any help would be much appreciated.
I don't know why you are getting that particular error. My first guess is that somewhere along the line the type was lost… Either somewhere you set a Dictionary to Plot (after all, it is Variant), or we are looking at a bug in Godot.
Either way, you can declare Plot as an Array (so it is not Variant). Either implicitly:
var Plot := [
{
"Seed":"",
"TimeLeft":0,
"Stage":0,
},
]
Or explicitly
var Plot:Array = [
{
"Seed":"",
"TimeLeft":0,
"Stage":0,
},
]
On the other hand, using using append_array is better than += (it does not allocate a new Array), so I would prefer that:
Game.Plot.apppend_array([{
"Seed": "Corn",
"TimeLeft": timer.time_left,
"Stage": stage,
}])
Furthermore, you are just adding one element, thus you can use append:
Game.Plot.apppend({
"Seed": "Corn",
"TimeLeft": timer.time_left,
"Stage": stage,
})
Thanks for the post.
I have done this
func _ready():
PlantNum = Game.Plot.size()
Game.Plot.append({
"Seed": "Corn",
"TimeLeft": timer.time_left,
"Stage": stage,
})
And this,
var Plot := [
{
"Seed":"",
"TimeLeft":0,
"Stage":0,
}]
I got a new error by doing so,
Parser Error: The assigned value's type (Dictionary) doesn't match the variable's type (Array).
func _ready():
var date = OS.get_datetime()
Game.Plot = OS.get_datetime() # Error is in this line.
self.text = "Time: " + str(date["hour"]) + " : " + str(date["minute"])

Kotlin unresolved reference when using mutlithreading

So I'm trying to use kotlin together with selenium and threading, but one parameter doesnt work. Here's my code:
class myClass(parameter1 : String, parameter2 : String, parameter3 : Int) : Thread(){
init{
var driver : ChromeDriver = ChromeDriver()
}
override fun run() {
driver.get("somewebsite")
var id_field = driver.findElementByName("iD")
id_field.sendKeys(parameter1)
id_field.submit()
name = parameter2 + parameter3.toString()
//At this Point, Intellij Idea tells me: Unresolved reference: parameter3
name_field = driver.findElementByName("name")
name_field.sendKeys(name)
name_field.submit()
}
}
fun main() {
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver")
val threads: Array<myClass> = Array(2) { myClass("some_id", "name", it)}
}
What should happen is that the script goes to my website, enters the name and iD. But I want to be able to run mutiple threads of my script where the threads "iteration" (which is parameter 3) is being added to my name.
So for example:
- thread 1 logs in with: name1
- thread 2 logs in with: name2
(...)
- thread 20 logs in with: name20
But my question is:
Why doesnt kotlin say: Unsolved reference: parameter 3?

How to write term none in alloy

I have write the code like accesses = none. But if I execute metamodel the message appears
Cannot bind field accesses to the empty set or empty relation
How to fix my code ?
sig months_prior_to_open_day extends BusinessEvent {} {
triggers = open_day_planning accesses = none
}
sig open_day_planning extends BusinessProcess {} {
flows_to = none
realizes = none
uses = none
aggregates = none
triggers = send_update_to_subject_staff
accesses = none
}
Try writing no accesses instead.

Swift : session sendData , type () does not confirm to protocol BooleanType

I am trying to create a Bluetooth chat system based on this tutorial : http://www.appcoda.com/chat-app-swift-tutorial/
The error that I receive is the following : type () does not conform to protocol BooleanType.
Does anyone know how to solve this?
func sendData(dictionaryWithData dictionary: Dictionary<String, String>, toPeer targetPeer: [MCPeerID]){
let dataToSend = NSKeyedArchiver.archivedDataWithRootObject(dictionary)
//let peersArray = NSArray(object: targetPeer)
if session.sendData(dataToSend, toPeers: targetPeer , withMode: MCSessionSendDataMode.Reliable) {
}
}
Well the error states that you use a var as a bool, while it is not a bool, my advice, stop using non type specific inits.
example:
var myBool = true //BAD
var mySecondBool : Bool = true //Good
The thing is I see no bools in the code you posted...

groovy Object and primitive confusion

Here's a part of (groovy) class that stores some data in Mongodb:
long save(Object data) {
def customerReference = getNextCustomerReference()
def map = ['customerReference': customerReference, 'data': data, 'created': new Date()]
BasicDBObject basicDBObject = new BasicDBObject(map)
collection.insert(basicDBObject)
customerReference
}
private long getNextCustomerReference() {
1234
}
even though I have explicitly said i want a primitive long, what ends up in the database is an object:
{ "_id" : ObjectId("52f3c0597d844b0fcee29013"), "customerReference" : NumberLong(1234), "data" : "original data", "created" : ISODate("2014-02-06T17:03:21.411Z") }
However, if I change the return type to def for the private method this happens:
{ "_id" : ObjectId("52f3c1477d84698725f50fe5"), "customerReference" : 1234, "data" : "data", "created" : ISODate("2014-02-06T17:07:19.055Z") }
which the behaviour I want (a primitive stored in the db).
Can someone explain this because its baffling. Surely if I go out of my way to define a type, Groovy should try and honour it?
Groovy almost always automatically autoboxes primitive types to their number reference type-equivalent:
long test_long() { 123l }
int test_int() { 123 }
def test_def() { 123 }
def test_def_long() { 123l }
long l = 42l
assert test_long().class == Long.class
assert test_int().class == Integer.class
assert test_def().class == Integer.class
assert test_def_long().class == Long.class
assert l.class === Long.class
If you remove the long return type, the object is autoboxed to java.lang.Integer. Seems your code handles the Integer like a "primitive".
Some time ago Groovy 1.8 introduced primitive type optimization, an internal fallback to use primitive types under the hood in certain situations. This can help in some situations but is an internal performance optimization you can't directly make use of (by using some syntax construct or something like that).
Sometimes you can force a primitive by an explicit cast, but chances are high it will be converted to a reference type along the way through methods calls and stuff.

Resources