Commit f2d8500f06ad08de2bee95aa50302a4d263aee43

Authored by dg
1 parent 48a504fa

fixed timeline splitting/projectile interaction crash (thanks tiger_eye :) )

Rune of the Rift paradox reduction reduced to 60
Rune of the Rift should no longer occasionally heal actors
Time Skip once again removes actors from the map rather then time prisoning them


git-svn-id: http://svn.net-core.org/repos/t-engine4@4820 51575b47-30f0-44d4-a5cc-537603b46e54
... ... @@ -45,7 +45,7 @@ function _M:save()
45 45 end
46 46
47 47 function _M:loaded()
48   - if self.project and self.project.def and self.project.def.typ and self.project.def.typ.line_function then
  48 + if self.project and self.project.def and self.project.def.typ and self.project.def.typ.line_function and type(self.project.def.typ.line_function.line) == "table" then
49 49 self.project.def.typ.line_function.line = core.fov.line_import(unpack(self.project.def.typ.line_function.line))
50 50
51 51 -- The metatable gets lost somewhere in the save, so let's remake it
... ...
... ... @@ -828,12 +828,22 @@ end
828 828 function _M:chronoClone(name)
829 829 local d = Dialog:simpleWaiter("Chronomancy", "Folding the space time structure...")
830 830
831   - local ret = nil
  831 + local to_reload = {}
  832 + for uid, e in pairs(self.level.entities) do
  833 + if type(e.project) == "table" and e.project.def and e.project.def.typ and e.project.def.typ.line_function then
  834 + e.project.def.typ.line_function.line = { game.level.map.w, game.level.map.h, e.project.def.typ.line_function:export() }
  835 + to_reload[#to_reload + 1] = e
  836 + end
  837 + end
  838 +
  839 + local ret = self:cloneFull()
  840 +
  841 + for uid, e in pairs(to_reload) do e:loaded() end
  842 +
832 843 if name then
833 844 self._chronoworlds = self._chronoworlds or {}
834   - self._chronoworlds[name] = self:cloneFull()
835   - else
836   - ret = self:cloneFull()
  845 + self._chronoworlds[name] = ret
  846 + ret = nil
837 847 end
838 848 d:done()
839 849 return ret
... ... @@ -852,6 +862,8 @@ function _M:chronoRestore(name, remove)
852 862
853 863 ngame:cloneReloaded()
854 864 _G.game = ngame
  865 +
  866 + game.inited = nil
855 867 game:run()
856 868 game.key:setCurrent()
857 869 game.mouse:setCurrent()
... ...
... ... @@ -65,7 +65,7 @@ newTalent{
65 65 require = temporal_req1,
66 66 points = 5,
67 67 paradox = 5,
68   - cooldown = 1,
  68 + cooldown = 10,
69 69 no_npc_use = true,
70 70 getDuration = function(self, t) return 4 + math.ceil((self:getTalentLevel(t) * 2)) end,
71 71 action = function(self, t)
... ...
... ... @@ -66,47 +66,75 @@ newTalent{
66 66 getDamage = function(self, t) return self:combatTalentSpellDamage(t, 25, 250) * getParadoxModifier(self, pm) end,
67 67 getDuration = function(self, t) return 2 + math.ceil(self:getTalentLevel(t) / 2 * getParadoxModifier(self, pm)) end,
68 68 action = function(self, t)
69   - -- Find the target and check hit
70 69 local tg = {type="hit", range=self:getTalentRange(t), talent=t}
71   - local tx, ty, target = self:getTarget(tg)
72   - if not tx or not ty then return nil end
73   - tx, ty = checkBackfire(self, tx, ty, t.paradox)
74   - local _ _, tx, ty = self:canProject(tg, tx, ty)
75   - if tx then
76   - target = game.level.map(tx, ty, engine.Map.ACTOR)
77   - end
78   -
79   - -- checks for spacetime mastery hit bonus
80   - local power = self:combatSpellpower()
81   - if self:knowTalent(self.T_SPACETIME_MASTERY) then
82   - power = self:combatSpellpower() * (1 + self:getTalentLevel(self.T_SPACETIME_MASTERY)/10)
83   - end
  70 + local x, y, _ = self:getTarget(tg)
  71 + if not x or not y then return nil end
  72 + x, y = checkBackfire(self, x, y, t.paradox)
  73 + _, x, y = self:canProject(tg, x, y)
  74 + local target = x and game.level.map(x, y, engine.Map.ACTOR) or nil
  75 + if not target then return nil end
84 76
85   - if target then
86   - local hit = self:checkHit(power, target:combatSpellResist() + (target:attr("continuum_destabilization") or 0))
87   - if not hit then
88   - game.logSeen(target, "%s resists!", target.name:capitalize())
89   - return true
90   - end
91   - else
92   - return
93   - end
94   -
95   - -- deal the damage first so time prison doesn't prevent it
96   - self:project(tg, tx, ty, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t)))
97   - game.level.map:particleEmitter(tx, ty, 1, "temporal_thrust")
  77 + local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0))
  78 + if not hit then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end
  79 +
  80 + target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)})
  81 + self:project(tg, x, y, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t)))
  82 + game.level.map:particleEmitter(x, y, 1, "temporal_thrust")
98 83 game:playSoundNear(self, "talents/arcane")
99 84
100   - -- make sure the target survives the initial hit and then time prison
101   - if not target.dead then
102   - if target ~= self then
103   - target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)})
104   - end
105   - target:setEffect(target.EFF_TIME_PRISON, t.getDuration(self, t), {})
  85 + -- End it here if we've killed the target or the target is a player
  86 + if target.dead or target.player then return true end
  87 +
  88 + -- set up instability
  89 + local summoner = self
  90 + -- Store the current terrain
  91 + local terrain = game.level.map(target.x, target.y, engine.Map.TERRAIN)
  92 + -- Store target attributes as needed
  93 + local a = {}
  94 + a.life = target.life
  95 + -- Instability
  96 + local temporal_instability = mod.class.Object.new{
  97 + old_feat = game.level.map(target.x, target.y, engine.Map.TERRAIN),
  98 + name = "temporal instability", type="temporal", subtype="anomaly",
  99 + display = '&', color=colors.LIGHT_BLUE,
  100 + temporary = t.getDuration(self, t),
  101 + canAct = false,
  102 + target = target,
  103 + act = function(self)
  104 + self:useEnergy()
  105 + self.temporary = self.temporary - 1
  106 + -- return the rifted actor
  107 + if self.temporary <= 0 then
  108 + game.level.map(self.target.x, self.target.y, engine.Map.TERRAIN, self.old_feat)
  109 + game.level:removeEntity(self)
  110 + local mx, my = util.findFreeGrid(self.target.x, self.target.y, 20, true, {[engine.Map.ACTOR]=true})
  111 + game.zone:addEntity(game.level, self.target, "actor", mx, my)
  112 + self.target.life = a.life
  113 + end
  114 + end,
  115 + summoner_gain_exp = true,
  116 + summoner = summoner,
  117 + }
  118 +
  119 + -- Mixin the old terrain
  120 + table.update(temporal_instability, terrain)
  121 + -- Now update the display overlay
  122 + local overlay = engine.Entity.new{
  123 + display = '&', color=colors.LIGHT_BLUE, image="object/temporal_instability.png",
  124 + display_on_seen = true,
  125 + display_on_remember = true,
  126 + }
  127 + if not temporal_instability.add_displays then
  128 + temporal_instability.add_displays = {overlay}
106 129 else
107   - game.logSeen(target, "%s has been killed by the temporal energy!", target.name:capitalize())
  130 + table.append(temporal_instability.add_displays, overlay)
108 131 end
109   -
  132 +
  133 + game.logSeen(target, "%s has moved forward in time!", target.name:capitalize())
  134 + game.level:removeEntity(target)
  135 + game.level:addEntity(temporal_instability)
  136 + game.level.map(target.x, target.y, engine.Map.TERRAIN, temporal_instability)
  137 +
110 138 return true
111 139 end,
112 140 info = function(self, t)
... ...
... ... @@ -720,27 +720,32 @@ newInscription{
720 720 getDamage = function(self, t) return 150 + self:getWil() * 4 end,
721 721 getDuration = function(self, t) return 4 end,
722 722 action = function(self, t)
723   - -- Find the target and check hit
724 723 local tg = {type="hit", range=self:getTalentRange(t), talent=t}
725   - local tx, ty, target = self:getTarget(tg)
726   - if not tx or not ty then return nil end
727   - local _ _, tx, ty = self:canProject(tg, tx, ty)
728   - if tx then
729   - target = game.level.map(tx, ty, engine.Map.ACTOR)
730   - end
731   - if target and not target.player then
732   - local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0))
733   - if not hit then
734   - game.logSeen(target, "%s resists!", target.name:capitalize())
735   - return true
736   - end
737   - else
738   - return
739   - end
  724 + local x, y, _ = self:getTarget(tg)
  725 + if not x or not y then return nil end
  726 + _, x, y = self:canProject(tg, x, y)
  727 + local target = x and game.level.map(x, y, engine.Map.ACTOR) or nil
  728 + if not target then return nil end
  729 +
  730 + local hit = self:checkHit(self:combatSpellpower(), target:combatSpellResist() + (target:attr("continuum_destabilization") or 0))
  731 + if not hit then game.logSeen(target, "%s resists!", target.name:capitalize()) return true end
  732 +
  733 + target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)})
  734 + self:project(tg, x, y, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t)))
  735 + game.level.map:particleEmitter(x, y, 1, "temporal_thrust")
  736 + game:playSoundNear(self, "talents/arcane")
740 737
741   - -- Create an object to time the effect and store the creature
742   - -- First, clone the terrain that we are replacing
  738 + -- End it here if we've killed the target or the target is a player
  739 + if target.dead or target.player then return true end
  740 +
  741 + -- set up instability
  742 + local summoner = self
  743 + -- Store the current terrain
743 744 local terrain = game.level.map(target.x, target.y, engine.Map.TERRAIN)
  745 + -- Store target attributes as needed
  746 + local a = {}
  747 + a.life = target.life
  748 + -- Instability
744 749 local temporal_instability = mod.class.Object.new{
745 750 old_feat = game.level.map(target.x, target.y, engine.Map.TERRAIN),
746 751 name = "temporal instability", type="temporal", subtype="anomaly",
... ... @@ -751,21 +756,23 @@ newInscription{
751 756 act = function(self)
752 757 self:useEnergy()
753 758 self.temporary = self.temporary - 1
  759 + -- return the rifted actor
754 760 if self.temporary <= 0 then
755 761 game.level.map(self.target.x, self.target.y, engine.Map.TERRAIN, self.old_feat)
756 762 game.level:removeEntity(self)
757 763 local mx, my = util.findFreeGrid(self.target.x, self.target.y, 20, true, {[engine.Map.ACTOR]=true})
758 764 game.zone:addEntity(game.level, self.target, "actor", mx, my)
  765 + self.target.life = a.life
759 766 end
760 767 end,
761 768 summoner_gain_exp = true,
762   - summoner = self,
  769 + summoner = summoner,
763 770 }
  771 +
764 772 -- Mixin the old terrain
765 773 table.update(temporal_instability, terrain)
766 774 -- Now update the display overlay
767 775 local overlay = engine.Entity.new{
768   - -- image = "terrain/wormhole.png",
769 776 display = '&', color=colors.LIGHT_BLUE, image="object/temporal_instability.png",
770 777 display_on_seen = true,
771 778 display_on_remember = true,
... ... @@ -775,24 +782,13 @@ newInscription{
775 782 else
776 783 table.append(temporal_instability.add_displays, overlay)
777 784 end
  785 +
  786 + game.logSeen(target, "%s has moved forward in time!", target.name:capitalize())
  787 + game.level:removeEntity(target)
  788 + game.level:addEntity(temporal_instability)
  789 + game.level.map(target.x, target.y, engine.Map.TERRAIN, temporal_instability)
778 790
779   - self:project(tg, tx, ty, DamageType.TEMPORAL, self:spellCrit(t.getDamage(self, t)))
780   - game.level.map:particleEmitter(tx, ty, 1, "temporal_thrust")
781   - game:playSoundNear(self, "talents/arcane")
782   - -- Remove the target and place the temporal placeholder
783   - if not target.dead then
784   - if target ~= self then
785   - target:setEffect(target.EFF_CONTINUUM_DESTABILIZATION, 100, {power=self:combatSpellpower(0.3)})
786   - end
787   - game.logSeen(target, "%s has moved forward in time!", target.name:capitalize())
788   - game.level:removeEntity(target)
789   - game.level:addEntity(temporal_instability)
790   - game.level.map(target.x, target.y, engine.Map.TERRAIN, temporal_instability)
791   - else
792   - game.logSeen(target, "%s has been killed by the temporal energy!", target.name:capitalize())
793   - end
794   -
795   - self:incParadox(-120)
  791 + self:incParadox(-60)
796 792
797 793 return true
798 794 end,
... ... @@ -800,7 +796,7 @@ newInscription{
800 796 local damage = t.getDamage(self, t)
801 797 local duration = t.getDuration(self, t)
802 798 return ([[Inflicts %0.2f temporal damage. If your target survives it will be sent %d turns into the future.
803   - It will also lower your paradox by 120 (if you have any).
  799 + It will also lower your paradox by 60 (if you have any).
804 800 Note that messing with the spacetime continuum may have unforeseen consequences.]]):format(damDesc(self, DamageType.TEMPORAL, damage), duration)
805 801 end,
806 802 short_info = function(self, t)
... ...
... ... @@ -9,24 +9,9 @@ mod="$1"
9 9 version="$2"
10 10 exclude_ogg="$3"
11 11
12   -pushd "$mod"
13   -teams=`lua <<EOS
14   -local init = loadfile("init.lua")
15   -local d = {}
16   -setfenv(init, d)
17   -init()
18   -if not d.teams then return end
19   -for i, def in ipairs(d.teams) do
20   - io.write(def[1]..":"..table.concat(def[3],":"):gsub("^/", ""):gsub(":/", ":"))
21   - if i < #d.teams then io.write(";") end
22   -end
23   -EOS`
24   -teams=`echo "$teams"| sed "s/#name#/$mod/g" | sed "s/#version#/$version/g"`
25   -popd
26   -
27 12 cp -a "$mod" tmp
28 13 find tmp -name .svn -or -name '*~' | xargs rm -rf
29   -pushd tmp
  14 +cd tmp
30 15
31 16 if test "$exclude_ogg" -eq 1; then
32 17 IFS=$'\n'; for i in `find -name '*.ogg'`; do
... ... @@ -39,25 +24,11 @@ mkdir mod
39 24 mv * mod
40 25 mv mod/data .
41 26
42   -IFS=';'
43   -for teamdef in `echo "$teams"`; do
44   - tname=`echo "$teamdef"|cut -d: -f1`
45   - tlist=`echo "$teamdef"|cut -d: -f2-`
46   - echo "=== Teamdef: $tname"
47   - IFS=':'
48   - for list in `echo "$tlist"`; do
49   - echo "=== Adding: $tlist"
50   - zip --quiet -r -0 ../"$tname" "$list"
51   - rm -rf "$list"
52   - done
53   - IFS=';'
54   -done
55   -
56 27 if test "$exclude_ogg" -eq 1; then
57   - zip --quiet -r -0 ../"$mod"-"$version-nomusic".team *
  28 + zip -r -0 ../"$mod"-"$version-nomusic".team *
58 29 else
59   - zip --quiet -r -0 ../"$mod"-"$version".team *
  30 + zip -r -0 ../"$mod"-"$version".team *
60 31 fi
61 32
62   -popd
  33 +cd -
63 34 rm -rf tmp
... ...