1 //
2 //  SuperTuxKart - a fun racing game with go-kart
3 //  Copyright (C) 2014-2015  SuperTuxKart Team
4 //
5 //  This program is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU General Public License
7 //  as published by the Free Software Foundation; either version 3
8 //  of the License, or (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 #include "script_kart.hpp"
20 
21 #include "karts/kart.hpp"
22 #include "karts/kart_properties.hpp"
23 #include "modes/world.hpp"
24 #include "scriptvec3.hpp"
25 #include "scriptengine/aswrappedcall.hpp"
26 
27 #include <assert.h>
28 #include <angelscript.h>
29 //debug
30 #include <iostream>
31 
32 /** \cond DOXYGEN_IGNORE */
33 namespace Scripting
34 {
35 /** \endcond */
36 
37     namespace Kart
38     {
39         /** \addtogroup Scripting
40           * @{
41           */
42         /** \addtogroup Kart
43         * @{
44         */
45 
46         /** Squashes the specified kart, for the specified time */
squash(int idKart,float time)47         void squash(int idKart, float time)
48         {
49             AbstractKart* kart = World::getWorld()->getKart(idKart);
50             kart->setSquash(time, 0.5);  //0.5 * max speed is new max for squashed duration
51         }
52 
53         /** Teleports the kart to the specified Vec3 location */
teleport(int idKart,SimpleVec3 * position)54         void teleport(int idKart, SimpleVec3* position)
55         {
56             AbstractKart* kart = World::getWorld()->getKart(idKart);
57             Vec3 v(position->getX(), position->getY(), position->getZ());
58             kart->setXYZ(v);
59             unsigned int index = World::getWorld()->getRescuePositionIndex(kart);
60             btTransform s = World::getWorld()->getRescueTransform(index);
61             s.setRotation(btQuaternion(btVector3(0.0f, 1.0f, 0.0f), 0.0f));
62             World::getWorld()->moveKartTo(kart, s);
63         }
64 
65         /** Teleports the kart to the specified Vec3 location */
teleportExact(int idKart,SimpleVec3 * position)66         void teleportExact(int idKart, SimpleVec3* position)
67         {
68             AbstractKart* kart = World::getWorld()->getKart(idKart);
69             Vec3 v(position->getX(), position->getY(), position->getZ());
70             kart->setXYZ(v);
71             btTransform s;
72             s.setRotation(kart->getRotation());
73             s.setOrigin(v);
74             World::getWorld()->moveKartTo(kart, s);
75         }
76 
77         /** Attempts to project kart to the given 2D location, to the position
78           * with height 0, at a 45 degree angle.
79           */
80         // TODO: not sure what this function is for
81         //void jumpTo(asIScriptGeneric *gen)
82         //{
83         //    //attempts to project kart to target destination
84         //    //at present, assumes both initial and target location are
85         //    //on the same horizontal plane (z=k plane) and projects
86         //    //at a 45 degree angle.
87         //    int id = (int)gen->GetArgDWord(0);
88         //
89         //    float x = gen->GetArgFloat(1);
90         //    float y = gen->GetArgFloat(2);
91         //    //float velocity = gen->GetArgFloat(3);
92         //    //angle = pi/4 so t = v/(root 2 * g)
93         //    //d = t * v/root 2 so d = v^2/(2g) => v = root(2dg)
94         //    //component in x = component in y = root (dg)
95         //    AbstractKart* kart = World::getWorld()->getKart(id);
96         //    Vec3 pos = kart->getXYZ();
97         //    float dx = x - pos[0];
98         //    float dy = y - pos[2]; //blender uses xyz, bullet xzy
99         //    float d = (sqrtf(dx*dx + dy*dy));
100         //    float normalized_dx = dx / d;
101         //    float normalized_dy = dy / d;
102         //    float g = 9.81f;
103         //    float velocity = sqrtf(d * g);
104         //
105         //    kart->setVelocity(btVector3(velocity * normalized_dx, velocity, velocity * normalized_dy));
106         //}
107 
108         /** Returns the location of the corresponding kart. */
getLocation(int idKart)109         SimpleVec3 getLocation(int idKart)
110         {
111             AbstractKart* kart = World::getWorld()->getKart(idKart);
112             Vec3 v = kart->getXYZ();
113             return SimpleVec3(v.getX(), v.getY(), v.getZ());
114         }
115 
116         /** Sets the kart's velocity to the specified value. */
setVelocity(int idKart,SimpleVec3 * position)117         void setVelocity(int idKart, SimpleVec3* position)
118         {
119             float x = position->getX();
120             float y = position->getY();
121             float z = position->getZ();
122 
123             AbstractKart* kart = World::getWorld()->getKart(idKart);
124             kart->setVelocity(btVector3(x, y, z));
125         }
126 
127         /** Gets the kart's velocity */
getVelocity(int idKart)128         SimpleVec3 getVelocity(int idKart)
129         {
130             AbstractKart* kart = World::getWorld()->getKart(idKart);
131             btVector3 velocity = kart->getVelocity();
132             return SimpleVec3(velocity.getX(), velocity.getY(), velocity.getZ());
133         }
134 
135         /** Gets the maximum speed (velocity) a kart can reach */
getMaxSpeed(int idKart)136         float getMaxSpeed(int idKart)
137         {
138             AbstractKart* kart = World::getWorld()->getKart(idKart);
139             return kart->getKartProperties()->getEngineMaxSpeed();
140         }
141 
142         /** @}*/
143         /** @}*/
144 
registerScriptFunctions(asIScriptEngine * engine)145         void registerScriptFunctions(asIScriptEngine *engine)
146         {
147             engine->SetDefaultNamespace("Kart");
148 
149             bool mp = strstr(asGetLibraryOptions(), "AS_MAX_PORTABILITY");
150             asDWORD call_conv = mp ? asCALL_GENERIC : asCALL_CDECL;
151             int r; // of type asERetCodes
152 
153             r = engine->RegisterGlobalFunction("void squash(int id, float time)",
154                                                mp ? WRAP_FN(squash) : asFUNCTION(squash),
155                                                call_conv); assert(r >= 0);
156 
157             r = engine->RegisterGlobalFunction("void teleport(int id, const Vec3 &in)",
158                                                mp ? WRAP_FN(teleport) : asFUNCTION(teleport),
159                                                call_conv); assert(r >= 0);
160 
161             r = engine->RegisterGlobalFunction("void teleportExact(int id, const Vec3 &in)",
162                                                mp ? WRAP_FN(teleportExact) : asFUNCTION(teleportExact),
163                                                call_conv); assert(r >= 0);
164 
165             r = engine->RegisterGlobalFunction("void setVelocity(int id, const Vec3 &in)",
166                                                mp ? WRAP_FN(setVelocity) : asFUNCTION(setVelocity),
167                                                call_conv); assert(r >= 0);
168 
169             //r = engine->RegisterGlobalFunction("void jumpTo(int id, float x, float y)",
170             //                                   mp ? WRAP_FN(jumpTo) : asFUNCTION(jumpTo),
171             //                                   call_conv); assert(r >= 0);
172 
173             r = engine->RegisterGlobalFunction("Vec3 getLocation(int id)",
174                                                mp ? WRAP_FN(getLocation) : asFUNCTION(getLocation),
175                                                call_conv); assert(r >= 0);
176 
177             r = engine->RegisterGlobalFunction("Vec3 getVelocity(int id)",
178                                                mp ? WRAP_FN(getVelocity) : asFUNCTION(getVelocity),
179                                                call_conv); assert(r >= 0);
180 
181             r = engine->RegisterGlobalFunction("float getMaxSpeed(int id)",
182                                                mp ? WRAP_FN(getMaxSpeed) : asFUNCTION(getMaxSpeed),
183                                                call_conv); assert(r >= 0);
184         }
185 
registerScriptEnums(asIScriptEngine * engine)186         void registerScriptEnums(asIScriptEngine *engine)
187         {
188             // TODO: document enum in doxygen-generated scripting docs
189             engine->SetDefaultNamespace("Kart");
190             engine->RegisterEnum("PowerupType");
191             engine->RegisterEnumValue("PowerupType", "ANVIL", PowerupManager::PowerupType::POWERUP_ANVIL);
192             engine->RegisterEnumValue("PowerupType", "BOWLING", PowerupManager::PowerupType::POWERUP_BOWLING);
193             engine->RegisterEnumValue("PowerupType", "BUBBLEGUM", PowerupManager::PowerupType::POWERUP_BUBBLEGUM);
194             engine->RegisterEnumValue("PowerupType", "CAKE", PowerupManager::PowerupType::POWERUP_CAKE);
195             engine->RegisterEnumValue("PowerupType", "PARACHUTE", PowerupManager::PowerupType::POWERUP_PARACHUTE);
196             engine->RegisterEnumValue("PowerupType", "PLUNGER", PowerupManager::PowerupType::POWERUP_PLUNGER);
197             engine->RegisterEnumValue("PowerupType", "RUBBERBALL", PowerupManager::PowerupType::POWERUP_RUBBERBALL);
198             engine->RegisterEnumValue("PowerupType", "SWATTER", PowerupManager::PowerupType::POWERUP_SWATTER);
199             engine->RegisterEnumValue("PowerupType", "SWITCH", PowerupManager::PowerupType::POWERUP_SWITCH);
200             engine->RegisterEnumValue("PowerupType", "ZIPPER", PowerupManager::PowerupType::POWERUP_ZIPPER);
201         }
202     }
203 
204 /** \cond DOXYGEN_IGNORE */
205 }
206 /** \endcond */
207