Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

adapter.gno

3.09 Kb · 90 lines
 1package physics
 2
 3import "gno.land/p/g1lnkytfqcjwllws63gvf0mv9yt04aswy4y9amhm/penalty/v0"
 4
 5// ParamsOf converts a game's constants from the realm's integer units (mm,
 6// mm/s, ms, per-mille, milli-radii) to the engine's. The defaults convert to
 7// DefaultParams exactly: each division is correctly rounded, so 2424/1000 is
 8// the same double as the browser's literal 2.424.
 9func ParamsOf(c penalty.Config) Params {
10	return Params{
11		GoalHalfWidth: float64(c.GoalWidth) / 2000,
12		GoalHeight:    float64(c.GoalHeight) / 1000,
13		KeeperScale:   float64(c.KeeperScale) / 1000,
14		ReactionMin:   float64(c.ReactionMin) / 1000,
15		ReactionMax:   float64(c.ReactionMax) / 1000,
16		StarShare:     float64(c.StarShare) / 1000,
17		ReadShare:     float64(c.ReadShare) / 1000,
18		DiveMin:       float64(c.DiveMin) / 1000,
19		DiveMax:       float64(c.DiveMax) / 1000,
20		JumpMin:       float64(c.JumpMin) / 1000,
21		JumpMax:       float64(c.JumpMax) / 1000,
22		BallMinSpeed:  float64(c.BallMinSpeed) / 1000,
23		BallMaxSpeed:  float64(c.BallMaxSpeed) / 1000,
24		FuzzBase:      float64(c.FuzzBase) / 1000,
25		FuzzPower:     float64(c.FuzzPower) / 1000,
26		MaxContact:    float64(c.MaxContact) / 1000,
27	}
28}
29
30// ShotOf converts the taker's ten-input half (integer units plus the mishit
31// seed) to the engine's units, as the web game does: each value / 1000.
32func ShotOf(s penalty.ShotParams) Shot {
33	return Shot{
34		AimX:      float64(s.AimX) / 1000,
35		AimY:      float64(s.AimY) / 1000,
36		ContactX:  float64(s.ContactX) / 1000,
37		ContactY:  float64(s.ContactY) / 1000,
38		Power:     float64(s.Power) / 1000,
39		Mishit:    s.Mishit,
40		HasMishit: true,
41	}
42}
43
44// SimulateShot is the realm's outcome function on this engine: the taker's
45// six inputs and the keeper's four, under a game's constants.
46func SimulateShot(shot penalty.ShotParams, plan penalty.KeeperPlan, cfg penalty.Config) penalty.Result {
47	prm := ParamsOf(cfg)
48	pl := DecodePlan([4]uint16{plan.Direction, plan.Speed, plan.Jump, plan.Reaction}, prm)
49	r := Simulate(ShotOf(shot), pl, prm, Options{})
50	return ResultOf(r, pl)
51}
52
53// ResultOf summarises a decided kick in the realm's integer units.
54func ResultOf(r Result, pl Plan) penalty.Result {
55	out := penalty.Result{
56		BallSpeed: int64(jsRound(r.Launch.Speed * 1000)),
57		MishitX:   int64(jsRound(r.Launch.FuzzX * 1000)),
58		MishitY:   int64(jsRound(r.Launch.FuzzY * 1000)),
59	}
60	switch r.Outcome {
61	case Goal:
62		out.Outcome = penalty.OutcomeGoal
63	case Save:
64		out.Outcome = penalty.OutcomeSave
65	case Miss:
66		out.Outcome = penalty.OutcomeMiss
67	case Post:
68		out.Outcome = penalty.OutcomePost
69	}
70	switch pl.Mode {
71	case ModeStar:
72		out.Keeper = penalty.ModeStar
73	case ModeRead:
74		out.Keeper = penalty.ModeRead
75	default:
76		out.Keeper = penalty.ModeDive
77	}
78	// Where the ball reached the goal line, or failing that where it was
79	// when the kick was decided (kept out before the line).
80	if r.LineCross {
81		out.X = int64(jsRound(r.LineX * 1000))
82		out.Y = int64(jsRound(r.LineY * 1000))
83		out.ArrivalMS = int64(jsRound(r.LineT * 1000))
84	} else {
85		out.X = int64(jsRound(r.EndX * 1000))
86		out.Y = int64(jsRound(r.EndY * 1000))
87		out.ArrivalMS = int64(jsRound(r.DecidedAt * 1000))
88	}
89	return out
90}